📜  自下而上或 Shift Reduce 解析器 | 2套

📅  最后修改于: 2021-09-27 15:00:11             🧑  作者: Mango

在本文中,我们将讨论自底向上解析器。
自底向上解析器/Shift Reduce解析器
构建从叶子到根的解析树。自下而上的解析可以定义为通过反向追踪 w 的最右边的派生来尝试将输入字符串w 减少到语法的起始符号。
例如。

自底向上解析器的分类

一般的移位归约解析是 LR 解析。 L 代表从左到右扫描输入,R 代表反向构造最右边的推导。
LR解析的好处:

  1. 许多使用 LR 解析器变体的编程语言。应该注意的是,C++ 和 Perl 是例外。
  2. LR Parser 可以非常有效地实现。
  3. 在所有从左到右扫描符号的解析器中,LR 解析器会尽快检测到语法错误。

在这里,我们将通过使用所有四种 LR 解析技术来构建语法的 GOTO 图。为了解决 GATE 中的问题,我们必须直接为给定的语法构造 GOTO 以节省时间。 LR(0) 解析器
我们需要两个函数——
关闭()
去()

增强语法
如果 G 是一个带有起始符号 S 的文法,那么 G 的增广文法 G’ 是具有新的起始符号 S’ 和一个产生式 S’ -> S 的文法。这个新的起始产生式的目的是向解析器表明当它应该停止解析并宣布接受输入时。
令文法为 S -> AA
A -> aA |乙
上述文法的增广文法将是
S’ -> S
S -> AA
A -> aA |乙

LR(0) 项目
LR(0) 是文法的项 G 是 G 的产生式,在右侧的某个位置有一个点。
S -> ABC 产生四项
S -> .ABC
S -> A.BC
S -> AB.C
S -> ABC。
产生式 A -> ε 只生成一项 A -> .ε

关闭操作
如果 I 是文法 G 的一组项目,则闭包 (I) 是由 I 通过以下两个规则构造的项目集:

  1. 最初 I 中的每一项都被添加到闭包(I)中。
  2. 如果 A -> α.Bβ 在闭包 (I) 中并且 B -> γ 是产生式,则将项目 B -> .γ 添加到 I,如果它不存在。我们应用这个规则直到没有更多的项目可以添加到闭包(I)。

例如:
转到操作
Goto(I, X) = 1. 通过在 X 之后移动点来添加 I。
2. 将封闭应用于第一步。
构建GOTO图-

  • 状态 I 0 – 增强 LR(0) 项的关闭
  • 在 DFA 的帮助下,使用 I 0查找 LR(0) 项集的所有集合
  • 将 DFA 转换为 LR(0) 解析表

LR(0)解析表的构建

  • 动作函数将状态 i 和终端 a(或 $ ,输入结束标记)作为参数。 ACTION[i, a] 的值可以是以下四种形式之一:
    1. 移位 j,其中 j 是一个状态。
    2. 减少 A -> β。
    3. 接受
    4. 错误
  • 我们将定义在项目集上的 GOTO函数扩展到状态:如果 GOTO[I i , A] = I j那么 GOTO 也将状态 i 和非终结符 A 映射到状态 j。

例如:
考虑语法 S ->AA
A -> aA |乙
增广文法 S’ -> S
S -> AA
A -> aA |乙

上面 GOTO 图的 LR(0) 解析表将是 –

表的动作部分包含语法的所有终结符,而 goto 部分包含所有非终结符。对于 goto 图的每个状态,我们将所有 goto 操作写入表中。如果 goto 应用于终端而不是写入操作部分,如果 goto 应用于非终端,则写入 goto 部分。如果在应用 goto 时产生式减少(即如果点到达产生式结束并且不能应用进一步的闭合),则表示为 R i ,如果产生式没有减少(移位),则表示为 S i .
如果产生式减少,则将其写在产生式左侧的后续给出的终端下,例如:在 I 5 S->AA 减少,因此 R 1写在 follow(S)= 中的终端下{$}(要了解有关如何计算跟随函数的更多信息:单击此处)在 LR(0) 解析器中。
如果在某种状态下,语法的起始符号被减少,则它被写在 $ 符号下作为接受。

注意:如果在任何状态下都存在减少和移位产生式或存在两个减少产生式,则称为冲突情况并且该语法不是 LR 语法。