方便复习用
题目
文法: E → ( L ) ∣ a E\rightarrow (L) | a E→(L)∣a L → E L ∣ E L\rightarrow EL | E L→EL∣E
分别求:DFA、parsing table、和串(a(a))
的分析过程。
DFA
先拆分和扩张文法: 1. E ′ → E 1. E'\rightarrow E 1.E′→E 2. E → ( L ) 2. E\rightarrow (L) 2.E→(L) 3. E → a 3. E\rightarrow a 3.E→a 4. L → E L 4. L\rightarrow EL 4.L→EL 5. L → E 5. L\rightarrow E 5.L→E
画DFA的要点:
- 初始状态从 E ′ → E E'\rightarrow E E′→E开始扩张。
- 扩张:当箭头后面第一个是非终结字符时(本题的 E 、 L E、L E、L),将其对应的文法也写在本状态下面。
- 用 · 标记状态,· 到达最后结尾表示可规约的状态。也就没有箭头再去指出了。
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的最左边为队首。
流程:
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- 当action=
s
i
s_i
si时,
stack.push(input_q.poll());
并返回流程1。 - 当action=
r
j
r_j
rj时,使用第
j
j
j个文法去规约(从栈顶向栈底扫描匹配并忽略其间的状态编号,匹配成功后弹出匹配到的相关串,弹出后栈顶元素应该为某个状态的编号)。将规约后得到的结果作为列,
stack.top();
得到的状态编号作为行查表得到下一个action= s i s_i si,并push得到的规约串后再stack.push(i);
转到流程1。 - 当action= a c c acc acc时,分析结束。
- 当action= n u l l null null时,发生异常,分析结束 。