2

考虑 LR 系列解析生成器(例如 YACC、BISON 等)的语法规则:

Nonterminal : [ lookahead not in {Terminal1, ..., TerminalN} ] Rule ;

这是一条普通的规则,只是它有一个限制:用这条规则产生的短语不能以 . 开头Terminal1, ..., TerminalN。(当然,这个规则可以用一套常用的规则来代替,但它会导致更大的语法)。这对于解决冲突很有用。

问题是,是否存在接受此类限制的 LR 表构造算法的修改?在我看来,这样的修改是可能的(如优先关系)。

当然,它可以在运行时检查,但我的意思是编译时检查(在构建解析表时执行的检查,如yacc兼容生成器中的 、 和指令%prec。)%left%right%nonassoc

4

1 回答 1

1

我不明白为什么这是不可能的,但我也看不出有任何明显的理由说明它会有用。你有一个例子吗?

最简单的方法是进行括号中提到的语法转换。这会产生更大的语法,但不会人为地增加 LR 状态的数量。

基本的转变,只需要一点点挥手:

对于任何有终端限制的生产:

  • 如果生产以不可为空的非终端开始,请将非终端替换为终端限制版本。

  • 如果生产以终端限制列表中的终端开始,则删除生产

  • 如果生产以不在终端限制列表中的终端开始,则无需更改。

如果产生式以可空非终结符开头,则必须创建可空非终结符的两个版本,一个始终为空,另一个不可为空;然后创建两个版本的产品,一个从每个新的非终端开始。然后应用上述转换,但将“开始于”解释为“在任何始终为空的非终结符之后开始”。

您实际上不需要修改语法,因为上述转换可以在底层 SLR 机器的构建过程中即时完成,至少对于 LR(0) 和 LALR(1) 构造。

于 2013-04-21T06:02:41.783 回答