CLR是指规范的前瞻。 CLR解析使用LR(1)项的规范集合来构建CLR(1)解析表。与SLR(1)解析相比, CLR(1)解析表产生的状态数更多。
在CLR(1)中, 我们仅将reduce节点放置在超前符号中。
CLR(1)解析涉及的各个步骤:
- 对于给定的输入字符串, 编写上下文无关的语法
- 检查语法的歧义
- 在给定的语法中添加增值产生
- 创建LR(0)个项目的规范集合
- 绘制数据流程图(DFA)
- 构造CLR(1)解析表
LR(1)件
LR(1)项目是LR(0)项目和前瞻符号的集合。
LR(1)件= LR(0)件+向前看
前瞻性用于确定我们放置最终物品的位置。
向前看总是为参数产生添加$符号。
例
CLR(1)语法
S → AA
A → aA
A → b
添加增广生产, 在G中每个生产的第一个位置插入“•”符号, 并添加前瞻。
S` → •S, $
S → •AA, $
A → •aA, a/b
A → •b, a/b
I0状态:
将增产增加到I0状态并计算关闭
I0 =闭合(S`→•S)
将所有以S开头的产品添加到I0状态, 因为“。”其次是非终结符。因此, I0状态变为
I0 = S`→•S, $ S→•AA, $
将所有以A开头的产品添加到修改的I0状态中, 因为“。”其次是非终结符。因此, I0状态变为。
I0 = S`→•S, $ S→•AA, $ A→•aA, a / b A→•b, a / b
I1 =转到(I0, S)=闭包(S`→S•, $)= S`→S•, $ I2 =转到(I0, A)=闭包(S→A•A, $)
在I2州添加所有以A开头的产品, 因为“。”其次是非终结符。因此, I2状态变为
I2 = S→A•A, $ A→•aA, $ A→•b, $
I3 =转到(I0, a)=闭包(A→a•A, a / b)
在I3州添加所有以A开头的产品, 因为“。”其次是非终结符。因此, I3状态变为
I3 = A→a•A, a / b A→•aA, a / b A→•b, a / b
转到(I3, a)=闭包(A→a•A, a / b)=(与I3相同)转到(I3, b)=闭包(A→b•, a / b)=(与I4相同)
I4 =转到(I0, b)=闭包(A→b•, a / b)= A→b•, a / b I5 =转到(I2, A)=闭包(S→AA•, $)= S→AA•, $ I6 =转到(I2, a)=闭包(A→a•A, $)
在I6州添加所有以A开头的产品, 因为“。”其次是非终结符。因此, I6状态变为
I6 = A→a•A, $ A→•aA, $ A→•b, $
转到(I6, a)=闭包(A→a•A, $)=(与I6相同)转到(I6, b)=闭包(A→b•, $)=(与I7相同)
I7 =转到(I2, b)=闭包(A→b•, $)= A→b•, $ I8 =转到(I3, A)=闭包(A→aA•, a / b)= A→ aA•, a / b I9 =转到(I6, A)=闭包(A→aA•, $)= A→aA•, $
绘图DFA:
CLR(1)解析表
产品编号如下:
S → AA ... (1)
A → aA ....(2)
A → b ... (3)
移位节点在CLR(1)解析表中的位置与SLR(1)解析表相同。化简节点的唯一区别是。
I4包含驱动的最后一项(A→b•, a / b), 因此动作{I4, a} = R3, 动作{I4, b} = R3。 I5包含驱动的最后一项(S→AA•, $), 因此操作{I5, $} = R1。 I7包含驱动的最后一项(A→b•, $), 因此动作{I7, $} = R3。 I8包含驱动的最后一项(A→aA•, a / b), 因此动作{I8, a} = R2, 动作{I8, b} = R2。 I9包含驱动的最后一项(A→aA•, $), 因此动作{I9, $} = R2。
评论前必须登录!
注册