我试图通过在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 >=
答案 0 :(得分:1)
检测到您的班次减少冲突,因为>=
位于Expression
非终端的跟随集中。这主要是因为Statement
可以是Expression
而IntExpression
可以以statement
结尾。考虑以下输入IF c THEN S1 ELSE S2 >= 42
,如果您有括号来消除歧义,则可以将其解释为(IF c THEN S1 ELSE S2) >= 42
和IF 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 '}'