简体   繁体   English

如何解决班次减少语法冲突?

[英]How to resolve shift reduce conflicts in my grammar?

I'm writing a compiler from (reduced) Pascal into ARM asm. 我正在将Pascal(精简版)的编译器编写为ARM asm。 I'm at the second step of the process - after writing lexical analyzer now I'm working on syntax analysis with java cup . 我处于过程的第二步-编写词法分析器之后,现在我正在使用Java cup进行语法分析。

I have written my grammar, but got 5 S/R conflicts, which are all very similar. 我已经编写了语法,但是遇到了5个S / R冲突,它们非常相似。 Example: 例:

   Warning : *** Shift/Reduce conflict found in state #150
between assign_stmt ::= val_expr ASSIGN val_expr (*) 
  and     val_expr ::= val_expr (*) LBRACKET val_expr RBRACKET 
  under symbol LBRACKET
  Resolved in favor of shifting

My grammar for this section: 我本节的语法:

assign_stmt ::=
 val_expr ASSIGN val_expr;

val_expr ::=
     NIL | BOOL_CONST | INT_CONST | CHAR_CONST | PTR val_expr %prec MEM | ADD val_expr %prec UADD |
     SUB val_expr %prec USUB | NOT val_expr | val_expr PTR %prec VAL | val_expr MUL val_expr |
     val_expr DIV val_expr | val_expr ADD val_expr | val_expr SUB val_expr | val_expr EQU val_expr |
     val_expr NEQ val_expr | val_expr LTH val_expr | val_expr GTH val_expr | val_expr LEQ val_expr |
     val_expr GEQ val_expr | val_expr AND val_expr | val_expr OR val_expr | IDENTIFIER | 
     val_expr LBRACKET val_expr RBRACKET | val_expr DOT IDENTIFIER | IDENTIFIER LPARENTHESIS params_list RPARENTHESIS |
     LBRACKET type_desc RBRACKET | LPARENTHESIS val_expr RPARENTHESIS
    ;

How could I eliminate this conflict? 我如何消除这种冲突?

Thanks. 谢谢。

Your grammar is ambiguous, and both right- and left-recursive. 您的语法是模棱两可的,并且都是右递归和左递归的。 From my (limited) knowledge about parsers, I know this is impossible to parse by most parser generators. 根据我对解析器的有限了解,我知道大多数解析器生成器都无法解析。

It's ambiguous because val_expr ADD val_expr SUB val_expr can be parsed as: 这是模棱两可的,因为val_expr ADD val_expr SUB val_expr可以解析为:

       ADD
      /   \
val_expr  SUB
         /   \
   val_expr  val_expr

and

        SUB
       /   \
     ADD  val_expr
    /   \
val_expr  val_expr

I've never used Java CUP, but here's how I did a similar thing using another parser generator: 我从未使用过Java CUP,但是这是我使用另一个解析器生成器执行类似操作的方式:

val_expr ::=
    expr1 (SUB | ADD | <add all your operators here>) val_expr
    | expr1 ;

expr1 ::=
    NIL | BOOL_CONST | INT_CONST | CHAR_CONST | <etc> ;

This makes the grammar unambiguous and only right-recursive, which can be handled by all parser generators I know of. 这使得语法是明确的,并且仅是右递归的,可以由我所知道的所有解析器生成器来处理。

A negative aspect of this grammar is that you don't have any precedence, but Java CUP probably has another way to specify precedence. 该语法的不利方面是您没有任何优先级,但是Java CUP可能有另一种指定优先级的方式。

Edit : Fixed first grammar rule. 编辑 :修复了第一个语法规则。

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

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