给出一个简单的语法,比如
rule1
:= token1 token2 token3 token4
|| token1 token2 token3 token3;
转移前三个令牌之间有什么区别,然后查看第四个令牌以查看要减少的规则,并简单地执行三个令牌的前瞻以查看要减少哪个规则?
答案 0 :(得分:9)
在shift / reduce解析器中,前瞻不用于确定正在考虑哪个生产,而是用于决定解析器是应该移动下一个令牌还是采取某种reduce操作。如果您有上述语法的shift / reduce解析器,解析器总是会在决定是否减少之前移动四个令牌;请记住,在LR解析器中,仅当适当的符号系列位于解析堆栈顶部时才执行缩减。如果解析器无法判断它是否应该减少它所拥有的四个标记,或者继续移动更多符号并稍后减少,那么Lookahead只在这里是必要的。
具体来说,解析器可能会执行以下操作:
Stack Input Action
-------------------------------------------------------------------------------
token1 token2 token3 token4 Shift
token1 token2 token3 token4 Shift
token1 token2 token3 token4 Shift
token1 token2 token3 token4 Shift
token1 token2 token3 token4 Reduce, Option 1
rule1 Accept
或者
Stack Input Action
-------------------------------------------------------------------------------
token1 token2 token3 token3 Shift
token1 token2 token3 token3 Shift
token1 token2 token3 token3 Shift
token1 token2 token3 token3 Shift
token1 token2 token3 token3 Reduce, Option 2
rule1 Accept
请注意,这与LL(k)解析器等自上而下的解析器形成对比,后者通过尝试预测要使用的生产来工作。在这种情况下,需要四个先行令牌,因为解析器猜测生产然后检查其猜测(预测/匹配解析)。例如,在自上而下的解析器(这里必须是LL(4))中,它将执行以下操作:
Stack Input Action
----------------------------------------------------------------------------------
rule1 token1 token2 token3 token4 $$$$ Predict, Option 1
token1 token2 token3 token4 token1 token2 token3 token4 $$$$ Match
token2 token3 token4 token2 token3 token4 $$$$ Match
token3 token4 token3 token4 $$$$ Match
token4 token4 $$$$ Match
$$$$ Accept
或者
Stack Input Action
----------------------------------------------------------------------------------
rule1 token1 token2 token3 token3 $$$$ Predict, Option 2
token1 token2 token3 token3 token1 token2 token3 token3 $$$$ Match
token2 token3 token3 token2 token3 token3 $$$$ Match
token3 token3 token3 token3 $$$$ Match
token3 token3 $$$$ Match
$$$$ Accept
注意如何预测要使用哪个生产,因此解析器必须有四个前瞻标记。在LR解析器中,解析器通过检查更多令牌来工作,直到它看到它正在查找的内容变得舒适,然后减少(移位/减少解析)。在这种情况下,根本不需要前瞻。 Lookahead仅在LR解析器中需要确定解析器是否已经看到句柄的末尾(要减少的字符串),或者它是否在句柄的中间并且必须继续移位。这就是为什么,例如,一些有趣的语法可以显示为LR(0),但唯一的LL(0)语法是语法,其中每个非终结者只有一个与之相关的生成;前瞻性在自上而下与自下而上的解析中有着根本不同的用途。
一般来说,自上而下的解析器可以处理比自下而上的解析器更少的语法,实际上任何LL(k)语法都保证是LR(k),但不是相反。
希望这有帮助!