野牛使用了错误的规则

Wrong rule used in bison

我正在尝试使用 bison 执行语法分析,但它有一次使用了错误的规则,我没能找到修复方法。 我有一些规则,但这些似乎是问题的根源:

method : vars statements;

vars : //empty
  | vars var;

var : type IDENTIFIER ';';

type : IDENTIFIER;

statements : //empty
  | statements statement;

statement : IDENTIFIER '=' e ';';

e : (...)

IDENTIFIER 是匹配 [a-zA-Z]*

的简单正则表达式

所以基本上,如果我这样写:

int myint;
myint = 12;

由于 myint 是一个标识符,bison 似乎仍然尝试在第二行将其作为类型进行匹配,然后将整个事物作为 var 而不是作为语句进行匹配。所以我得到这个错误(知道 ASSIGN 是'='):

syntax error, unexpected ASSIGN, expecting IDENTIFIER

编辑:请注意,bison 表示存在 shift/reduce 错误,因此它可能已链接(如答案中所述)。

您遇到的问题是由于空 statements 规则导致的 shift-reduce 冲突的默认解决方案——它需要知道是否减少空 statement 并开始匹配语句,或者移动可能开始另一个 var 的 IDENTIFIER。所以它决定移动,这将它放在 var 路径下。

您可以通过重构语法来避免此问题,以避免出现空产生式:

method: vars | vars statements | statements ;
vars: var | vars var ;
statements : statement | statements statement ;
... rest the same

这避免了需要知道某物是 var 还是语句,直到移动到足够远才能分辨出来。