0

我试图通过在 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 >=
4

2 回答 2

1

检测到您的轮班减少冲突,因为>=它位于Expression非终端的后续集中。这基本上是由于 aStatement可以是 aExpression并且IntExpression可以以 a 结尾statement。考虑以下输入IF c THEN S1 ELSE S2 >= 42,如果您有括号要消除歧义,则可以将其解释为(IF c THEN S1 ELSE S2) >= 42IF c THEN S1 ELSE (S2 >= 42)。由于 shift 优于 reduce,因此将选择后者。

于 2013-04-14T00:33:16.260 回答
-1

你的问题来自

 IF BoolExpression THEN Statement ELSE Statement

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

唯一 100% 明确的解决方法是要求在 if/else 语句周围使用某种分隔符(大多数语言使用括号“{”和“}”)。前任,

 IF BoolExpression THEN '{' Statement '}' ELSE '{' Statement '}'
于 2013-04-11T13:51:12.303 回答