Compiler construction 如何解决移位,减少语法冲突?

Compiler construction 如何解决移位,减少语法冲突?,compiler-construction,syntax,pascal,shift-reduce-conflict,Compiler Construction,Syntax,Pascal,Shift Reduce Conflict,我正在编写一个从reduced Pascal到ARM asm的编译器。我正处于这个过程的第二步——在编写了词法分析器之后,现在我正在使用进行语法分析 我已经写了语法,但是有5个S/R冲突,它们都非常相似。例如: Warning : *** Shift/Reduce conflict found in state #150 between assign_stmt ::= val_expr ASSIGN val_expr (*) and val_expr ::= val_expr

我正在编写一个从reduced Pascal到ARM asm的编译器。我正处于这个过程的第二步——在编写了词法分析器之后,现在我正在使用进行语法分析

我已经写了语法,但是有5个S/R冲突,它们都非常相似。例如:

   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
我的本节语法:

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
    ;
我怎样才能消除这种冲突


谢谢。

你的语法模棱两可,左右循环。根据我对解析器的有限知识,我知道这是大多数解析器生成器无法解析的

这是不明确的,因为val_expr ADD val_expr SUB val_expr可以解析为:

       ADD
      /   \
val_expr  SUB
         /   \
   val_expr  val_expr

我从未使用过Java CUP,但下面是我如何使用另一个解析器生成器完成类似操作的:

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

expr1 ::=
    NIL | BOOL_CONST | INT_CONST | CHAR_CONST | <etc> ;
这使得语法明确无误,并且只有正确的递归,这可以由我所知道的所有解析器生成器处理

这种语法的一个消极方面是没有任何优先级,但JavaCup可能有另一种指定优先级的方法


编辑:修正了第一条语法规则。

你可能应该用你正在使用的解析器生成器来标记这个问题,或者至少在问题的某个地方提到它。我提到了java cup,但不能添加标记,因为你需要1,5k的声誉来添加新标记。实际上,我的语法还有一些其他问题,在我解决这些问题时,所有的冲突都自动神奇地消失了。然而,根据你的帖子,我也改变了我的语法,使之更漂亮。谢谢你,我学到了一些新东西!
val_expr ::=
    expr1 (SUB | ADD | <add all your operators here>) val_expr
    | expr1 ;

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