0

总而言之,与 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
      ;
4

1 回答 1

1

我不确定您在问题中所说的“工作”是什么意思。该在线解析器生成器报告 LR(1) 和 LALR(1) 算法的移位减少冲突,这并不令人惊讶,因为您的语法包括指数模棱两可

Mul -> Mul * Mul

显然,该站点的 LR(1) 实现比 LALR(1) 实现更轻松地处理错误。我会说这是一个错误。但无论如何,文法不能生成 LALR(1) 或 LR(1) 解析器。

于 2020-07-30T23:58:09.140 回答