编译原理第4章 语法分析 自上而下

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
ABb BAc Bd
是间接左递归
※ 消除左递归的方法:
(1) 消除直接左递归:
方法:改为右递归。保持其语言不变。
直接左递归的消除
候选式:
A->Aα|β β
βα
βαα βααα ……
A -> βA’ A’-> α A’ | ε
例4.2 文法: E —> E+T | T T —> T*F | F F —>(E)| i
对于这样的文法,其推导过程可以根据当前的输入 符号决定选择哪个产生式往下推导,因此,分析过 程是唯一确定的。
文法G: S —> cAd
A —> ab
A —> a
输入串w : c a d
S
IP
c A a d
分析过程:
4)报告失败,撤销A的子 3)IP—> ‘a’ 2)α=c 1)w——输入串; 树,回到A; A d; A扩展,第一式ab, 与 IP—> ‘c’ IP—> ‘c’ 指针回退到IP—> ‘a’; IP—> ‘a’与ab匹配; A还有替换式未试过,而又 匹配; S——扩充; IP—> ‘d’,但d与b不匹配; 可能匹配;

2、消除回溯、提左公因子
例如,有产生式: 语句->if 条件 then 语句 else 语句 | while 条件 do 语句 |begin 语句表 end 若要寻找一个语句,那么关键字 if,while,begin就 提示某个替换式是唯一的替换式。
回溯原因
若当前符号 = a,下一步要展开A , 而 A ->α1|α2|„|αm , 那么,要知道哪一个αi是获得以a开头的串的式。 怎样选择αi?
语法分析的任务 :
对任一给定 w ∈ VT*,判断 w ∈ L(G)? 语法分析器:按照产生式规则,做识别w的工作
源程序
单词符号
词法分析器
取下一个 单词符号
语法分析器
语法分析
编译程序后续部分
符号表
语法分析器在编译程序中的地位
语法分析算法分类
分析算法分类:
自上而下分析法(自顶向下):
从文法的开始符号出发,反复使用各种产生 式,寻找与输入符号匹配的最左推导。 自下而上分析法(自底向上): 从输入符号串开始,逐步进行归约(最右推 导的逆过程),直至归约到文法的开始符号。

其次,由于回溯,如果走了一大段错路,
最后必须回头,那么,就应把已经做 的一大堆语义工作(指中间代码产生 工作和各种表格的簿记工作)推倒重 来。回溯会引起时间和空间的大量消 耗应设法消除回溯。 最后,如果被识别的语句是错的,算 法无法指出错误的确切位置。
问题解决--消除左递归 1. 一个文法含有下列形式的产生式时,
4.1.2 递归下降分析程序构造
在不含左递归和每个非终结符的所有候选 式的终结首符集都两两不相交条件下,构造一
个不带回溯的自上而下分析程序,该分析程序
由一组递归过程组成,每个过程对应文法的一
个非终结符。
这样的一个分析程序称为递归下降分析器。
递归下降分析器
文法G消除左递归 得: E→TE' E'→+TE'| T→FT'
E
TE’
i
i+i*i
上述分析方法的实现:
①每一非终结符对应一个递归子程序; 在只生成有限个串的文法,过程是无须递归的,而 对生成无数个串的文法,递归是不可避免的;
②递归子程序:是一个过程,一旦发现它的某个 候选式与输入串匹配,它就按此式扩充(语法树), 指针移过已匹配子串。否则, 返回error,保持原来的 (语法树)和指针不变。
语法分析方法
递归子程序
自顶向下
预测分析(LL(1)分析器) 算符优先
自底向上
LR(0)、SLR(1),LR(1)、LALR(1)
自上而下语法分析的一般过程
从文法的开始符号出发,反复使用各种产生式,寻找 与输入符号匹配的最左推导。 如果能够推导出,则该输入串是给定文法的句子; 如果不能推导出,则该输入串不是给定文法的句子。

消除隐含的左递归算法与非终极符排序方法无关; 例如,文法G46按S、Q、R排序
所得文法对应正
规式相同。 …………..
=bc(abc)*(abc)|c(abc)*(abc)| (abc)*(abc)|bc|c =bc(abc)+|c(abc)+|(abc)(abc) *|bc (abc) 0 |c (abc) 0 =bc((abc)+| (abc) 0) |c((abc)+|(abc) 0) |(abc)(abc) * =bc(abc)*|c(abc)*|(abc) (abc) * =(abc|bc|c)(abc)*=V1
上下文无关文法的句型的推导
最左(最右)推导:在推导的任何一步
αβ,其中α、β是句型,都是对α中 的最左(右)非终结符进行替换 最右推导被称为规范推导。 由规范推导所得的句型称为规范句型
句型的分析
句型分析就是识别一个符号串是否为某文法
的句型,是某个推导的构造过程。 在语言的编译实现中,把完成句型分析的程 序称为分析程序或识别程序。分析算法又称 识别算法。 从左到右的分析算法,即总是从左到右地识 别输入符号串,首先识别符号串中的最左符 号,进而依次识别右边的一个符号。
a
b
语法树的形成过程
匹配结束,语法树形成
例:文法G为:S→xAy
| z,A→**|*
输入串=#x*y# 自上而下的分析过程:
(1)S有两个侯选式“xAy”和“z”,侯选式“xAy” 与输入串“x*y”相匹配,故推导:SxAy。 (2)非终极符A也有两个侯选式“**”和“*”, 若选第一个侯选式“**”对句型进行推导,则得: SxAyx**y,不相匹;推导回溯到句型“xAy”; 再用非终极符A的第二个侯选式“*”进行推导, 即:SxAyx*y。且都是终极符,输入串“x*y” 是所给文法的句子。
}/*替换为直接左递归*/
消除关于Ai规则的直接左递归; }; 化简所得到的文法(去掉无用产生式),结束。
例子G46:
S→Qc|c Q→Rb|b R→Sa|a 有推导:S ⇒ Qc ⇒ Rbc ⇒ Sabc, 存在左递归。 按R、Q、S排序,执行算法①得: i=1,j从1至0,R的产生式R→Sa|a无直接左递 归,无需消除直接左递归。 i=2,j从1至1,R的产生式代入Q的产生式得: Q→Sab|ab|b,无直接左递归。
消除方法:
若:A —> Aα|β , 修改为 : A —> βA′
A′—> αA′|ε
消去直接左递归后:E —> TE′ E′—> +TE′|ε
T —> FT′
T′—> *FT′|ε
F —>(E)| i
一般地,若文法的产生式为:
P→P1| P2|……|Pn|1|2|……|m 其中:j 不以P打头,i 非空 (1≤j≤m,1≤i≤n); 消除左递归后,为: P→1P'|2 P'|……|m P'
i=3,j从1至2, j=1,S的候选式不含R,所以无需替换; j=2,S的候选式含Q,将Q→Sab|ab|b代入S的候选式 得: S→Qc|c S→Sabc|abc|bc|c Q→Rb|b 再消除直接左递归得: R→Sa|a S→abcS'| bcS'| cS' S'→abcS'|ε 消除无用产生式:Q→Sab|ab|b,R→Sa|a, 得文法G47: S→abcS'| bcS'| cS' S'→abcS'|ε 文法G47对应的正规式:V1=(abc|bc|c)(abc)* 。
使用记号:
sym存放读单词子程序读来的单词,称为当前输入符 号,进入程序前,输入串的第一个符号应读入sym中;
•使用过程:
advance()将读单词子程序的单词指针下移一个单词 位置,且读出指针所指的单词,存入sym。

将过程调用示意图写成程序,程序称为递归下降分析器。
过程调用程序示意图
E'→+TE'| void E'(void) { if(sym=='+') { advance(); T(); E'(); } } F→(E)|i void F(void) { if(sym=='i') advance(); else if(sym=='(') { advance(); E(); if(sym=')') advance(); else error(); } else error(); }
相应的语法树: S S S

P A P A

P
S

A P
A
S→pA S→qB A→cAd A→a W=pccadd
c A d
c A d
c A d
c A d a
c A d
文法G(S):S→pA A→cAd
S→qB A→a
该来自百度文库法的特点:
(1)每个产生式的右部都由终结符号开始;
(2 )如果两个产生式有相同的左部,则它们的右 部由不同的终结符开始。
4.1 语法分析——自上而下分析
内容 语法分析的任务与分类
自上而下分析面临的问题
递归下降分析程序构造
LL(1)分析法
句型、句子、语言的定义
句型
有文法G,若S
* x,且x∈V*,则称x是文法G的
句型。
句子
有文法G,若S
的句子。
* x,且x∈VT*,则称x是文法G
例:G: S→0S1, S→01 S 0S1 00S11 000S111 00001111
L(G43)= L(G41)
G41过程调
用图
输入串为#aa#
文法G42=({P,B} , {a}, {P→B|a, B→Pa}, P)
过程调用图--输入串为#aa#
自上而下分析面临的问题
首先,是文法的左递归问题。 一个文法是含有左递归的,如果存在非终结 符P的产生式P ⇒Pα 含有左递归的文法将使上述的自上而下的分 析过程陷入无限循环。即,当试图用P去匹配 输入串时,我们会发现,在没有识别任何输 入符号的情况下,又得重新要求P去进行新的 匹配。因此,使用自上而下分析法必须消除 文法的左递归性。
T'→*FT'|
F→(E)|i
给出#i+i*i#的最左推导: 过程调用程序示意图 E=>TE'=>FT'E'=> iT'E'=>iE' => i+TE'=> i+FT'E'=> i+iT'E'=> i+i*FT'E'=>i+i*iT'E'=> i+i*iE'=> i+i*i
当前句型 应选候选式 当前输入符号 余下的符号
P'→1P'|2 P'|……|n P'|
(2)消除隐含的左递归
+ 要求文法中不含回路,即无AA的推导 ①给文法VN中的符号一个排序:A1, A2, …, An; for (i=1; i<=n; i++) { for (j=1; j<= i-1; j++) { 把形如Ai→Aj的规则改成 Ai→1|2|…|k 其中:Aj→1|2|…|k是关于Aj的所有规则;
过程调用示意图描述句型的推导过程
例4.1 文法G41=({P,U} , {a} , {P→aU, U→P|}, P),L(G41)={an|n≥1} 例4.2 文法G42=({P,B} , {a}, {P→B|a, B→Pa}, P), L(G42)= L(G41)
例4.3 文法G43=({P}, {a}, {P→aP|a}, P),
①以a为头的αi如果只有一个,则替换唯一;
②若以a为头有多个αi的,则替换不唯一,需要回 溯,这是文法的问题,应该变换文法。
解决办法--提取左公因子
要求文法的任一非终极符的侯选式之间无左 公因子,使相匹的侯选式是唯一的,提取左公 因子的方法是增加非终结符,改写文法。
提取左公因子
--例如: S→if B then S else S | if B then S 其中,S表示语句,if 、then、else为终极符。 提取左公因子,增加非终结符S3,产生式改成: S→if B then S S3 S3→else S | 经过反复提取左因子,就能够把每个非终结符 (包括新引进者)的所有候选首符号变成为两两 不相交。 为此付出的代价是,大量引进新的非终结符和 ε-产生式。
主旨:从文法开始符号出发,自上而下的为输 入串建立一棵语法树
自顶向下语法分析要解决的关键问题

假定要被代换的最左非终结符号是B,且有n 条规则:B→A1|A2|…|An,那么如何确定用 哪个右部去替代B?
例1:文法G(S):S→pA S→qB
A→cAd
A→a
输入串 W=pccadd
SpA pcAd pccAdd pccadd
a) AA AVN, V*
b) AB
B A A,BVN, , V*
称为左递归文法。
其中a)是直接递归,b)是间接递归。 如果一个 文法是
左递归时,则不能采用自顶向下分析法。
例:文法S Sa
S b 是直接左递归 所产生的语言是:L={ ban | n≥0}
例: 文法为:AaB
相关文档
最新文档