总而言之,与 LALR(1) 相比,LR(1) 在各方面都应该更强大,因为 LR(1) 构建了 LR(1) 项的规范集合,而 LALR(1) 只是一个更好的 SLR(1)解析器。
那么当我尝试这个输入时,为什么这个语法在 LALR(1) 解析器中成功运行,但在 LR(1) 解析器中却没有:
int + int
对于这个语法:
S' -> S
S -> Add
Add -> Mul
Add -> Add + Mul
Mul -> Const
Mul -> Mul * Mul
Const -> int
Const -> float
这些是我用于此示例的 JavaScript LR(1) 和 JavaScript LALR(1) 解析器:http:
//jsmachines.sourceforge.net/machines/lr1.html
http://jsmachines.sourceforge.net/machines/lalr1.html
更新
JSmachine 网站有很多错误。我改用南佛罗里达大学的https://zaa.ch/jison/try/usf/index.html这个网站,但有人建议我使用 Bison 来确保正确性。正如最高评论所建议的那样,Mul -> Mul * Mul
非常模棱两可,所以我相应地更新了语法
S' -> S
S -> Add
Add -> Mul
Add -> Add + Mul
Mul -> Const
Mul -> Mul * Const
Const -> int
Const -> float
适配BNF格式:
%%
SS : S ;
S : Add ;
Add : Mul
| Add '+' Mul
;
Mul : Const
| Mul '*' Const
;
Const : int
| float
;