Bison yacc转移/减少冲突

Bison yacc转移/减少冲突,bison,yacc,Bison,Yacc,对于以下语法,我遇到了SR错误 这是我的语法 program : CLASS Program '{' field_decl '}' ; field_decl : type field_part ';' | field_part field_fact | meth_decl | ; field_fact : ',' field_decl | field_pa

对于以下语法,我遇到了SR错误

这是我的语法

program : CLASS Program '{' field_decl '}'
        ;    
field_decl : type field_part ';'
           | field_part field_fact
           | meth_decl
           |
           ;    
field_fact : ',' field_decl
           | field_part
           ;    
field_part  : IDENTIFIER field_part2
            ;    
field_part2 :
            | '[' int_literal ']' field_decl
            ;    
meth_decl   : type meth_decl1
            | VOID meth_decl1
            ;    
meth_decl1  : IDENTIFIER '(' meth_part ')' block 
            ;    
meth_part   : type meth_part1
            |
            ;    
meth_part1  : IDENTIFIER meth_part2
            ;                
meth_part2  :
            | ',' meth_part
            ;    
block       : '{' block_list '}'
            ;    
type        : INT
            | BOOLEAN
            ;    
block_list  : var_decl
            |
            ;    
var_decl    : type ids ';'
            | statement
            ;    
ids         : IDENTIFIER ids_part
            ;    
ids_part    :
            | ',' ids
            ;    
statement   : location ASSIGNMENT_OPERATOR expr ';'
            | method_call ';'
            | IF '(' expr ')' block ELSE block 
            | IF '(' expr ')' block
            | FOR IDENTIFIER '=' expr ',' expr block
            | RETURN expr ';'
            | RETURN ';'
            | BREAK ';'
            | CONTINUE ';'
            | block
            ;    
location    : IDENTIFIER loc_part
            ;               
loc_part    : 
            | '[' expr ']'
            ;    
method_call : IDENTIFIER '(' ')'
            | IDENTIFIER '(' expr_block ')'
            | CALLOUT '(' STRING_LITERAL ')'
            | CALLOUT '(' STRING_LITERAL ',' callout_arg_block ')'
            ;    
callout_arg_block : callout_arg
                  | callout_arg ',' callout_arg_block
                  ;    
callout_arg : expr
            | STRING_LITERAL
            ;    
expr        : location
            | method_call
            | literal
            | expr bin_op expr
            | MINUS expr
            | '!' expr
            | '(' expr ')'
            ;    
expr_block  : expr expr_fact
            ;    
expr_fact   : 
            |  ',' expr_block
            ;
bin_op      : ARITHEMATIC_OPERATOR
            | EQUALS_OPERATOR
            | RELATIONAL_OPERATOR
            | CONDITIONAL_OPERATOR
            ;
literal     : int_literal
            | bool_literal
            ;
int_literal : DIGIT
            | HEXADECIMAL_VALUE
            ;
bool_literal    : TRUE
                | FALSE
                ;
野牛显示的输出是

状态19冲突:1班/减少

状态33冲突:1班/减少

州87冲突:4班/减少

状态107冲突:4班/减少


如何重写语法以消除这些冲突

我实际上没有编译语法进行检查,因此下面的内容可能并不详尽

基本上,您有两种典型的移位/减少冲突:

  • 您的表达式语法不明确:

    expr: expr bin_op expr
    
    语法不允许解析器决定哪个
    bin_op
    在任何给定表达式中具有优先级,因此它允许(例如)
    3+4*5
    被解析为
    expr(3+4)bin_op(*)expr(5)
    expr(3)bin_op(+)expr(4*5)
    。此问题的通常解决方案是使用优先级声明,但这些声明与将所有二进制运算符聚集到单个产品中不兼容

    请参阅并阅读

  • 您的
    if
    语句不明确。例如,在

    if ( <expr> ) if ( <expr> ) <block> else <block>
    
    if()if()else
    
    语法没有指定
    if
    else
    应用于哪个

    在这种特定的情况下,默认的bison规则(倾向于shift而不是reduce)将做正确的事情(通过将
    else
    与最里面的
    if
    关联),但它仍然会报告shift/reduce冲突

    请参阅野牛手册以获取示例(在前面链接的部分中),或查看和