【问题标题】:shift/reduce conlfict and how to solve转移/减少冲突以及如何解决
【发布时间】:2016-11-19 18:46:16
【问题描述】:

我的教授分配给我的项目有问题。我们得到以下内容

Goal
    ::= (Function|Statement)* <EOF>
Function
    ::= "def" Identifier "(" Argument? ")" ":" Statement 
Argument
    ::= Identifier ("=" Value )? ( "," Identifier ("=" Value )?)* 
Statement
    ::= tab* "if" Comparison ":" Statement 
    |tab* "while" Comparison ":" Statement
    |tab* "for" Identifier "in" Identifier ":" Statement
    |tab* "return" Expression 
    |tab* "print" Expression ("," Expression)* 
    |tab* Identifier ( "=" | "-=" | "/=" ) Expression 
    |tab* Identifier "[" Expression "]" "=" Expression 
    |tab* Function Call 
Expression
    ::= Expression ( "+" | "-" | "*" | "/" ) Expression
    | ( "++" | "--" ) Expression
    | Expression( "++" | "--" )
    | Identifier "[" Expression "]"
    | Function Call 
    | Value 
    | Identifier
    | "(" Expression ")"
    | "["Value ( "," Value)*"]"
Comparison
    ::= Expression ( ">" | "<" | "!=" | "==") Expression
    | "true"
    | "false"
Function Call
    ::= Identifier "(" Arglist? ")"
Arglist
    ::= Expression ( "," Expression )* 
Value
    ::= Number | "<STRING_LITERAL>"|'<STRING_LITERAL>'
Number
    ::= <INTEGER_LITERAL> 
Identifier
    ::= <IDENTIFIER>

<STRING_LITERAL> = A word that can contain letter(capitals or non capital) and white spaces
<INTEGER_LITERAL> = An integer number
<IDENTIFIER> = Name of a variable

我们必须用词法和语法分析来实现一个语法文件。我已经实现了大部分的行,但是我在实现其余的行时遇到了问题,因为我遇到了移位/减少冲突。我的代码是这样的

 Helpers
    digit = ['0' .. '9'];
    letter = ['a' .. 'z']|['A' .. 'Z']; 
    cr = 13; 
    lf = 10;
    all = [0..127]; 
    eol = lf | cr | cr lf ;
    not_eol = [all - [cr + lf]]; 

Tokens
    tab = 9;
    plus = '+';
    dplus = '++';
    minus = '-';
    dminus = '--';
    mult = '*';
    div = '/';
    eq = '=';
    minus_eq = '-=';
    div_eq = '/=';
    exclam = '!';
    l_br = '[';
    r_br = ']';
    l_par = '(';
    r_par = ')';
    comma=',';
    def = 'def';
    if = 'if';
    elif = 'elif';
    else = 'else';
    for = 'for';
    in = 'in';
    while = 'while';
    print = 'print';
    return = 'return';
    less = '<';
    great = '>';
    not_eq = '!=';
    log_eq = '==';
    true = 'true';
    semi = ':';
    false = 'false';    
    quote = '"';
    blank = (' ' | lf | cr);
    line_comment = '#' not_eol* eol; 
    number = digit+;
    id = letter (letter | digit)*;
    string = ('"'not_eol* '"' | ''' not_eol* ''');

Ignored Tokens
    blank, line_comment;
    Productions
    programme = commands*;

    commands ={stat} statement|
                 {expr}expression;

    function = {function} def id l_par argument? r_par semi statement;

    argument = {argument} id arg1? arg2*;

    arg1 = {arg1} eq value;

    arg2 = {arg2} comma id arg1?;

    statement = {if}tab* if  comparison semi statement |
                {while}tab* while comparison semi statement |
                {for}tab* for [id1]:id in [id2]:id semi statement |
                {return}tab* return expression|
                {print}tab* print expression |
                {assign}tab* id eq expression |
                {reduce_by}tab* id minus_eq expression |
                {divide_by}tab* id div_eq expression |
                {array_element_assing}tab* id l_br [ex2]:expression r_br eq [ex32]:expression;



    comparison = {true} true|
                     {false} false|
                     {lessc} [lpar]:expression less [rpar]:expression|
                     {greatc}[lpar]:expression great [rpar]:expression|
                     {equal} [lpar]:expression log_eq [rpar]:expression|
                     {not_equal} [lpar]:expression not_eq [rpar]:expression;

    expression = {multiplication} multiplication |               
                    {addition} expression plus multiplication |
                    {subtraction} expression minus multiplication |
                    {array}id l_br expression r_br;






    multiplication = {something} something |
                          {multiplication} multiplication mult something |
                          {division} multiplication div something |
                          {postfix}  suffix;

    suffix = {dplus} dplus something |
                {dminus} dminus something ;




    value = {number} number |
            {string} string;

    something ={identifier}id|
                  {numb}number|
                  {par} l_par expression r_par;

如果没有移位/减少冲突,我不能包含的行是

在声明中

|tab* Function Call

在表达式中

|Expression( "++" | "--" )
| Function Call
| "["Value ( "," Value)*"]"

还有线条

    Function Call
    ::= Identifier "(" Arglist? ")"
Arglist
    ::= Expression ( "," Expression )*

我只发布了生产部分,而不是所有内容,因为问题就在那里。我希望得到一些帮助,了解如何在我的语法中添加这些行而不发生移位/减少冲突。我现在正试图解决这个问题,它看起来我什么都试过了。提前感谢您的帮助。

【问题讨论】:

    标签: compiler-construction grammar reduce shift bnf


    【解决方案1】:

    您的语法允许expression 成为command(您混淆地称为commands)。你给出的语法没有。

    由于没有命令分隔符,您的语法允许连续表达式。然而,这是模棱两可的。 a+b 是一个表达式,还是两个表达式 a+ba(b) 呢?函数调用,或表达式a 后跟表达式(b)?以此类推。

    您需要重新考虑关于什么是命令的决定。

    顺便说一句,something 对于非终端来说是一个糟糕的名字,我觉得你叫冒号(:semi;分号实际上是;,这是我假设semi 所指的。

    【讨论】:

    • 非常感谢!我解决了大部分问题,现在我只需要设置后缀和后缀的优先级!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多