第三章 程序设计语言的语法描述
1.语法树
第四章 自上而下的语法分析
语法分析:根据给定的语法定义,判断输入的句子是否符合语法规则,识别句子并确定句子类型;
自上而下语法分析步骤:
(1)消除歧义:无二义性
(2)文法改造:消除左递归;提取左因子
(3)文法判定:LL1文法,文法确定性
直接左递归:含有A->Aa形式产生式的文法;
若一个文法中有一个非终结符A使得对某个串a存在一个推倒A=>+Aa,那么这个文法就是左递归的;
经过两步或以上推导产生的左递归称为间接左递归;
消除左递归:
S->Sa|b
=>
S→bS’
S’→aS’|ε
e.g.
E->E+T|T
T->T*F|F
F->(E)|i|x|y
=>
E->TE’
E’->+TE’|ε
T->FT’
T’->*FT’|ε
F->(E)|i|x|y
直接左递归消除一般规则:
P→Pα1|Pα2|…|Pαm|β1|β2|…|βn
=>
P→β1P’|β2P’|…|βnP’
P’→α1P’|α2 P’|…|αm P’ |ε
e.g.
A → A c | A a d | b d | ε
=>
A->bdA’|A’
A’->cA’|adA’|ε
产生回溯的原因:
(1)多个候选式右部第一个符号相同
e.g.S->ab|ac S->Aa|Ab
解决:提取左因子
(2)多个右部其中一个可以退出ε
e.g.S->Ba B->a|ε
解决:要去描述语言符合LL1文法
提取左因子:
e.g. N-> DN|D
D->0|1|2|3|4|5|6|7|8|9
=>
N->D(N|ε)
=>
N->DN’
N’->N|ε
D->0|1|2|3|4|5|6|7|8|9
S-> aAd|aBe
A->c
B->b
=>
S->aS’
S’->Ad|Be
A->c
B->b
提取左因子一般规则:
P→δβ1|δβ2|…|δβn,δ∈(VT∪VN)+,βi∈(VT∪VN)*
=>
P→δP’
P’→β1|β2|…|βn
4.5.回溯的解决 -LL(1)文法
follow集:
e.g. E->TE’, 则follow(E’)应该添加Follow(E);
若E’可以为空串,则follow(T)应添加follow(E);
first集:
e.g.E->TE’,则first(E)应添加first(T)
若T可以为空串,则first(E)应添加first(E’)
select集
A->al
若空串不属于first(a), 则SELECT(A->a) = first(a)
若空串属于first(a), 则SELECT(A->a) = (first(a) - {空串})Vfollow(a)
文法G为LL1文法,当且仅当G的任意两个具有相同左部的产生式A->a|b满足下面条件:
不存在终结符a使得a和b都能够推导出以a开头的串
a和b至多有一个能推导出空串;
select(A->a)交select(A->b) = 空串;
设文法G:
A->aB|d
B->bBA|空串
=>
first(A)={a,d,#} follow(A) = {a,d,#};
first(B) = {b} follow(B) = {a,d,#}
select(A->aB)交select(A->d) = 空集
select(B->bBA)交select(B->空串) = 空集
递归下降分析法:
E->TE’
E’->+TE’|空串
T->FT’
T’->*FT’|空串
F->(E)|i|x|y
=>
(a+b)*c
(i+i)*c#
| step | 调用过程 | code | 输入串 |
|---|---|---|---|
| 0 | E | ( | a+b)*c |
| 1 | TE’ | ( | a+b)*c |
| 2 | FT’E’ | ( | a+b)*c |
| 3 | E)T’E’ | i | i+i)*i |
| 4 | TE’)T’E’ | i | i+i)*i |
| 5 | FT’E’)T’E’ | i | i+i)*i |
| 6 | T’E’)T’E’ | + | i)*i |
| 7 | E’)T’E’ | + | i)*i |
| 8 | TE’)T’E’ | i | )*i |
| 9 | FT’E’)T’E’ | i | )*i |
| 10 | T’E’)T’E’ | ) | *i |
| 11 | E’)T’E’ | ) | *i |
| 12 | T’E’ | * | i |
| 13 | FT’E’ | i | # |
| 14 | T’E’ | # | |
| 15 | E’ | # | |
| 16 | # |
分析表构造法:
(1)构造所有候选式的first集,构造所有非终结符的follow集
(2)对于文法的每个产生式A->a执行3和4
(3)对于a∈first(α) ,将A->a加到M[A][a]
(4)若ε∈first(α),则对于每个终结符b∈follow(A),把A→ε加至M[A][b]。
e.g.
E->TE’
E’->+TE’
E’->空串
T->FT’
T’->*FT’
T’->空串
F->(E)
F->i
F->x
F->y
=>
first(E)={(,i,x,y} follow(E)={),#}
first(E’)={+,空串,} follow(E’)={),#}
first(T)={(,i,x,y} follow(T)={+,),#}
first(T’)={空串,*} follow(T’)={+,),#}
first(F)={(,i,x,y,} follow(F)={*,+,),#}
构造预测分析表:
| + | * | ( | ) | i | x | y | # | |
|---|---|---|---|---|---|---|---|---|
| E | E->TE’ | E->TE’ | E->TE’ | E->TE’ | ||||
| E’ | E’->+TE’ | E’->空串 | E’->空串 | |||||
| T | T->FT’ | T->FT’ | T->FT’ | T->FT’ | ||||
| T’ | T’->空串 | T’->*FT’ | T’->空串 | T’->空串 | ||||
| F | F->(E) | F->i | F->x | F->y |
e.g.i+i#
| step | stack | X | code | 输入串 |
|---|---|---|---|---|
| 0 | #E | i | +i# | |
| 1 | E’T | i | +i# | |
| 2 | E’T’F | i | +i# | |
| 3 | E’T’i | i | +i# | |
| 4 | E’T’ | + | i# | |
| 5 | E’ | + | i# | |
| 6 | E’T+ | + | i# | |
| 7 | E’T | i | # | |
| 8 | E’T’F | i | # | |
| 9 | E’T’i | i | # | |
| 10 | E’T’ | # | # | |
| 11 | E’ | # | ||
| 12 | # |
1.预测分析法是由分析表和控制程序构成,控制程序与文明发无关,分析表随文法而异;
2.在预测分析表中,若某一单元持有一个或以上的产生式,则称该预测分析表含多重定义;
3.一个文法,若其预测分析表不存在多重定义,则称该文法为LL(1)文法,即 对于A->a|b, first(a)交first(b) = {};若b->空串,则first(a)交follow(A)={};
预测分析表二义性:
e.g.
S->fCtS|fCtSeS|a
C->i
=>
S->fCtSS’|a
S’->空串|eS
C->i
first(S) = {f,a} follow(S)={e,#}
first(S’)={空串,e} follow(S’)={e,#}
first©={i}
| f | t | a | e | i | # | |
|---|---|---|---|---|---|---|
| S | S->fCtSS’ | S->a | ||||
| S’ | S’->eS/S’->空串 | S’->空串 | ||||
| C | C->i |
输入:fitaea
| step | stack | code | 输入串 |
|---|---|---|---|
| 0 | #S | f | itaea |
| 1 | #S’StCf | f | itaea |
| 2 | #S’StC | i | taea |
| 3 | #S’Sti | i | taea |
| 4 | #S’St | t | aea |
| 5 | #S’S | a | ea |
| 6 | #S’a | a | ea |
| 7 | #S’ | e | a |
| 8 | 此处有歧义 |
第五章 自下而上的语法分析
从叶节点出发,步步向上规约。若能规约到根节点,说明输入串合法
移入:将输入符号移到栈的顶端
规约:
接受:Acc,语法分析成功
抛错:语法分析抛错
e.g.产生式
1.S→aAcBe
2.A→b
3.A→Ab
4.B→d
| step | 符号栈 | 剩余输入 | 动作 |
|---|---|---|---|
| 0 | $ | abbcde$ | |
| 1 | $a | bbcde$ | 移入 |
| 2 | $ab | bcde$ | 移入 |
| 3 | $aA | bcde$ | 规约 |
| 4. | $aAb | bcde$ | 移入 |
| 5 | $aA | bcde$ | 规约 |
| 6 | $aAb | cde$ | 移入 |
| 7 | $aA | cde$ | 规约 |
| 8 | $aAc | de$ | 移入 |
| 9 | $aAcd | e$ | 移入 |
| 10 | $aAcB | e$ | 规约 |
| 11 | $aAcBe | $ | 移入 |
| 12 | $S | $ | 规约 |
短语:子树端末结点的自左至右的排列,称为相对于子树根的短语;

短语:b bb d
直接短语:Ab Bd
句柄:Ab
直接短语(简单短语):两代子树端末结点的自左至右的排列,称为相对于两代子树根的直接短语;
句柄:最左面的两代子树的端末结点的自左自右的排列;
- 句型:语法树端末结点的自左自右的排列;(规约过程中产生的值)
- 句子:语法树端末结点的自左自右的排列,且端末结点均为终结符;
- 短语:子树端末结点自左自右的排列,称为相对于子树根的短语;
- 直接短语:两代子树端末结点的自左自右的排列;
- 句柄:最左面的两代子树的端末结点的自左至右的排列;(给我感觉像是产生式右侧的值)
规范规约(最左规约):
设a是文法G的一个句子,并且序列an,an-1,…a0满足下列三个条件,称该序列是a的一个规范规约。
(1)an = a
(2)a0 = S
(3)ai-1是将ai中的句柄替换成产生式的做不夫哈而得到的 (1<=i<=n)
前缀: 符号串的任意首部;e.g.a=abc 前缀有空串, a, ab, abc
活前缀:规范句型的一个前缀,不包括句柄后的任何符号。
a = aAbcde, 因为Ab是该句型的句柄,所以该句型的活前缀有空串,a, aA, aAb
LR分析法:LR分析法严格执行最左规约,每次按句柄规约。LR分析法把句柄的识别过程划分为若干状态,每个状态仅识别句柄的一个符号,若干个状态就可识别句柄的一部分左端符号。识别了句柄这一部分就相当于识别规范句型的左起部分,即活前缀。这样,对句柄的识别就变成了对活前缀的识别,可以构造一个DFA,用于识别给定文法所有贵方句型的活前缀;
增广文法:在G中加上新开始符号 S’ -> S 而得到的文法,引入该产生式的目的是使得文法开始福海仅出现在一个产生式左边,从而使得分析器仅有一个接受状态;
项目集I的闭包(CLOSURE(I)),就是把.后面的所有项目加上

e.g.

| state | a | b | # | S | B |
|---|---|---|---|---|---|
| 0 | S4 | S1 | – | 2 | 3 |
| 1 | r3 | r3 | r3 | – | – |
| 2 | – | – | Acc | – | – |
| 3 | S4 | S1 | – | – | 5 |
| 4 | S4 | S1 | – | – | 6 |
| 5 | r1 | r1 | r1 | – | – |
| 6 | r2 | r2 | r2 | – | – |
若一个项目集既含有移进项目,又含有一个或多个规约项目,则称该LR(0)项目集含有冲突项目,冲突项目使得分析表含有多重定义入口。
LR(0):若构造的分析鞭炮不含多重定义入口,则称该分析表是LR(0)分析表,相应文法为LR(0)文法;
SLR(1): 若t.code和b相等,则移进输入符号;
若t.code属于follow(A),则使用产生式 A->a进行规约;
若t.code属于follow(B),则使用产生式B->a进行规约;
SLR(1)是LR(0)的扩展,
(1)引入增广文法 S’->S
(2)对所有产生式进行编号
(3)构造文法其DFA
(4)计算follow集

| step | state | string | val | wval | current |
|---|---|---|---|---|---|
| 0 | # | - | - | <i,‘a’> | |
| 0 5 | #i | -a | – | <*,nil> | |
| 0 3 | #F | – | -&a | <*,nil> | |
| 0 2 | #T | – | -&a | <*,nil> | |
| 0 2 7 | #T* | — | &a– | <i,‘b’> | |
| 0 2 7 5 | #T*i | —b | -&a– | <+,nil> | |
| 0 2 7 10 | #T*F | ---- | -&a-&b | <+,nil> | |
| 0 2 | #T | – | -&T1 | <+,nil>(*,&a,&b,&T1) | |
| 0 1 | #E | – | -&T1 | <+,nil> | |
| 0 1 6 | #E+ | — | -&T1- | <i,‘c’> | |
| 0 1 6 5 | #E+i | —c | -&T1– | <#,nil> | |
| 0 1 6 3 | #E+F | ---- | -&T1-&c | <#,nil> | |
| 0 1 6 9 | #E+T | ---- | -&T1-&c | <#,nil> | |
| 0 1 | #E | – | -&T2 | <#,nil>(+,&T1,&c,&T2) | |
| Acc |
(1)LR分析表
(2)状态栈:设置状态栈,用于记录分析过程中所经历的状态,即路径
(3)符号栈:用于记录路径的符号,其和状态栈等高
(4)产生式右部符号串长度:因每个状态仅识别一个符号,退回的状态数和构成句柄的字符数相等,因此需要存储产生式右部符号串长度。
(5)产生式左部符号:规约后,根据左部符号进入下一状态
第六章
1.词法分析
词法分析器,依据语言的构词规则。从文件读入源程序,由字符拼接单词
e.g.
类别:值
3+abc*128
('x',"3")
('+',)
('i',"abc")
('*',)
('x',128)
=》
x+i*x
2.语法分析
根据语言的语法规则,将词法分析器所提供的单词种别分成各类语法范畴。
3.中间代码生成
中间代码的生成有时称为语义分析,执行中间代码产生的程序称为中间代码产生器=》按照语法分析器所识别出的语法范畴产生相应的中间代码,并建立符号表,常数表等各种表格
4.目标代码生成(后端)
依据中间代码和表格信息,确定各类数据在内存中的位置,选择合适的指令代码,将中间代码翻译成汇编语言或机器指令,这部分工作与硬件有关。
第二章 词法分析
从文件读入源程序,由字符拼接单词。每当识别出一个单词,就产生这个单词的内部码。
基本字(real),标识符(),常数,运算符,界符(;,)
经过词法分析后,单词使用二元式来表示,code表示单词的种别,表示单词的语法特性,val表示单词的值,表示单词的语义特性
e.g.
输入
begin
real r,h,s;
s = 2*3.14*r*(r+h)
end
('{',"null")
('c',"null")
('i',"r")
(',',"null")
('I',"h")
(',',"null")
('i',"s")
(';',"null")
('i',"s")
('=',"null")
('x',"2")
('*',null")
('y',"3.14")
('*',"null")
('i',"r")
('*',"null")
('(',"null")
('i',“r”)
('+',"null")
('i',"h")
(')',"null")
('}',"null")
第6章 语法制导翻译和中间代码生成
1.语法分析:利用产生式推导或规约,验证符号串是否为文法的一个句子
2.语义分析:规定每个符号和符号串的意义,同时完成符号串所规定的语义动作;
(1)建立符号表和常数表
(2)诊断和报告源程序中的语义错误
(3)根据语言的语义产生中间代码,或直接解释执行
- SLR分析器由工作栈(状态栈,符号栈),分析表和总控程序三部分组成

PS:
(1)在移进时,除移进状态和单词的种别外,还需移进单词的值;
(2)在用某个产生式进行规约时,除需执行规约动作外,还需调用相应语义子程序;
e.g.
解释执行
(1)文法及语义子程序
(2)SLR分析表
(3)手工计算

e.g.
7+9*5
1.分析二元式
<x,‘7’>
<+,nil>
<x,‘9’>
<*,nil>
<x,‘5’>
<#,nil>
| step | state | string | word_val | val | current |
|---|---|---|---|---|---|
| 0 | 0 | # | - | - | <x,‘7’> |
| 1 | 0 3 | #x | -7 | – | <+,nil> |
| 2 | 0 1 | #E | - - | - &7 | |
| 3 | 0 1 4 | #E+ | — | -&7- | <x,‘9’> |
| 4 | 0 1 4 3 | #E+x | —9 | -&7– | <*,nil> |
| 5 | 0 1 4 7 | #E+E | ---- | -&7-&9 | |
| 6 | 0 1 4 7 5 | #E+E* | ----- | -&7-&9- | <x,‘5’> |
| 7 | 0 1 4 7 5 3 | #E+E*x | -----5 | -&7-&9– | <#,nil> |
| 8 | 0 1 4 7 5 8 | #E+E*E | ------ | -&7-&9-&5 | <#,nil> |
| 9 | 0 1 4 7 | #E+E | ---- | -&7-&45 | <#,nil>,(*,&9,&5,&T1) |
| 10 | 0 1 | #E | – | -&52 | <#,nil>,(+,&7,&T1,&T2) |
| 11 | 0 1 | #E | Acc |
结束
e.g.

0.S’->S
1.S->i=X
2.X->X+Y
3.X->Y
4.Y->Y*Z
5.Y->Z
6.Z->(X)
7.Z->-Z
8.Z->i
9.Z->x
follow(S) ={#};
follow(X) = {+,#,)};
folow(Y) = {,+,#,),}
follow(Z) = {,+,#,)};//r8
| i | x | + | * | - | = | ( | ) | # | X | Y | Z | S | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | S2 | – | – | – | – | – | – | – | – | – | – | – | 1 |
| 1 | – | – | – | – | – | – | – | – | Acc | – | – | – | – |
| 2 | – | – | – | – | – | S8 | – | – | – | – | – | – | – |
| 3 | – | – | S9 | – | – | – | – | – | r1 | – | – | – | – |
| 4 | – | – | r3 | S10 | – | – | – | r3 | r3 | – | – | – | – |
| 5 | S12 | S7 | – | – | S6 | – | S5 | – | – | 11 | 4 | 18 | – |
| 6 | S12 | S7 | – | – | S6 | – | S5 | – | – | – | – | 17 | – |
| 7 | – | – | r9 | r9 | – | – | – | r9 | r9 | – | – | – | – |
| 8 | S12 | S7 | – | – | S6 | – | S5 | – | – | 13 | 4 | 18 | – |
| 9 | S12 | S7 | – | – | S6 | – | S5 | – | – | – | 14 | 18 | – |
| 10 | S12 | S7 | – | – | S6 | – | S5 | – | – | – | – | 15 | – |
| 11 | – | – | S9 | – | – | – | – | S16 | – | – | – | – | – |
| 12 | – | – | r8 | r8 | – | – | – | r8 | r8 | – | – | – | – |
| 13 | – | – | S9 | – | – | – | – | – | r1 | – | – | – | – |
| 14 | – | – | r2 | S10 | – | – | – | r2 | r2 | – | – | – | – |
| 15 | – | – | r4 | r4 | – | – | – | r4 | r4 | – | – | – | – |
| 16 | – | – | r6 | r6 | – | – | – | r6 | r6 | – | – | – | – |
| 17 | – | – | r7 | r7 | – | – | – | r7 | r7 | – | – | – | – |
| 18 | – | – | r5 | r5 | – | – | – | r5 | r5 | – | – | – | – |
//分析
a=-b*(c+2)
<i,‘a’>
<=,nil>
<-,nil>
<i,‘b’>
<*,nil>
<(,nil>
<i,‘c’>
<+,nil>
<x,2>
<),nil>
<#,nil>
| step | state | string | word_val | val | current |
|---|---|---|---|---|---|
| 0 | # | - | - | <i,‘a’> | |
| 0 2 | #i | -a | – | <=,nil> | |
| 0 2 8 | #i= | -a- | — | <-,nil> | |
| 0 2 8 6 | #i=- | -a– | ---- | <i,‘b’> | |
| 0 2 8 6 12 | #i=-i | -a–b | ----- | <*,nil> | |
| 0 2 8 6 17 | #i=-Z | -a— | ----&b | <*,nil> | |
| – | 0 2 8 18 | #i=Z | -a– | —&T1 | <*,nil>,(-,&b,nil,&T1) |
| – | 0 2 8 4 | #i=Y | -a– | —&T1 | <*,nil> |
| 0 2 8 4 10 | #i=Y* | -a— | —&T1- | <(,nil> | |
| 0 2 8 4 10 5 | #i=Y*( | -a---- | —&T1– | <i,‘c’> | |
| 0 2 8 4 10 5 12 | #i=Y*(i | -a----c | ----&T1— | <+,nil> | |
| 0 2 8 4 10 5 18 | #i=Y*(Z | -a----- | —&T1–&c | <+,nil> | |
| 0 2 8 4 10 5 4 | #i=Y*(Y | -a----- | —&T1–&c | <+,nil> | |
| 0 2 8 4 10 5 11 | #i=Y*(X | -a----- | —&T1–&c | <+,nil> | |
| 0 2 8 4 10 5 11 9 | #i=Y*(X+ | -a----- | —&T1–&c- | <x,2> | |
| 0 2 8 4 10 5 11 9 7 | #i=Y*(X+x | -a-----2 | —&T1–&c- | <),nil> | |
| 0 2 8 4 10 5 11 9 18 | #i=Y*(X+Z | -a------ | —&T1–&c-&2 | <),nil> | |
| 0 2 8 4 10 5 11 9 14 | #I=Y*(X+Y | -a------ | —&T1–&c-&2 | <),nil> | |
| 0 2 8 4 10 5 11 | #i=Y*(X | -a----- | —&T1–&T2 | <),nil>(+,&c,&2,&T2) | |
| 0 2 8 4 10 5 11 16 | #i=Y*(X) | -a------ | —&T1–&T2- | <#,nil> | |
| 0 2 8 4 10 15 | #i=Y*Z | -a---- | —&T1-&T2 | <#,nil> | |
| 0 2 8 4 | #i=Y | -a– | —&T3 | <#,nil>(*,&T1,&T2,&T3) | |
| 0 2 8 13 | #i=X | -a– | —&T3 | <#,nil> | |
| 0 1 | #S | – | -&T4 | <#,nil>(=,&T3,0,&i ) | |
| Acc |
6.7.布尔表达式的翻译
(1)控制语句的条件 if x+y<10 goto L
(2)计算逻辑值 d = x>y
if(a){
X+1
}else{
x-1
}
//other
(1)(jnz,&a,0,3)
(2)(jmp,0,0,5)
(3)(+,&x,&1,&T1)
(4)(jmp,0,0,other)
(5)(-,&x,&1,&T2)
(6)other
if aVbVc the x+1 else x-1
(1)(jnz,&a,0,7)
(2)(jmp,0,0,3)
(3)(jnz,&b,0,7)
(4)(jmp,0,0,_5)
(5)(jnz,&c,0,7)
(6)(jmp,0,0,9)
(7)(+,&x,&1,&T1)
(8)(jmp,0,0,10)
(9)(-,&x,&1,&T2)
(10)other
if a&b then x+1 else x-1
(1)(jnz,&a,0,3)
(2)(jmp,0,0,7)
(3)(jnz,&b,0,5)
(4)(jmp,0,0,7)
(5)(+,&x,&1,&T1)
(6)(jmp,0,0,8)
(7)(-,&x,&1,&T2)
(8)other
if a&b&c then x+1 else x-1 other
(1)(jnz,&a,0,3)
(2)(jmp,0,0,9)
(3)(jnz,&b,0,5)
(4)(jmp,0,0,9)
(5)(jnz,&c,0,7)
(6)(jmp,0,0,9)
(7)(+,&x,1,&T1)
(8)(jmp,0,0,10)
(9)(-,&x,1,&T2)
(10)other
if aVb<c then S1 else S2
(1)(jnz,&a,0,3)
(2)(jmp,0,0,7)
(3)(j<,&b,&c,5)
(4)(jmp,0,0,7)
(5)S1
(6)(jmp,0,0,8)
(7)S2
(8)other
if b<cVa then S1 else S2
(1)(j<,&b,&c,5)
(2)(jmp,0,0,3)
(3)(jnz,&a,0,5)
(4)(jmp,0,0,7)
(5)S1
(6)(jmp,0,0,8)
(7)S2
(8)other
布尔表达式由若干子表达式构成,转移目标地址只有2个,或为真出口,或为假出口。为方便记录及回填,利用四元式的第四项构成2条单向链。赋予E、EA和EO以及.tc和.fc,分别记录需回填真假出口单向链的链首;
(1)(jnz,&x,0,0) <- E.tc = 1
(2)(jmp,0,0,0) <- E.fc = i+1
... ...... ......
(p)(jnz,&x,0,i) <- E.tc = p
(p+1)(jmp,0,0,i+1) <- E.fc = p+1
在分析过程中,利用语义值传递和合并链的方法,最终完成两根真假出口链的构造。在if-then-else语句中,当翻译完布尔表达式,就可以找到真出口,利用E.tc进行回填.当翻译完语句S1,就可知道假出口,利用E.fc进行回填。
e.g.
aVbVc
<i,“a”>
<V,nil>
<i,“b”>
<V,nil>
<i,“c”>
p100
| step | status | symbol | .wval | .addr | 四元式1 | .tc | 四元式2 | .fc | nxq | 输入 |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | # | - | - | - | - | 1 | <i,“a”> | ||
| – | 08 | #i | -a | – | – | – | – | – | 1 | <V,nil> |
| – | – | – | – | – | – | – | – | – | – | – |
| – | – | – | – | – | – | – | – | – | – | – |
| – | – | – | – | – | – | – | – | – | – | – |
本文深入探讨了程序设计语言的语法描述,包括语法树、自上而下的语法分析、LL1文法、回溯解决、预测分析表构造、自下而上的语法分析。讲解了消除左递归、提取左因子、LL(1)文法、SLR分析等关键技术,并通过实例展示了分析过程。此外,还提到了词法分析、中间代码生成以及语义分析在编译过程中的作用。

459

被折叠的 条评论
为什么被折叠?



