左递归语法的 LR(1) 项集
我读过几篇关于创建 LR(1) 项集的论文,但没有一篇涉及左递归语法,例如用于解析表达式的语法。如果我有以下语法,
E -> E + T | T
T -> T * F | F
F -> (E) | NUMBER
我将如何创建 LR(1) 项目集?
I read several papers about creating LR(1) item sets, but none of them pertained to left recursive grammars, such as those used for parsing expressions. If I had the following grammar,
E -> E + T | T
T -> T * F | F
F -> (E) | NUMBER
How would I go about creating the LR(1) item sets?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于 LR(1) 解析器来说,左递归本质上并不是一个问题,并且无论您的语法是否具有左递归,确定配置集和前瞻的规则都是相同的。
在您的例子中,我们首先使用新的开始符号增强语法:
我们的初始配置集对应于查看生产
S -> E
,前瞻为$
。最初,这给我们带来了以下结果:我们现在需要扩展 E 的范围。这给了我们这些新项目:
现在,让我们看看项目
E ->; .E + T [$]
。我们需要扩展E
可能在这里,这样做的规则与非左递归情况相同:我们列出E
的所有产生式点在前面,前瞻由产生式E ->; 中
。在本例中,我们正在寻找具有E
后面的内容给出。 .E + T [$]+
前瞻的E
,因为这就是产生式中的内容。这添加了这些项目:从这里开始,我们展开了
T
之前有一个点的所有情况,这给出了以下内容:我们现在必须展开
T
在T -> 的上下文中.T * F [$]
,我们通过列出T
的所有产生式来做到这一点,然后列出T
后面跟在T 中的内容 - > .T * F [$]
(即*
)。这给了我们以下结果:从这里开始,我们将扩展
F
之前有一个点的产生式。根据目前的情况,你知道如何做到这一点吗?Left recursion isn't inherently a problem for LR(1) parsers, and the rules for determining the configurating sets and lookaheads is the same regardless of whether your grammar has left recursion.
In your case, we begin by augmenting the grammar with our new start symbol:
Our initial configurating set corresponds to looking at the production
S -> E
with a lookahead of$
. Initially, that gives us the following:We now need to expand out what E could be. That gives us these new items:
Now, let's look at the item
E -> .E + T [$]
. We need to expand out whatE
could be here, and the rules for doing so are the same as in the non-left-recursive case: we list all productions forE
with the dot at the front, with a lookahead given by what follows theE
in the productionE -> .E + T [$]
. In this case we're looking for anE
with a lookahead of+
because that's what follows is in the production. That adds these items:From here, we expand out all the cases where there's a dot before a
T
, which gives the following:We now have to expand out the
T
s in the context ofT -> .T * F [$]
, and we do so by listing all productions ofT
followed by what theT
is followed by inT -> .T * F [$]
(namely,*
). That gives us the following:And from here we'd expand out the productions that have a dot before the
F
. Do you see how to do that based on how things have played out so far?