非终端也有转换,我不明白。如果输入为aab
。那么你将最终处于A->a·
状态。如果您想通过输入aab
或任何其他输入来显示所达到的状态,那么在它们之间没有弧线的状态之间会发生转换吗?
我不明白为什么这与DFA或NFA不同,在DFA或NFA中,您从起始状态开始,并且只在自动机中沿着弧线转换,直到您达到接受状态。
答案 0 :(得分:1)
LR解析使用下推状态堆栈,它在任何时候都代表解析中尚未识别的未完全识别的产生的集合。当达到完整生产的状态时(点位于末尾,例如' A -> a.
'),这意味着堆栈在此生产的右侧有符号在顶部。你将它们弹出以回到启动这个特定转换序列的状态,然后在本产品的左侧进行非终端的转换。
所以,如果你到达A -> a.
'您必须备份一个转换(标记为' a
')的路径并采取' A
'过渡而不是。如果您达到S -> AB.
'你必须备份两个过渡并采取' S
'过渡而不是。等等。
DFA或NFA没有这样的回溯(或维持堆叠的相应需求)。
答案 1 :(得分:0)
仅在执行reduce步骤后才会跟踪标有非终结符的转换。执行reduce操作时,将从解析堆栈中删除一些符号,然后将非终结符号移到堆栈上。此时,您将遵循标记为特定非终结符的转换。
解析自动机与典型的DFA或NFA的不同之处在于它设计用于控制堆栈。转换都对应于解析堆栈上的不同操作;每个终端对应一个班次,完成的项目对应减少,非终端告诉你在减少之后去哪里。从理论上讲,LR自动机是确定性下推自动机的控制,如果有帮助的话。
答案 2 :(得分:0)
LR自动机是一种下推式自动机,它使用一堆状态,而不是像DFA那样使用单个当前状态。动作(shift,reduce和goto)由当前位于堆栈顶部的状态控制,shift和goto按下新状态并根据减少的规则减少弹出固定数量的状态。在您的示例中,如果我们对列中的状态进行编号(因此0是左上角的初始状态,3是中间列中的状态),我们可以显示它如何解析输入字符串' ab' :
Action Stack
initial state 0
shift a 0 1
reduce A->a 0
goto A 0 3
shift b 0 3 4
reduce B->b 0 3
goto B 0 3 5
reduce S->AB 0
goto S 0 2
accept
由于这是一个LR(0)解析器,每个状态都有shift / goto动作或单个reduce动作,并且不需要前瞻来知道下一步该做什么(尽管一个消耗输入令牌的转移,依赖于该令牌来确定要转移到哪个州。)
输入' aab'这个过程只有一点点了:
Action Stack
initial state 0
shift a 0 1
reduce A->a 0
goto A 0 3
shift a 0 3 1
reduce A->a 0 3
goto A 0 3 3
shift b 0 3 3 4
reduce B->b 0 3 3
goto B 0 3 3 5
reduce S->AB 0 3
goto S 0 3 6
reduce B->S 0 3
goto B 0 3 5
reduce S->AB 0
goto S 0 2
accept
显示右侧 - 拒绝规则的效果,以匹配输入中的多个a(B - > S - > AB),这会导致所有a被移位(推送)堆栈上的状态)直到达到重复序列的末尾,然后是一系列reduce / goto操作以将它们弹回。使用左递归规则更好,并使用固定数量的堆栈空间,交替移位并减少。