繁体   English   中英

Bison Shift/减少冲突

[英]Bison Shift/Reduce conficts

    //parserr.y 
    //tokens

       
 
    ---------
    /* precedences */
    %left T_LPAREN T_RPAREN 
    %left T_MULOP T_DIVOP
    %left T_ADDOP
    %left T_ANDOP
    %left T_OROP
    %left T_NOTOP
    %right T_POWEROP
    %right T_ASSIGN
  
     
    %nonassoc T_RELOP
    %nonassoc T_PAIROP
    %start program 

    
** syntax rules - same file **
   program:  body T_END subprograms
       ;

body:  declarations statements
    ;

declarations: declarations couplespec type vars
            | declarations T_DATA vals
            | %empty { }
            ;

couplespec: T_COUPLE
          | %empty { }
          ;

type: T_INTEGER
    | T_REAL
    | T_LOGICAL
    | T_CHARACTER
    ;

vars: vars T_COMMA undef_variable
    | undef_variable
    ;

undef_variable: T_ID T_LPAREN dims T_RPAREN         
              | T_ID                                
              ;

dims: dims T_COMMA dim
    | dim
    ;

dim: T_ICONST
   | T_ID                                
   ;

vals: vals T_COMMA T_ID value_list      
    | T_ID value_list                   
    ;

value_list: T_DIVOP values T_DIVOP
          ;

values: values T_COMMA value
      | value
      ;

value: repeat T_MULOP T_ADDOP simp_constant
     | repeat T_MULOP constant
     | repeat T_MULOP T_STRING
     | T_ADDOP simp_constant
     | constant
     | T_STRING
     ;

repeat: T_ICONST
      | %empty { }
      ;

simp_constant: T_ICONST
             | T_RCONST
             | T_LCONST
             | T_CCONST
             ;

constant: simp_constant
        | coup_constant
        ;


coup_constant: T_LPAREN simp_constant T_COLON simp_constant T_RPAREN
             | T_LPAREN simp_constant T_COLON T_ADDOP simp_constant T_RPAREN
             | T_LPAREN T_ADDOP simp_constant T_COLON simp_constant T_RPAREN
             | T_LPAREN T_ADDOP simp_constant T_COLON T_ADDOP simp_constant T_RPAREN
             ;

statements: statements labeled_statement
          | labeled_statement
          ;

labeled_statement: label statement
                 | statement
                 ;

label: T_ICONST
     ;

statement: simple_statement
         | compound_statement
         ;

simple_statement: assignment
                | goto_statement
                | if_statement
                | subroutine_call
                | io_statement
                | T_CONTINUE
                | T_RETURN
                | T_STOP
                ;

assignment: variable T_ASSIGN expression
          | variable T_ASSIGN T_STRING
          ;

variable: variable T_LPAREN expressions T_RPAREN
        | T_ID                                      
        ;

expressions: expressions T_COMMA expression
            | expression
            ;

expression: expression T_OROP expression
          | expression T_ANDOP expression
          | expression T_RELOP expression
          | expression T_ADDOP expression
          | expression T_MULOP expression
          | expression T_DIVOP expression
          | expression T_POWEROP expression
          | T_NOTOP expression
          | T_ADDOP expression
          | T_PAIROP expression
          | variable
          | constant
          | T_LPAREN expression T_COLON expression T_RPAREN
          | T_LPAREN expression T_RPAREN
          ;

goto_statement: T_GOTO label
              | T_GOTO T_ID T_COMMA T_LPAREN labels T_RPAREN            
              ;

labels: labels T_COMMA label
      | label
      ;

if_statement: T_IF T_LPAREN expression T_RPAREN label T_COMMA label T_COMMA label
            | T_IF T_LPAREN expression T_RPAREN simple_statement
            | T_IF error expression T_RPAREN simple_statement           
            | T_IF T_LPAREN expression error simple_statement            
            ;

subroutine_call: T_CALL variable
               ;

io_statement: T_READ read_list
            | T_WRITE write_list
            ;

read_list: read_list T_COMMA read_item
         | read_item
         ;

read_item: variable
         | T_LPAREN read_list T_COMMA T_ID T_ASSIGN iter_space T_RPAREN         
         ;

iter_space: expression T_COMMA expression step
          ;

step: T_COMMA expression
    | %empty { }
    ;

write_list: write_list T_COMMA write_item
          | write_item
          ;

write_item: expression
          | T_LPAREN write_list T_COMMA T_ID T_ASSIGN iter_space T_RPAREN       
          | T_STRING
          ;

compound_statement: branch_statement
                  | loop_statement
                  ;

branch_statement: T_IF T_LPAREN expression T_RPAREN T_THEN body tail
                ;

tail: T_ELSE body T_ENDIF
    | T_ENDIF
    ;

loop_statement: T_DO T_ID T_ASSIGN iter_space body T_ENDDO                      
              ;

subprograms: subprograms subprogram
           | %empty { }
           ;

subprogram: header body T_END
          ;

header: type T_FUNCTION T_ID T_LPAREN formal_parameters T_RPAREN                
      | T_SUBROUTINE T_ID T_LPAREN formal_parameters T_RPAREN                   
      | T_SUBROUTINE T_ID                                                       
      ;

formal_parameters: type vars T_COMMA formal_parameters
                 | type vars
                 ;

(文件:parserr.output)

State 87 冲突:1 班次/减少

State 124 冲突:1 班次/减少

(状态 87):

State 87

 37 constant: simp_constant .

 39 coup_constant: "(" simp_constant . ":" simp_constant ")"

 40              | "(" simp_constant . ":" "+ -" simp_constant ")"


  ":"  shift, and go to state 125

  ":"       [reduce using rule 37 (constant)]

  $default  reduce using rule 37 (constant)

(状态 124):

 State 124

 37 constant: simp_constant .
 41 coup_constant: "(" "+ -" simp_constant . ":" simp_constant ")"
 42              | "(" "+ -" simp_constant . ":" "+ -" simp_constant ")"

  ":"  shift, and go to state 159

  ":"       [reduce using rule 37 (constant)]
  $default  reduce using rule 37 (constant)

我遇到了 2 个班次/减少冲突,我最后尝试使用 %prec XXX 但它没有用。 我也尝试用左优先级定义冒号“:”,它也不起作用。

  • 更改: - 从 %nonassoc LPAREN RPAREN => 到 %left LPAREN RPAREN

您的语法在expression规则中有歧义:

expression: T_LPAREN expression T_COLON expression T_RPAREN
expression: constant

constant: coup_constant
coup_constant: T_LPAREN simp_constant T_COLON simp_constant T_RPAREN

(1,2)可以通过其中任何一个产生,从而导致冲突。

最简单的解决方案是将expression: constant替换为expression: simp_constant ,强制解析器接受更通用的选项。

在可能的情况下尝试使用常量解释将无法正确解析(2:a) ,这是一个有效的expression ,因为解析器需要在a是前瞻之前做出决定。 出于同样的原因,您无法通过优先声明轻松解决此冲突。

这可能符合也可能不符合您的语义要求,但您可以在必要时转换语义操作中的常量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM