简体   繁体   中英

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
                 ;

(FILE: parserr.output)

State 87 conflicts: 1 shift/reduce

State 124 conflicts: 1 shift/reduce

(State 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)

(State 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)

I am getting 2 shift/reduce conflicts, i tried using %prec XXX in the end but it did not work. I also tried defining colon ":" with left precedence, it didnt work either.

  • changed: - from %nonassoc LPAREN RPAREN => TO %left LPAREN RPAREN

Your grammar has an ambiguity in the rules for expression :

expression: T_LPAREN expression T_COLON expression T_RPAREN
expression: constant

with

constant: coup_constant
coup_constant: T_LPAREN simp_constant T_COLON simp_constant T_RPAREN

(1,2) can be produced through either of these, resulting in the conflict.

The simplest resolution would be to replace expression: constant with expression: simp_constant , forcing the parser to accept the more general option.

Trying to use the constant interpretation when possible will make it impossible to correctly parse (2:a) , which is a valid expression , because the parser needs to decide before a is the lookahead. For the same reason, you cannot readily solve this conflict with a precedence declaration.

That might or might not conform to your semantic requirements, but you could transform the constant in the semantic action were that necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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