编译原理 自下而上分析题型

前言

自下而上分析法是“移进——归约”法
从输入串开始,逐步进行“归约”,直至归约到文法的开始符号

规范规约简述

  • 短语
    已知文法语法树,任一子树的叶子结点就是短语

  • 直接短语
    当子树不包含其他更小的子树时,该子树叶节点所组成的字符串就是该句型的直接短语

  • 句柄:
    一个句型的最左直接短语称为该句型的句柄

  • 素短语
    至少含有一个终结符,而且除他之外不含有其他素短语的短语

例:
G: E → E+T | E-T | T
T → T * F | T/F | F
F → (E) | i
给出句型E+T * F+i的短语、直接短语和句柄
先可以画语法树
短语: E+T * F+i, E+T*F, T * F,i
直接短语: T * F,i
句柄: T * F
素短语:i,T * F

算符优先文法及优先表的构造(<,>,=符号中间还有一点)

假定G是不含ε- 产生式的算符文法。对于任何一对终结符a、b,我们说:
(1)a=b 当且仅当文法G中含有形如P→ ···ab···或P→···aQb···的产生式;
(2)a<b 当且仅当G中含有形如P→···aR···的产生式,而R=>b···或R=>Qb···;
(3)a>b 当且仅当G中含有形如P→···Rb···的产生式,而R=>···a或R=>···aQ;

如果一个算符文法G中的任何终结符对(a,b)最多满足下述三个条件之一:
a=b,a<b,a>b
则称G是一个算符优先文法。

对于三种关系的计算,使用FIRSTVT 集及LASTVT集计算

FIRSTVT
对于一个非终结符A,它的FIRSTVT,A的产生式的候选式:
(1)以终结符开头a…或一个非终结符和终结符开头Ba…,将该终结符加入FIRSTVT(A)
(2)以非终结符开头B…,将该非终结符的FIRSTVT加入FIRSTVT(A)
LASTVT
对于一个非终结符A,它的LASTVT,A的产生式的候选式:
(1)以终结符结尾…a或一个非终结符结尾前面紧跟一个终结符 …aB,将该终结符加入LASTVT(A)
(2)以非终结符结尾…B,将该非终结符的LASTVT加入LASTVT(A)
构建算符优先关系表
对文法的每一个产生式判断<,>,=
① =关系:由产生式右部决定,形如…ab…或…aQb…,就有a=b
② <关系:求出每个符号的FIRSTVT,对于形如A→…aB…就有a<FIRSTVT(B)
③ >关系:求出每个符号的LASTVT,对于形如A→…Bb…就有LASTVT(B)>b
例:
G: S’→#S#
S→if Eb then E else E
E→E+T | T
T→T*F | F
F→ i
Eb→b
FIRSTVT
FIRSTVT(S’)={#}
FIRSTVT(S)={if}
FIRSTVT(E)={+, * ,i}
FIRSTVT(T)={ * ,i}
FIRSTVT(F)={i}
FIRSTVT(Eb)={b}
LASTVT
LASTVT(S’)={#}
LASTVT(S)={else, +, * ,i}
LASTVT(E)={+, * ,i}
LASTVT(T)={ * ,i}
LASTVT(F)={i}
LASTVT(Eb)={b}
在这里插入图片描述
构造优先表

在这里插入图片描述

优先函数

f(a)——栈内优先函数
g(a)——比较优先函数
用关系图法构造优先函数
①对任取a属于VT(包括’#’)用下标fa,ga为结点名画出2n个结点;
②任取a,b属于VT ,若a>b或a=b,则从fa画一箭弧到gb;若a=b或a<b,则从gb画一箭弧到fa;
③给每个结点赋一个数值,此数等于从该结点出发到所能到达结点(包括出发结点自身在内)的个数,赋给fa的数值作为f(a)的值,赋给gb的数值作为g(b)的值;
④检查所构造出的函数f和g,看它同原来的优先关系表是否矛盾,若没有矛盾,则f和g就是所要的优先函数;若有矛盾,则不存在优先函数。
在这里插入图片描述

LR分析法(LR(0)、SLR(1))

分析表

在这里插入图片描述
Action[S,a]规定了栈顶状态为S时遇到输入符号a应执行的动作:
(1)移进:把[S,a]的下一状态S’=Goto[S,a]和输入符号a推进栈,下一输入符号变成现行输入符号。
(2)规约:用产生式A→β进行归约。若|β|=r,归约动作为A,则去除栈顶的r个项,使状态Sm-r变成栈顶状态,然后把[Sm-r,A]的下一状态S’=Goto[Sm-r,A]和文法符号A推进栈。
(3)接受accetpt:宣布分析成功,停止分析器的工作。
(4)报错:发现源程序含有错误,调用出错处理程序。

LR(0)分析法

LR(0)项目集族与LR(0)分析表的构造
LR(0)项目:文法G的每条规则右部的任意位置加上一圆点构成的式子
A→·XYZ
A→XYZ A→X·YZ A→X1X2…Xi-1Xi · Xi+1…Xn
A→XY·Z 已在栈内符号 尚未进栈符号
A→XYZ·

识别文法活前缀的NFA:
例:已知文法G:
S’→E E→ aA|bB A→ cA|d B→ cB|d

1.S’→·E 2. S’→E· 3. E→·aA 4. E→a·A 5. E→aA·
6. A→·cA 7. A→c·A 8. A→cA· 9. A→·d 10. A→d·
11.E→·bB 12.E→b·B 13.E→bB· 14. B→·cB 15.B→c·B
2. B→cB· 17. B→·d 18. B→d·
NFA:
在这里插入图片描述
NFA确定化构造DFA
(1) S’→E (2) E→aA (3) E→bB (4) A→cA (5) A→d (6) B→ cB (7) B→d
在这里插入图片描述
LR(0)分析表的构造
设LR(0)项目集规范族为C={I0,I1,…In} S’→·S称为初态
(1)若项目A→α·xβ·Ik ,Go[Ik,x]=Ij
①若x属于VT,置Action[Ik,x]=Sj
②若x属于VN,置Goto[Ik,x]=j
(2)若项目S’→S·属于Ik ,则置Action[Ik,#]=acc
(3)若项目A→α·属于Ik ,则任取a 属于VT (包括#),置Action[Ik,a]=rj

例:(1) S’→E (2) E→aA (3) E→bB (4) A→cA (5) A→d (6) B→ cB (7) B→d
由DFA构造LR(0)分析表
在这里插入图片描述
完整解题过程
已知文法S’→E
E→ aA|bB
A→ cA|d
B→ cB|d
构造LR(0)分析表,对输入字符串bccd进行分析

(1) S’→E (2) E→aA (3) E→bB (4) A→cA (5) A→d (6) B→ cB (7) B→d
构造DFA:
在这里插入图片描述
构造LR(0)分析表:
在这里插入图片描述
对输入字符串bccd进行分析:
在这里插入图片描述

SLR分析

LR(0)产生移进—规约冲突
假定一个LR(0)规范族中包含项目集(状态)I:I={X→α·bβ, A→α·, B→α·},即在该项目集中包含移进-归约冲突和归约-归约冲突,解决冲突的办法为:
考察FOLLOW(A)和FOLLOW(B),若这两个集合不相交且均不包含b,那么当状态I时面临输入符a,可采用如下决策执行动作:
(1)若a=b,则移进;
(2)若a属于FOLLOW(A),则用A→α归约;
(3)若a属于FOLLOW(B),则用B→α归约。

SLR(1)分析表的构造方法
设C={I0,I1,…In},令S’→S的Ik的下标k为初态。
(a)若项目A→α·aβ属于Ik,且Go[Ik,a]=Ij,a为终结符,则置Action[k,a]为Sj;
(b)若项目A→α·属于Ik,则对任何终结符a(包括#) ,a属于FOLLOW(A),置Action[k,a]为rj ,j为产生式A→α在文法中的编号;
©若项目S’→S·属于Ik,则置Action[k,#]为acc;
(d)若Go[Ik,A]=Ij,则置Goto[k,A]=j;
(e)凡不能用上述规则填入信息的空白格,均置“出错信息”。

按上述方法构造的含有Action和Goto两部分的分析表,若每个入口不含多重定义(冲突),则该文法称为SLR(1)文法。

例:
文法(0) S’→S
(1) S→rD
(2) D→D,i
(3) D→i

通过上述LR(0)分析法画出分析表,通过follow集解决移进—规约冲突
FOLLOW(D)={, ,# }
FOLLOW(S)={ # }
DFA
在这里插入图片描述
SLR(1)分析表
在这里插入图片描述

发布了8 篇原创文章 · 获赞 0 · 访问量 167

猜你喜欢

转载自blog.csdn.net/key_768/article/details/103928036