左递归语法的 LR(1) 项集

发布于 2025-01-10 13:53:17 字数 171 浏览 0 评论 0原文

我读过几篇关于创建 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

誰ツ都不明白 2025-01-17 13:53:17

对于 LR(1) 解析器来说,左递归本质上并不是一个问题,并且无论您的语法是否具有左递归,确定配置集和前瞻的规则都是相同的。

在您的例子中,我们首先使用新的开始符号增强语法:

S -> E
E -> E + T | T
T -> T * F | F
F -> (E) | NUMBER

我们的初始配置集对应于查看生产 S -> E,前瞻为 $。最初,这给我们带来了以下结果:

(1)
    S -> .E     [$]

我们现在需要扩展 E 的范围。这给了我们这些新项目:

(1)
    S -> .E     [$]
    E -> .E + T [$]
    E -> .T     [$]

现在,让我们看看项目 E ->; .E + T [$]。我们需要扩展 E 可能在这里,这样做的规则与非左递归情况相同:我们列出 E 的所有产生式点在前面,前瞻由产生式 E ->; 中 E 后面的内容给出。 .E + T [$]。在本例中,我们正在寻找具有 + 前瞻的 E,因为这就是产生式中的内容。这添加了这些项目:

(1)
    S -> .E     [$]
    E -> .E + T [$]
    E -> .T     [$]
    E -> .E + T [+]
    E -> .T     [+]

从这里开始,我们展开了 T 之前有一个点的所有情况,这给出了以下内容:

(1)
    S -> .E     [$]
    E -> .E + T [$]
    E -> .T     [$]
    E -> .E + T [+]
    E -> .T     [+]
    T -> .T * F [$]
    T -> .F     [$]
    T -> .T * F [+]
    T -> .F     [+]

我们现在必须展开 TT -> 的上下文中.T * F [$],我们通过列出 T 的所有产生式来做到这一点,然后列出 T 后面跟在 T 中的内容 - > .T * F [$](即*)。这给了我们以下结果:

(1)
    S -> .E     [$]
    E -> .E + T [$]
    E -> .T     [$]
    E -> .E + T [+]
    E -> .T     [+]
    T -> .T * F [$]
    T -> .F     [$]
    T -> .T * F [+]
    T -> .F     [+]
    T -> .T * F [*]
    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:

S -> E
E -> E + T | T
T -> T * F | F
F -> (E) | NUMBER

Our initial configurating set corresponds to looking at the production S -> E with a lookahead of $. Initially, that gives us the following:

(1)
    S -> .E     [$]

We now need to expand out what E could be. That gives us these new items:

(1)
    S -> .E     [$]
    E -> .E + T [$]
    E -> .T     [$]

Now, let's look at the item E -> .E + T [$]. We need to expand out what E could be here, and the rules for doing so are the same as in the non-left-recursive case: we list all productions for E with the dot at the front, with a lookahead given by what follows the E in the production E -> .E + T [$]. In this case we're looking for an E with a lookahead of + because that's what follows is in the production. That adds these items:

(1)
    S -> .E     [$]
    E -> .E + T [$]
    E -> .T     [$]
    E -> .E + T [+]
    E -> .T     [+]

From here, we expand out all the cases where there's a dot before a T, which gives the following:

(1)
    S -> .E     [$]
    E -> .E + T [$]
    E -> .T     [$]
    E -> .E + T [+]
    E -> .T     [+]
    T -> .T * F [$]
    T -> .F     [$]
    T -> .T * F [+]
    T -> .F     [+]

We now have to expand out the Ts in the context of T -> .T * F [$], and we do so by listing all productions of T followed by what the T is followed by in T -> .T * F [$] (namely, *). That gives us the following:

(1)
    S -> .E     [$]
    E -> .E + T [$]
    E -> .T     [$]
    E -> .E + T [+]
    E -> .T     [+]
    T -> .T * F [$]
    T -> .F     [$]
    T -> .T * F [+]
    T -> .F     [+]
    T -> .T * F [*]
    T -> .F     [*]

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文