在本文中,我们将概述运算符优先级解析器,并主要关注运算符优先级解析器的作用。并且还将介绍构建优先级函数的算法,最后将讨论运算符优先级解析中的错误恢复。让我们一一讨论。
介绍 :
运算符优先级解析器,用于运算符优先级语法。运算符优先级语法是一种不包含ε产生式且在任何产生式的RHS上不包含两个相邻非终结点的语法。优先级规则提供了运算符优先级语法。运算符优先级语法可以是模棱两可的或模棱两可的。
运算符优先级解析器算法:
1. If the front of input $ and top of stack both have $, it's done
else
2. compare front of input b with ⋗
if b! = '⋗'
then push b
scan the next input symbol
3. if b == '⋗'
then pop till ⋖ and store it in a string S
pop ⋖ also
reduce the poped string
if (top of stack) ⋖ (front of input)
then push ⋖ S
if (top of stack) ⋗ (front of input)
then push S and goto 3
组件操作图:
例子 –
让我们以一个例子来理解运算符优先级的作用,如下所示。
E-> E+T/T
T-> T*V/V
V->a/b/c/d
string= "a+b*c*d"
字符串“ a + b * c * d”的上述算法的实现如下。
Stack | Input | Stack Top | Current Input | Action |
---|---|---|---|---|
$ | a+b*c*d$ | $ | a | shift a |
$a | +b*c*d$ | A | + | reduce using A->a |
$V | +b*c*d$ | V | + | reduce using T->V |
$T | +b*c*d$ | T | + | reduce using E->T |
$E | +b*c*d$ | E | + | shift + |
$E+ | b*c*d$ | b | * | reduce using V->b |
$E+V | b*c*d$ | V | * | reduce using T->V |
$E+T | *c*d$ | T | * | shift * |
$E+T* | c*d$ | * | c | shift c |
$E+T*c | *d$ | c | * | reduce using V->c |
$E+T*V | *d$ | V | * | reduce using T->T*V |
$E+T | *d$ | T | * | shift * |
$E+T* | d$ | * | d | shift d |
$E+T*d | $ | d | $ | reduce using V->d |
$E+T*V | $ | V | $ | reduce using T->T*v |
$E+T | $ | T | $ | reduce using E->E+T |
$T | $ | E | $ | accept |
优先函数的构造算法:
- 为每个语法终端a和字符串符号的末尾生成函数Xa。
- 如果a≐b,则将符号分成组,以使Xa和Yb是相同的组。
- 生成有向图,其节点在组中,对于每个符号a和b,如果a⋖b,则确实放置从Yb组到Xa组的边,否则,如果a⋗b放置在Xa组的边上到Yb。
- 如果构造的图具有循环,则不存在过程函数。当没有循环时,分别从Xa和yb组中收集最长路径的长度。
例子 –
让我们以一个例子来理解优先级函数的构造,如下所示。
E -> E + E/E * E/( E )/id
在这里,您将看到运算符优先级关系表和优先级关系图图。我们来看一下。
因为我们看不到循环,所以图中没有循环,因此可以使此函数表如下所示。
列表示函数:
列代表函数Ya,行代表函数Xa –
它是通过从Xid到X $和Yid到Y $的最长路径来计算的。
fid -> g* -> f+ ->g+ -> f$
gid -> f* -> g* ->f+ -> g+ ->f$
- 运算符优先级关系表的缺点是,如果符号数为n,则我们需要一个n * n的表来存储它们。另一方面,通过使用运算符函数表,要容纳n个符号,我们需要2 * n的表。运算符优先级语法无法确定一元减号(词法分析器应处理一元减号)。
- 使用运算符优先级语法的优点是简单,并且足够强大,可以在编程语言中进行表达。
运算符优先级解析中的错误恢复:
- 错误案例–
1.堆栈顶部的端子与下一个输入符号之间没有关系。
2.找到了一个手柄(缩小步骤),但该手柄作为右侧没有生产。 - 错误恢复–
1.每个空条目都填充有一个指向错误例程的指针。
2.确定弹出的手柄“看起来像”在右侧。并试图从这种情况中恢复过来。 - 处理移位/减少错误–
为了解决此类错误,我们必须修改以下内容。
1.堆叠
2 。输入
3.或两者兼而有之