LR解析算法中的否定先行

时间:2013-04-20 00:21:50

标签: parsing generator conflict resolve negative-lookahead

在LR-family解析生成器(例如YACC,BISON等)的语法中考虑这样的规则:

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

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

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

当然,它可以在运行时检查,但我的意思是编译时检查(在构建解析表时执行的检查,如%prec%left%right和{ yacc-compartible generator中的{1}}指令。)

1 个答案:

答案 0 :(得分:1)

我不明白为什么这不应该是可能的,但我也没有看到任何明显的原因,为什么它会有用。你有一个例子吗?

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

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

对于任何有终端限制的制作:

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

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

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

如果一个产品以一个可以为空的非终端开始,你必须创建两个可以为空的非终端版本,其中一个版本始终为null,另一个版本不可为空;然后创建两个版本的生产,一个从每个新的非终端开始。然后应用上面的变换,但解释“以...开头”意味着“从任何始终为空的非终端之后开始。”

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