LR(1)解析器如何处理空规则?

时间:2017-04-01 17:57:45

标签: parsing finite-automata menhir

我曾与一些解析器(Yacc,Bison和Menhir)合作过。如果我没记错的话,所有这些都允许规则为空。这是我使用Menhir的一个例子,它是我最常用的一个。

some_list:
 | {[]}
 | some_non_empty_list { $1 }

some_non_empty_list:
 | SEMICOLON some_list { $2 }
 | element { [$1] }
 | element some_non_empty_list { $1 :: $2 }

重要的部分是some_list可以减少虚无。

我目前对构建解析表(构建NFA,从NFA构建DFA,最小化)的算法的理解使我认为这会导致整个地方的移位/减少冲突。但它显然没有,因为我的代码当时有效。

那么如何构建一个可以接受这些空规则的解析表?

1 个答案:

答案 0 :(得分:1)

为什么您认为空规则比带有一个右侧令牌的规则难处理?

过于简化,语法规则L = R1 R2 R3;表示“如果看到R1 R2 R3,则降为L”。不简化,如果我们有X = A L B;那么我们的L规则意味着“如果您的左上下文是A,您已经看过R1 R2 R3,并且下一个标记是first(B),则减少到L。

如果L = R1 R2,则此想法相同;并且L = R1;。

甚至对于(空规则)的极限情况:L =;

除非您已经看到L的左上下文,其内容以及随后内容的开头,否则您不能简化为L。因此,您无法在“任何时候”简化为空规则。

您需要做的是通过学习如何在建立分析状态时跟踪项目集来了解LR解析器的工作方式。一次在纸上做一个小语法(痛苦的是,值得的),LR解析器将变得很清晰。您可以在有关LR解析的任何书籍(包括Aho等人的经典Compilers)中找到描述的过程。