【编译原理】LR(0)分析举例

方便复习用

题目

文法: E → ( L ) ∣ a E\rightarrow (L) | a E(L)a L → E L ∣ E L\rightarrow EL | E LELE

分别求:DFA、parsing table、和串(a(a))的分析过程。

DFA

先拆分和扩张文法: 1. E ′ → E 1. E'\rightarrow E 1.EE 2. E → ( L ) 2. E\rightarrow (L) 2.E(L) 3. E → a 3. E\rightarrow a 3.Ea 4. L → E L 4. L\rightarrow EL 4.LEL 5. L → E 5. L\rightarrow E 5.LE

画DFA的要点:

  • 初始状态从 E ′ → E E'\rightarrow E EE开始扩张。
  • 扩张:当箭头后面第一个是非终结字符时(本题的 E 、 L E、L EL),将其对应的文法也写在本状态下面。
  • 用 · 标记状态,· 到达最后结尾表示可规约的状态。也就没有箭头再去指出了。

【编译原理】LR(0)分析举例_第1张图片

Parsing Table

直接根据DFA画出即可。

status output output output output goto goto
( ) a $ E L
0 s2 s3 1
1 acc 6 4
2 s2 s3 6 4
3 r3 r3 r3 r3 r3 r3
4 s5
5 r2 r2 r2 r2 r2 r2
6 s2 r5 s3 r5 6 7
7 r4 r4 r4 r4 r4 r4

(a(a)) 的分析过程

先给出分析过程再总结:

Stack intput_q action
$0 (a(a)) s2
$0(2 a(a)) s3
$0(2E6 (a)) r3
$0(2E6(2 a)) s3
$0(2E6(2a3 )) r3
$0(2E6(2E6 )) r5
$0(2E6(2L4 )) r5
$0(2E6(2L4)5 ) r2
$0(2E6E6 ) r5
$0(2E6L7 ) r4
$0(2L4 $ s5
$0(2L4)5 $ r2
$0E1 $ acc

规定stack的 $ 为栈底,input_q的最左边为队首。

流程:

  1. stack.top();作为行并input_q.peek()队首作为列,并查表得到相应的action: s i , r j , a c c , n u l l s_i, r_j, acc, null si,rj,acc,null,根据action的 情况分别转到流程2、3、4
  2. 当action= s i s_i si时,stack.push(input_q.poll());并返回流程1。
  3. 当action= r j r_j rj时,使用第 j j j个文法去规约(从栈顶向栈底扫描匹配并忽略其间的状态编号,匹配成功后弹出匹配到的相关串,弹出后栈顶元素应该为某个状态的编号)。将规约后得到的结果作为列,stack.top();得到的状态编号作为行查表得到下一个action= s i s_i si,并push得到的规约串后再stack.push(i);转到流程1。
  4. 当action= a c c acc acc时,分析结束。
  5. 当action= n u l l null null时,发生异常,分析结束 。

你可能感兴趣的:(总结)