这种转移/减少冲突来自于野牛在哪里?

时间:2013-04-11 10:59:51

标签: parsing bison lalr shift-reduce-conflict jison

我试图通过在Jison(一个javascript解析器)中定义一个非常简单的语言来解决问题。它接受与野牛相同/非常相似的语法。

这是我的语法:

%token INT TRUE FALSE WHILE DO IF THEN ELSE LOCATION ASSIGN EOF DEREF

%left "+"
%left ">="

/* Define Start Production */
%start Program 

/* Define Grammar Productions */
%%

Program
    : Statement EOF
    ;

Statement
    : Expression
    | WHILE BoolExpression DO Statement
    | LOCATION ASSIGN IntExpression
    ;

Expression
    : IntExpression
    | BoolExpression
    ;

IntExpression
    : INT IntExpressionRest
    | IF BoolExpression THEN Statement ELSE Statement
    | DEREF LOCATION
    ;   

IntExpressionRest
    : /* epsilon */
    | "+" IntExpression
    ;

BoolExpression
    : TRUE
    | FALSE
    | IntExpression ">=" IntExpression
    ;

%%

我正在进行一次转变/减少冲突。 Jison的输出在这里:

Conflict in grammar: multiple actions possible when lookahead token is >= in state 6
- reduce by rule: Expression -> IntExpression
- shift token (then go to state 17)

States with conflicts:
State 6
  Expression -> IntExpression . #lookaheads= EOF >= THEN DO ELSE
  BoolExpression -> IntExpression .>= IntExpression #lookaheads= EOF DO THEN ELSE >=

2 个答案:

答案 0 :(得分:1)

检测到您的班次减少冲突,因为>=位于Expression非终端的跟随集中。这主要是因为Statement可以是ExpressionIntExpression可以以statement结尾。考虑以下输入IF c THEN S1 ELSE S2 >= 42,如果您有括号来消除歧义,则可以将其解释为(IF c THEN S1 ELSE S2) >= 42IF c THEN S1 ELSE (S2 >= 42)。由于转移优先于降低,因此将选择后者。

答案 1 :(得分:-1)

您的问题来自

 IF BoolExpression THEN Statement ELSE Statement

如果THEN之后的语句包含IF,您如何知道ELSE是属于第一个还是第二个IF?有关详细信息,请参阅此处:http://www.gnu.org/software/bison/manual/html_node/Shift_002fReduce.html

唯一100%非模糊的修复是要求在if / else语句周围使用某种分隔符(大多数语言使用括号“{”和“}”)。前,

 IF BoolExpression THEN '{' Statement '}' ELSE '{' Statement '}'