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

标签 parsing lr-grammar lr1

我阅读了几篇有关创建 LR(1) 项集的论文,但没有一篇涉及左递归语法,例如用于解析表达式的语法。如果我有以下语法,

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

我将如何创建 LR(1) 项目集?

最佳答案

对于 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 + T [$]E 后面的内容给出。在本例中,我们正在寻找具有 + 前瞻的 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     [+]

我们现在必须在 T -> .T * F [$] 的上下文中扩展 T,为此我们列出了T 后跟 T -> .T * F [$]T 后面的内容(即 *)。这给我们带来了以下结果:

(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 之前有一个点的产生式。根据目前的情况,您知道如何做到这一点吗?

关于parsing - 左递归语法的 LR(1) 项集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71296252/

相关文章:

c# - 加速解析算法

php - 匹配包含两个 "needles"的字符串

parsing - 了解语法是否是 LR(1) 且没有解析表

qml - QML 语法是 LALR(1) 吗?

parsing - LR(1) 语法 : how to tell? 支持/反对的例子?

c# - 如何一次读取一个 csv 文件并替换/编辑某些行?

java - 如何在java中获取嵌套XML中的父标签?

parsing - 是否可以将这个文法转化为LR(1)文法?

parsing - 具有 epsilon 转换的左递归 LR(0) 项的闭包是什么?