ch5-自顶向下语法分析方法-v2

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

26
4. 计算SELECT集
27
28
5.3 非LL(1)文法到LL(1)文法的等价变换
在确定的自顶向下分析中,要求对给定语言的文法必须 是LL(1)文法,然而不一定每个语言都有LL(1)文法。 如何对一个语言的非LL(1)文法变换为等价的LL(1)形式? 由LL(1)文法的定义知道,当文法中含有直接或间接左递归, 或含有左公共因子时,这样的文法肯定不是LL(1)文法。 因此,首先设法消除文法中的左递归与提取左公共因子 对文法进行等价变换。在某些情况下,使其变换为LL(1)文法。
语法分析就是识别由词法分析给出的单词符号序列是 否是给定文法的正确句子(程序). 语法分析常用的方法:
自顶向下分析
自底向上分析 自底向上分析分为: 算符优先分析 LR分析
2
第五章 自顶向下语法分析
自顶向下分析(面向目标的分析方法) 从文法的开始符号出发企图推导出与输入的单词串完全相 匹配的句子. 自顶向下分析方法分为: 确定的分析方法-对文法有一定的限制。 不确定的分析方法-回溯的分析方法,一种穷举的试 探方法。
18
例题分析: 求文法中符号与符号串的FIRST集。
G[S]: S->AB | bC A->b |ε B->aD |ε C->AD | b
D->aS | c
FIRST(S)=FIRST(A)∪FIRST(B)∪{ε} ∪{b}={b,a, ε} FIRST(A)={b} ∪{ε}={b, ε} FIRST(B)={ε} ∪{a}={a, ε} FIRST(C)={FIRST(A)- {ε}}∪FIRST(D) ∪FIRST(b)={b,a, c} FIRST(D)={a} ∪{c}={a, c}
10
5.1 确定的自顶向下分析
LL(1)文法:一个上下文无关文法
G 是 LL(1)文法,当 且仅当对 G 中每个非终结符 A 的任何两个不同的规则 A→α|,满足:
SELECT(A→α) SELECT(A→)=
其中 α、 中至多只有一个能推导出 串。 1、第一个 L 表示从左到右扫描字符串; 2、第二个 L 表示最左推导;
G[S]: S->AB|bC A->b|ε B->aD| ε C->AD|b D->aS|c
14
3) 扫描产生式右部的每一符号
a)若所扫描到的非终结符号在数组中的对应标志是‚是‛, 则删去该非终结符,若这使得产生式右部为空,则对产生式左 部的非终结符在数组中对应的标志改为‚是‛,并删去该非 终结符为左部的所有产生式。 b)若所扫描到的非终结符号在数组中的对应标志是‚否‘, 则删去该产生式,若这使得产生式左部非终结符的有关产生 式都被删去,则将数组中该非终结符对应的标志改成‛否‚。
30
【例】文法G[S]:
S→aAb A→de|d
利用提取公共左因子的方法对其进行改写,得到: S→aAb A→dA’ A’→e|ε 这是一个 LL(1)文法
31
【例】文法G[S]: S→ad|Ae A→aS|bA
对于非终结符 S 的规则,因为有: SELECT(S→ad) SELECT(S→Ae) = {a}{a,b} 故它不是一个 LL(1)文法。 因为非终结符 S 的两个右部的公共左因子是隐式的,因此, 在提取公共左因子之前,对 S 右部以非终结符 A 开头的规则 (两条规则)进行相应替换,得到: S→ad|aSe|bAe 对 S 提取公共左因子得 S→aS’|bAe S’→d|Se A→aS|bA
22
3.计算FOLLOW集
为什么将FOLLOW(A)加入FOLLOW(B)呢?
因为当有
23
G[S]: S->AB|bC A->b|ε B->aD| ε C->AD|b D->aS|c
24
方法2:
25
G[S]: S->AB|bC A->b|ε B->aD| ε C->AD|b D->aS|c
FOLLOW
4) 重复3),直到扫描完一遍文法的产生式,数组中非终结符对 应的特征再没有改变为止。
G[S]: S->AB|bC A->b|ε B->aD| ε C->AD|b D->aS|c
15
2.计算FIRST集
第一种方法:根据定义计算
1)计算每一文法符号X的FIRST集-----FIRST(X)
(a)若XVT,则FIRST(X)={ X }; (b)若XVN且有产生式X->a….,a VT,则a FIRST(X); (c)若XVN且有产生式X-&g(续)
2)求每个符号串的FIRST集
* a)若符号串 V*, =X1…Xn,当X1不能=> , 则 FIRST()=FIRST(X1); b)若对任何j(1ji-1, 2in), FIRST(Xj), FIRST(Xi), 则FIRST()= (FIRST(Xj)-{}) FIRST(Xi) ; c)当所有FIRST(Xj)都含有时, 则 FIRST()= ( FIRST(Xj)) {}。
19
产生式右部符号串的FIRST集:
G[S]: S->AB|bC A->b|ε B->aD| ε C->AD|b D->aS|c FIRST(AB)={a,b, ε} FIRST(bC)={b} FIRST(ε)={ε} FIRST(b)={b} FIRST(aD)={a} FIRST(b)={b} FIRST(aS)={a} FIRST(c)={c} FIRST(AD)={a,b,c}
文法G3[S]为: S->aA S->d A->bAS A-> 给出W=abd的推导过程。 文法的特点: 1)文法中有空产生式。
6
5.1 确定的自顶向下分析
【 FIRST 集定义】
设G=(VN,VT,S,P)是上下文无关文法,又设 是文法 G 的
任一字符串,定义 的首符集 * FIRST()= {a | a…, a∈ VT } * 若 ε,ε∈ FIRST() FIRST()就是从 可推导出的所有首终结符或可能的ε构成 的集合。
第五章 自顶向下语法分析
用正规式可以描述单词符号的结构,并且用有限 自动机可以构造词法分析器。由于正规式与正规文法是 等价的,它们的描述能力有限,而高级语言的语法结构 适合用上下文无关文法描述,因此,将上下文无关文法 用作语法分析的基础。 本章主要介绍编译程序构造中的一些典型的语法分 析方法。
1
第五章 自顶向下语法分析
3、1 表示每一步只需向前看一个符号。
11
例题分析:
分析输入串W=ab的推导过程。 1)S=>aAS=>abAS=>abS 2)S=>aAS=>aS=>ab 判断该文法是否LL(1)文法?
12
5.2 LL(1)文法的判别
判断LL(1)文法的步骤: 1.求出能够推出的非终结符
1)初始化
设臵一个数组,并初始化为‚未定‛ 值。
20
第二种方法:
G[S]: S->AB|bC A->b|ε B->aD| ε C->AD|b D->aS|c
21
3.计算FOLLOW集
方法1:根据定义计算
对文法中每一A VN计算FOLLOW(A) a)设S为文法中开始符号,将‚#”加入FOLLOW(S) 中。 b)若A->B是一个产生式,则将FIRST()的非空元 * 素加入FOLLOW(B)中; 若=> ,则将FOLLOW(A)也加入FOLLOW(B)中。 c)重复使用(b)直到每个非终结符的FOLLOW集不 再增大为止。
S→aS’|bS”
S’→Aee|Bdd A→aAe|b
S”→e|d B→aBd|b
它还不是 LL(1)文法,但无论重复上述步骤多少次都无法改 写为 LL(1)文法。 33
可以看到:
1)不一定每个文法的左公共因子都能在有限的步骤内替 换成无左公共因子的文法。 2)一个文法提取了左公共因子后,只解决了相同左部产 生式右部的FIRST集不相交问题,当改写后的文法不含空 产生式且无左递归时,则改写后的文法是LL(1)文法, 若还有空产生式时,还需用LL(1)文法的判别方式进行 判断才能确定是否为LL(1)文法。
9
5.1 确定的自顶向下分析
【SELECT集定义】
假设 A 是文法 G 的任一规则,定义规则 A 的选
择集合 SELECT 为 :
* FIRST() 若 / SELECT(A)= (FIRST()-{})FOLLOW(A) * 若 =>ε 其中 A∈VN,∈(VNVT)*,
8
5.1 确定的自顶向下分析
当文法中含有形如: A-> A-> 的产生式时,其中AVN, , V*。 * * 若和不同时推导出空时, 假定 ‡>ε ε ,则当 FIRST( )(FIRST( )FOLLOW(A))= 时,对于非终结符A的替换仍可唯一确定候选。
29
1.提取左公共因子
提取左公共因子是指当文法中含有形如: A→α1|α2|...|αn|1|2|...|m 的规则, 可以把它修改成: A → α A’|1|2|...|m A’→1|2|...|n 经过反复提取左公共因子,就能够做到使每个非终结符的 所有候选首符集变成两两不相交。 该做法的代价是大量引进非终结符和ε-产生式。
4
5.1 确定的自顶向下分析
文法G2[S]为: S->Ap|Bq A->a|cA B->b|dB 给出输入串W=ccap的推导过程。 文法的特点: 1)产生式的右部不全是由终结符开始; 2)若两个产生式有相同的左部,则它们的右部是由不 同的终结符或非终结符开始; 3)文法中无空产生式。
5
5.1 确定的自顶向下分析
G[S]: S->AB|bC A->b|ε B->aD| ε C->AD|b D->aS|c
13
5.2 LL(1)文法的判别
2) 扫描文法的产生式
a)删除所有右部含有终结符的产生式,若以某一非终结符为 左部的所有产生式都被删除,则将数组中对应该非终结符的标 记修改为‚否‛。 b)若某一非终结符的某一产生式右部为,则将数组中对应该 非终结符的标志臵为‚是‛,并从文法中删除该非终结符的所 有产生式。
16
2.计算FIRST集
* (d)若X,Y1, …,YnVN ,且有产生式X-> Y1 …Yn.当 Y1, …,Yi-1=> (其中1in),则FIRST(Y1)-{}, …, FIRST(Yi-1)-{},FIRST(Yi) 都包含在FIRST(X)中; (e) 若 (d) 中 所 有 Yi* (i=1, …,n), 则 FIRST(X)=FIRST(Y1) => FIRST(Y2) … FIRST(Yn) {} 反复使用(b)-(e)步直至每个符号的FIRST集合不再增大为止。
3
5.1 确定的自顶向下分析
若有文法G1[S]: 确定的自顶向下分析方法是从文法的开始符号 出发,如何根据当前的输入符号唯一确定选用 S->pA|qB 哪个产生式替换相应非终结符往下推导,或构 A->cAd|a 造一颗相应的语法树。 B->dB|b 构造输入串W=pccadd的语法树。 文法的特点: 1)每个产生式的右部都 由终结符号开始; 2)若两个产生式有相同 的左部,则它们的右部由不同 的终结符开始。
7
5.1 确定的自顶向下分析
【 FOLLOW 集定义】
假设 S 是文法 G 的开始符号,对于 G 的任何非终结符 A,
定义非终结符 A 的后继符号的集合: FOLLOW(A)={a |S * ...Aa...,a∈VT} 。 * 若 S...A,则规定 #∈FOLLOW(A)。 FOLLOW(A)是 G 的所有句型中紧接在 A 之后出现的终结符或 #构成的集合。 其中 # 作为输入串的结束符。
A→aS|bA
32
【例】文法G[S]:
S→Ae|Bd A→aAe|b B→aBd|b
对于非终结符 S 的规则,因为有: SELECT(S→Ae) SELECT(S→Bd)={a,b} {a,b} 故它不是一个 LL(1)文法。 对 S 规则,用A,B的两条规则进行相应替换,得到: S→aAee|be|aBdd|bd 对 S 提取公共左因子得 A→aAe|b B→aBd|b
相关文档
最新文档