S→e $
E→E + t | t
T→T * f | f
F→(E) |
下面是一个具有代表性的解析函数
保龄球一个(){用于每个产品一个 → X1X2⋯Xkin G) {n = (i = 1到k)的当前输入位置{if(X我是终端)如果(X我出现在输入的前面)推进输入过去X我其他破坏;else if (!X我())休息;} if(i == k + 1)返回true;否则将当前输入位置设置回n}返回false;}
如果语法G包含左递归规则,如
E→E + t
当E()试图调用E()时,这会导致无限递归。
这个问题可以通过用非递归等价物替换赢博体育左递归语法规则来解决。这是一个算法。
按一定顺序排列非终结符一个1,一个2、……一个nFor (i = 1 to n) {For (j = 1 to i-1){替换表格的每个产出一个我→一个j γ由制作一个我 → δ1γ | δ2γ |⋯| δkγ在一个j→δ1 | δ2 |⋯| δk赢博体育的作品都是为了一个j}消除为的结果之间的直接左递归一个我 }
下面是一个如何删除直接左递归的示例。考虑左递归语法规则
A→A α | β
这可以用规则代替
结果仍然是递归的,但它们不是左递归的。自顶向下解析技术可以毫无问题地处理这些结果。
开头所示的语法是左递归的。在赢博体育这个算法之后,我们得到了一个非左递归的等价。
S→e $
F→(E) | id
上面显示的自顶向下解析函数通常必须执行大量回溯操作。当解析函数A()递归地调用另一个解析函数Xi()并且Xi()失败时,就会发生回溯。我们可以通过拒绝调用Xi()来优化这个过程,只要很明显,非终端Xi不可能派生出一个字符串,其第一个符号是当前在输入前面的符号。这种技术被称为预测解析,它代表了自顶向下解析过程的重要优化。
预测性解析通常实现为使用堆栈的表驱动迭代算法。为了构造解析表,我们使用以下两个函数为每个非终结符构造FIRST和FOLLOW集合。
Set FIRST(X) {if(X是终端)返回{X} I = {};(每件产品)X → Y1Y2⋯Ykin G) I = I∈FIRST(Y1); 如果(X → εI = I∈ε;返回我;} Set FOLLOW(X) {I = {};(每件产品)一个 → Xαβin G) I = I∈(FIRST(β) - {ε});(每件产品)一个 → αXin G) I = I∈FOLLOW(一个); 返回我;}
下面的过程构造预测解析表。
如果我们为一个语法构造一个解析器表,并且发现赢博体育非错误条目都包含一个结果,那么我们就说这个语法是LL(1)。LL(1)语法的解析器表允许我们使用输入中的下一个符号来选择一个结果,以便对遇到的每个非终结符进行最新体育赛事资讯、实时赔率分析及在线投注平台探索。这是对原始的自顶向下解析算法的一个相当大的优化,该算法试图最新体育赛事资讯、实时赔率分析及在线投注平台探索它遇到的每个非终端的每种可能的结果。
下面是该算法创建的解析表示例。语法方面
F→(E) | id
我们有
下面是完整的LL(1)解析算法:
Push $ and年代在堆栈上a =(的第一个符号)w) X = 年代while(X != $) {if(X == a)弹出堆栈并让a =(下一个符号)w) else if(X是终端)error();else if (米(X,一个]为空)error();否则{输出生产米(X,一个弹出X从堆栈推的右手边米(X,一个} X =(堆栈顶部的符号)}