为什么这个文法适用于 LALR(1) 但不适用于 LR(1)
Why does this Grammar work in LALR(1) but not LR(1)
从各方面来看,与 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
;
我不确定你问题中的“工作”是什么意思。该在线解析器生成器报告 LR(1) 和 LALR(1) 算法的移位减少冲突,这并不奇怪,因为您的语法包含指数歧义
Mul -> Mul * Mul
显然,该站点的 LR(1) 实现在处理错误时不如其 LALR(1) 实现优雅。我会说这是一个错误。但无论如何,语法不能生成 LALR(1) 或 LR(1) 解析器。
从各方面来看,与 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
;
我不确定你问题中的“工作”是什么意思。该在线解析器生成器报告 LR(1) 和 LALR(1) 算法的移位减少冲突,这并不奇怪,因为您的语法包含指数歧义
Mul -> Mul * Mul
显然,该站点的 LR(1) 实现在处理错误时不如其 LALR(1) 实现优雅。我会说这是一个错误。但无论如何,语法不能生成 LALR(1) 或 LR(1) 解析器。