编译原理笔记11 自上而下分析-递归下降分析法
编译原理 自上而下分析
本章在编译程序中的地位表词法分析器语法分析器源程序单词符号出2• 上下文无关文法的定义:G G=(V T V N S P)– V T ( )– V N ( ) V T ∩ V N =∅ – S S ∈V N– P ( )P →α P ∈V N α ∈ (V T ∪ V N )*– S复习• + *G= {i + * ( )} {E} E PPE → iE → E+EE → E*EE → (E)(i+i)E⇒(E)⇒(E+E)⇒(i+E)⇒(i+i)34},|{)(*TV S G L ∈⇒=+αααq 定义:假定G是一个文法,S 是它的开始符号。
如果Sα ,则α称是一个句型。
仅含终结符号的句型是一个句子。
文法G所产生的句子的全体是一个语言,将它记为 L(G)。
• α1 αn α1 αn+ ⇒α1 αn α1 0 αn* ⇒ 所以 : α1 αn 即 α1=αn , α1 αn* ⇒ + ⇒ * ⇒第4章 自上而下语法分析• 消除文法左递归,消除回溯,计算FIRST集、FOLLOW集,LL(1)分析条件, LL(1)文法的概念,预测分析表的构造。
• :自上而下分析方法的基本思想, 自上而下分析的过程。
• 4.14.24.3 LL(1)4.4重点难点4.5*4.6 LL(1)564.1 语法分析器的功能• 是在词法分析识别出单词符号串的基础上,分析判断程序的 是否符合语法规则。
• 是编译过程的核心部分。
• 有自上而下和自下而上两类。
两种方法反映了两种语法树的构造过程。
74.1 语法分析器的功能• " " 推导。
也就是从文法的开始符号开始,将它做为语法树的根,向下逐步建立语法树,使语法树的结果正好是输入符号串.• “归约”也就是从输入符号串开始,以它做为语法树的结果,自底向上地构造语法树.注:这里所说的输入符号串指词法分析所识别的单词。
84.2 自上而下分析面临的问题• – . – .• 例4.1文法:⑴ S→xAy⑵ A→** ⑶ A→*输入串 α=x*y,分析α是否该文法的句子?指示器IP指向 语法树 最左推导 说明x*y S S, x序号 ip 指向 语法树 最左推导 说明S x*yx A y A →** AS ⇒xAy ⇒x**y* *x*y* , ip S序号 ip 指向 语法树 最左推导 说明x*y Sx A yA →* AS ⇒xAy ⇒x*y * x*y * , ip Sx A y12自上而下分析• 从文法的开始符号出发,向下推导,试图推出句子,匹配输入符号串,寻找输入串的最左推导,并按与最左推导相对应的顺序,自上而下从左到右地建立输入串的语法分析树。
编译原理-递归下降分析法
编译原理-递归下降分析法题:对下列⽂法,⽤递归下降分析法对任意输⼊的符号串进⾏分析:(1)E->TG(2)G->+TG|—TG(3)G->ε,(4)T->FS(5)S->*FS|/FS(6)S->ε(7)F->(E)(8)F->i答:⽂法太多,可先合并。
(1)E->FSG(2)G->+TG|—TG|ε(3)S->*FS|/FS|ε(4)F->(E)|i结合1,4(1)E->ESG|iSG(2)G->+TG|—TG|ε(3)S->*FS|/FS|ε(4)F->(E)|i消除左递归(1)E->iSGE1(2)E1->SGE1|ε(3)G->+TG|—TG|ε(4)S->*FS|/FS|ε(5)F->(E)|i好吧,其实上⾯的化简有些地⽅并⽆必要,不过我的代码是按照最后的⽂法写的。
package compile;public class com {public static String str="i+i*i"; //待测试语句static int seri=0; //记录当前读到的序号public static void main(String[] args) {int t=E(); //⽂法if(t==1) {System.out.println(str+" compiled successfully");}else {System.out.println(str+" compiled failed");}}static char getchar() {if(seri<str.length()) {System.out.println(seri+" "+str.charAt(seri));return str.charAt(seri++);}return ' ';};static int E() {char ch=getchar();if(ch!='i') {return 0;}return S()*G()*E1();}static int S() {char ch=getchar();if(ch=='+'|ch=='-') {seri--;return 1;}else if(ch=='*'|ch=='/') {return F()*S();}else if(ch=='i') {return 0;}return 1;}static int F() {char ch=getchar();if(ch=='i') return 1;return E();}static int G() {char ch=getchar();if(ch=='*'|ch=='/') {seri--;return 1;}else if(ch=='+'|ch=='-') {return F()*S()*G();}else if(ch=='i') {return 0;}return 1;}static int E1() {char ch=getchar();if(ch=='i') return 0;if(ch==' ') return 1;return S()*G()*E1(); }}。
编译原理递归下降分析法C语言
编译原理递归下降分析法C语言编译原理是计算机科学中的一个重要领域,主要研究如何将高级语言程序转化为机器可执行的目标代码。
在编译原理中,递归下降分析法是一种常用的语法分析方法,它通过递归地从上至下对程序进行分析,最终确定程序的语法结构。
递归下降分析法是一种自顶向下的语法分析方法,基于产生式和预测分析表来实现对程序的语法分析。
该方法的基本思想是,每个非终结符对应一个处理过程,通过递归调用这些处理过程来分析整个程序。
在C语言的递归下降分析法中,需要定义对应C语言语法结构的处理过程,这些处理过程通常对应于C语言中的各种语句、表达式、声明等。
递归下降分析法的实现主要包括两个步骤:构造预测分析表和编写递归下降分析程序。
预测分析表是一个二维表格,行对应于非终结符,列对应于终结符,表格中的每个元素记录了该产生式的编号。
通过预测分析表,可以预测下一个分析符号,并选择相应的产生式进行语法分析。
编写递归下降分析程序时,首先需要确定递归下降分析程序的数据结构和接口。
一般来说,分析程序的数据结构包括符号栈、语法树等,接口包括初始化、语法分析、错误处理等。
接下来,根据语法规则编写对应的递归下降分析函数,每个函数对应一个非终结符的处理过程。
在实际编写过程中,通常使用递归调用来实现对程序的逐步分析,直到达到终结符。
递归下降分析法在C语言编译器中的应用非常广泛。
通过该方法,可以对C语言程序进行语法分析,检测代码中的语法错误,并生成相应的语法树。
在生成语法树之后,可以继续进行语义分析、中间代码生成、代码优化等编译过程。
总的来说,递归下降分析法是一种重要的语法分析方法,可以用于对C语言程序进行语法分析。
它通过自顶向下的递归调用,从上至下地解析语法规则,最终确定程序的语法结构。
递归下降分析法在实际编译器设计中有广泛应用,是理解和学习编译原理的重要内容。
编译原理语法分析——自下而上分析
E
1)LR分析法 2)算符优先分析法
E+ T
T
F
T * F i3
F
i2
i1
归约的含义: G(E): E i| E+E | E-E | E*E |
例:设文法G(S): (1) S aAcBe (2) A b (3) A Ab (4) B d
试对abbcde进行“移进-归约”分析。
e
BBd
abbbbcccdddeee
bcc
Ab
Saa
步骤: 1 2 3 4 5 6 7 8 9 10 动作: 进a 进b 归(2) 进b 归(3) 进c 进d 归(4) 进e 归(1)
规范归约是关于是一个最右推导的逆过程
最左归约
规范推导
由规范推导推出的句型称为规范句型。
把上例倒过来写,则得到:
S aAcBe aAcde aAbcde
abbcde
显然这是一个最右推导。
规范归约是关于是一个最右推导的逆过程
最左归约
规范推导
由规范推导推出的句型称为规范句型。
S
句柄“最左”特征的含 义
aAcde (4) B d
aAcBe (1) S aAcBe
S
S
a A c Be
A
bd
b S
S
a A c Be
Ab
d
S
a A c Bea A c Be d
定义:假定是文法G的一个句子,我们称序列 n, n-1, ,0
是的一个规范归约,如果此序列满足:
编译原理完整课件_第4章 语法分析-自上而下分析
2022/3/20
中南大学软件学院 陈志刚
6
第四章 语法分析-自上而下分析
4.2 自上而下分析面临的问题
➢ 顾名思义,自上而下就是从文法的开始符号出 发,向下推导,推出句子。 • 带回溯的分析方法 • 不带回溯的递归子程序(递归下降)分析方 法
➢ 自上而下分析的主旨: 对任意输入串,试图用一切可能的办法,从文 法开始符号(根结)出发,自上而下地为输入 串建立一棵语法树。或者说,为输入串寻找一 个最左推导。
设 ,有P→Pα|β,若α≠>ε,β不以P开头 (否则不可能消除左递归)。
则改写为:
可消除左递归。
2022/3/20
中南大学软件学院 陈志刚
12
第四章 语法分析-自上而下分析
一般地,若 αi≠ε,βj不以P开头, 则可改写为:
从而消除直接左递归。 ■ 例:S→Sabc|Sab|ab ■ 消除直接左递归得:
2022/3/20
中南大学软件学院 陈志刚
13
2、完全消除左递归 分析
第四章 语法分析-自上而下分析
虽不含直接左递归,但
所以含有左递归。
■ 如果文法G不含回路( ),也不含ε产生式,
则下列算法可消除左递归(完全)
①把G的非终结符按任意顺序排列成P1,…,Pn
②for i:=1 to n do
begin for j:=1 to i-1 do
➢ 关键:对一个文法,当给你一串(终结)符号 时,怎样知道它是不是该文法的一个句子呢? 这就要判断,看是否能从文法的开始符号出发 推导出这个字符串。或者,从概念上讲,就是 要建立一棵与输入串相匹配的语法分析树。
2022/3/20
中南大学软件学院 陈志刚
编译原理-递归下降分析法
实验二递归下降分析法一实验目的递归下降分析法。
二实验要求(一)准备:1.阅读课本有关章节;2.考虑好设计方案;3.设计出模块结构、测试数据,初步编制好程序。
(二)上课上机:将源代码拷贝到机上调试,发现错误,再修改完善。
第二次上机调试通过。
(三)程序要求:程序输入/输出示例:对下列文法,用递归下降分析法对任意输入的符号串进行分析:(1)E->TG(2)G->+TG|—TG(3)G->ε(4)T->FS(5)S->*FS|/FS(7)F->(E)(8)F->i输出的格式如下:(1)递归下降分析程序,编制人:姓名,学号,班级(2)输入一以#结束的符号串(包括+—*/()i#):在此位置输入符号串例如:i+i*i#(3)输出结果:i+i*i# 为合法符号串备注:输入一符号串如i+i*#,要求输出为“非法的符号串”。
注意:(6)S->ε1.表达式中允许使用运算符(+-*/)、分割符(括号)、字符I,结束符#;2.如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);3.对学有余力的同学,可以详细的输出推导的过程,即详细列出每一步使用的产生式。
三实验内容1.程序思路(1)定义部分:定义常量、变量、数据结构。
(2)初始化:从文件将输入符号串输入到字符缓冲区中。
(3)利用递归下降分析法分析,对每个非终结符编写函数,在主函数中调用文法开始符号的函数。
(4)实验思路:利用程序设计语言的知识和大量编程技巧,递归下降分析法是一种较实用的分析法,通过练习,掌握函数间相互调用的方法。
四实验结果(1)当输入“i-i”,不但输出推导过程,还会把栈内的状态显示出来;(2)当输入“iii”,则直接输出“不符合该文法”;五实验总结通过这次试验,让我更加熟悉掌握了自上而下语法分析法的特点。
掌握了递归下降语法分析的基本原理和方法。
运用递归下降分析法完成了本试验的语法分析构造,并且成功的分析出每种正确的句子和错误的句子。
编译原理---递归下降分析法
编译原理---递归下降分析法所谓递归下降法 (recursive descent method),是指对⽂法的每⼀⾮终结符号,都根据相应产⽣式各候选式的结构,为其编写⼀个⼦程序 (或函数),⽤来识别该⾮终结符号所表⽰的语法范畴。
例如,对于产⽣式E′→+TE′,可写出相应的⼦程序如下:exprprime( ){if (match (PLUS)){advance( );term( );exprprime( );}}其中:函数match()的功能是,以其实参与当前正扫视的符号 (单词)进⾏匹配,若成功则回送true,否则回送false;函数advance()是⼀个读单词⼦程序,其功能是从输⼊单词串中读取下⼀个单词,并将它赋给变量Lookahead;term则是与⾮终结符号T相对应的⼦程序。
诸如上述这类⼦程序的全体,便组成了所需的⾃顶向下的语法分析程序。
应当指出,由于⼀个语⾔的各个语法范畴 (⾮终结符号)常常是按某种递归⽅式来定义的,此种特点也就决定了这组⼦程序必然以相互递归的⽅式进⾏调⽤,因此,在实现递归下降分析法时,应使⽤⽀持递归调⽤的语⾔来编写程序。
所以,通常也将上述⽅法称为递归⼦程序法。
例4 2对于如下的⽂法G[statements]:statements→expression; statements |εexpression→term expression′expression′→+term expression′ |εterm→factor term′term′→*factor term′ |εfactor→numorid | (expression)通过对其中各⾮终结符号求出相应的FIRST集和FOLLOW集 (计算FIRST集和FOLLOW集的⽅法后⾯再做介绍),可以验证,此⽂法为⼀LL(1)⽂法,故可写出递归下降语法分析程序如程序41所⽰(其中,在⽂件lex.h⾥,将分号、加号、乘号、左括号、右括号、输⼊结束符及运算对象分别命名为SEMI,PLUS,TIMES,LP,RP,EOI及NUMORID,并指定了它们的内部码;此外,还对外部变量yytext,yyleng及yylineno进⾏了说明)。
编译原理-自上而下的语法分析
高效性
由于从文法的最顶端开始分析, 一旦发现不匹配,就可以立即终 止当前分支的搜索,避免不必要 的计算,提高了编译器的效率。
易于处理左递归文
法
自上而下的分析方法可以很方便 地处理含有左递归的文法,而左 递归是许多实际编程语言的重要 特征。
局限性
无法处理左边界问题
自上而下的分析方法在处理某些含有左边界的文法时可能 会遇到问题,因为这种方法会优先匹配最左边的符号,而 左边界问题需要从右往左匹配符号。
案例三
在编译器优化中,自上而下的语法分析被用 于识别和修改源代码中的冗余和低效的语法 成分。例如,在C编译器的实现中,自上而 下的语法分析可以用于优化循环结构,减少 不必要的循环次数,提高程序的执行效率。
自上而下的语法分析还可以用于代码生成和 代码生成器的实现。通过识别和解析源代码 中的语法成分,可以生成更高效、更安全的 机器代码或字节码,提高程序的执行效率和
安全性。
THANKS
感谢观看
详细描述:递归下降分析算法易于理解,每个产生式规 则对应一个函数,函数的实现相对简单明了。
详细描述:对于每个产生式规则,需要编写相应的递归 函数,可能会导致代码冗余。
移入-规约分析算法
总结词
基于栈的算法
详细描述
移入-规约分析算法是一种自上而下的语法分 析算法,它将目标语句从左到右依次读入, 并根据文法的产生式规则进行移入或规约操 作,直到找到目标语句的语法结构。
词法分析
词法分析是编译过程的第一步,也称为扫描或词法扫描。它的任务是从左 到右读取源代码,将其分解成一个个的记号或符号。
词法分析器通常使用正则表达式或有限自动机来识别和生成记号,这些记 号可以是关键字、标识符、运算符、标点符号等。
编译原理语法分析_自上而下__分析过程-FirstFollowSelect
G1: S → pA |qB A → a | cA B → b | dB 输入串 pca G2: S → Ap | Bq A → a | cA B → b | dB 输入串 cap
FIRST 集
FIRST集 / 开始符号集 / 终结首符集
* a…, a∈VT} FIRST(α) = {a|α * ε, 则规定 ε∈FIRST(α) 若α
G: S→ AB A→aA |ε B→bA |ε
自上而下语法分析面临的问题
G: S → cAd A → a|ab 输入串 cabd
- 回溯 Backtrack S
c A d
S
c A d a b
a A→ α1 |α2 |…|αn 如何决定用哪个候选式替换A? 不确定分析: 带回溯 (试探) 确定分析 : 不带回溯
练习: 求 First 集
G: S → ABC A → aA |ε B → bB |b C → cC |c First(S) = { a, b }
First(A) = { a, ε }
First(B) = { b}
First(C) = { c}
例: 自上而下语法分析
G5: E → TE' E'→ +TE'|ε T → FT' T'→ *FT'|ε F → (E) | i 输入串 i+i
Select 集
SELECT集 选择集合
给定上下文无关文法的产生式A→α, * ε, • 若α SELECT(A→α) = FIRST(α) * ε, • 若α SELECT(A→α) = (FIRST(α)-{ε})∪FOLLOW(A)
编译原理第四章语法分析-自上而下分析
• 例 4.4
4.4 递归下降分析程序构造
• 递归下降分析器:
这个分析程序由一组递归过程组成的,每个过程对应 文法的一个非终结符。 E→TE’ E’→+TE’| T→FT’ T’→*FT’| F→(E)|i
PROCEDURE E BEGIN T ; E’ END PROCEDURE E’ IF SYM=‘+’THEN BEGIN ADVANCE ; T ; E’ END
4.2 自上而下分析面临的问题
• 例4.1 假定有文法
(1) SxAy (2)A**|*
对输入串x*y,构造语法树。 • 构造过程:
(1)把S作为根 (2)用S的产生式构造子树 (3)让输入串指示器IP指向输入串的第一个符号。
S x A y x
S
A y x
S
A y
*
*
*
(4)调整输入串指示器IP与叶结点进行匹配。 (5)如果为非终结符,用A的下一个产生式构建子树。 (6)如果匹配成功则结束;否则,回溯到步骤(4)。
• 一个反例:
– 文法:SQc|c;QRb|b;RSa|a虽然不是直接 左递归,但S、Q、R都是左递归。
• 消除左递归算法:
– 算法的思想是:
• • • • 首先构造直接左递归; 再利用一般转换规则,消除直接左递归 化简文法。 下面算法在不含PP,也不含在右部产生式时可以消除 左递归。
• 消除一个文法的左递归算法:
(1) 把文法 G 的所有非终结符按任一种顺利排列成 P1…Pn;按此顺序执行; (2) FOR i:=1 TO n DO
BEGIN FOR j:=1 TO i-1 DO 把形如Pj+1→Pj 的规则改写成 Pj+11|1|…k| 。其中 Pj1|1|…k 是关于 Pj 的 所有规则; 消除关于Pi规则的直接左递归性。 END 化简由(2)所得的文法。即去除那些从开始符号出发永 远无法到达的非终结符的产生规则。
编译原理(3)语法_3(自顶向下语法分析:递归下降)33页PPT
G[S]: S → Q c | c
Q → R b | b
R → S a | a
(3.3)
中的S、Q、R都具有间接左递归
S Qc Rbc Sabc
3.3 自顶向下的语法分析
3、消除间接左递归 如何消除一个文法的一切左递归呢?如果一个文法不含回路(
形如A=+>A的推导),且产生式的右部也不含ε的候选式,那么
(3.1)
G[E]:E → TE' E' → +TE' | ε T → FT' T' → *FT' | ε F → (E) | i
(3.2)
可以通过文法(3.2)构造递归下 降分析器:
(1)文法(3.2)无左递归 (2) E ' 、 T ' 、F的候选式首字 符无交集
3.3 自顶向下的语法分析
4、递归下降分析器
3.3 自顶向下的语法分析 4、递归下降分析器
– 子程序的调用关系:
主程序
子程序
1.简单子程序
主程序
子程序1
2.嵌套子程序
子程序2
主程序
子程序
3.直接递归子程序
主程序
子程序1
子程序2
4.间接递归子程序
递归下降分析器的设计示例
G[E]:E → E+T | T T → T*F | F
F → (E) | i
A … Aα Aαα Aααα βααα
3.3 自顶向下的语法分析
再看下面不含A的直接左递归的产生式: A → βA' A' → α A' | ε
这两个产生式所能推导的句子如下:
A βA' β A βA' βαA' βα A βA' βαA' βααA' βαα A βA' βαA' βααA' βαααA' βααα
编译原理语法分析—自上而下分析
对文法G的任何符号串=X1X2…Xn构造集 合FIRST()。
1. 置FIRST()=FIRST(X1)\{};
2. 若对任何1ji-1,FIRST(Xj), 则把FIRST(Xi)\{}加至FIRST()中; 特别是,若所有的FIRST(Xj)均含有, 1jn,则把也加至FIRST()中。显 然,若=则FIRST()={}。
T→T*F | F
F→(E) | i
经消去直接左递归后变成:
E→TE E→+TE | T→FT T→*FT | F→(E) | i
(4.2)
例如文法G(S): S→Qc|c Q→Rb|b R→Sa|a
虽没有直接左递归,但S、Q、R都是左递归的
SQcRbcSabc
(4.3)
一个文法消除左递归的条件: 不含以为右部的产生式 不含回路。
即A的任何两个不同候选 i和 j FIRST(i)∩FIRST( j)=
当要求A匹配输入串时,A就能根据它所面临的第
一个输入符号a,准确地指派某一个候选前去执
行任务。这个候选就是那个终结首符集含a的。
提取公共左因子:
假定关于A的规则是 A→ 1 | 2 | …| n | 1 | 2 | … | m (其中,每个 不以开头)
*
特别是,若S A ,则规定
#FOLLOW(A)
构造不带回溯的自上而下分析的文法条件
1. 文法不含左递归,
2. 对于文法中每一个非终结符A的各个产生式 的候选首符集两两不相交。即,若
A→ 1| 2|…| n 则 FIRST( i)∩FIRST( j)= (ij)
3. 对文法中的每个非终结符A,若它存在某个 候选首符集包含,则
1)算符优先分析法:按照算符的优先关系和结 合性质进行语法分析。适合分析表达式。
《编译原理》第四章-自上而下分析
自上而下分析中出现的问题
回溯 当最终报告分析不成功时,我们难于知 道出错的确切位置. 带回溯的自上而下的分析效率较低,代 价极高.
4.3
LL(1)分析法
直接左递归的消除 直接消除: 假定非终结符P的规则为 P→P︱ 其中,不以P开头 那么我们可以把P的规则改写为如下的非直接 左递归形式: P→P’ P→P’︱ (为空字) 两种形式是等价的,也就是说,从P推出的符号 串是相同的.
语法分析的方法
Ways of Parsing
分析的目的就是为了得到从开始符S到一 个输入串u的推导: S 1 1 … n (=u) 所以,以下有两种推导方法: 由顶向下 (Top Down) : 从文法的开始 符号出发,向下推导,推出句子. 由底向上 (Bottom Up) : 从输入串开始, 逐步进行‚归约‛,直至归约到文法的开 始符号.
直接左递归,和非直接左递归的消除方法均在必须掌握 之列。这里我们切不可被形式描述消除左递归的算法吓 倒,多做几个例题后再来理解是很有好处的:
[例4。3]: 考虑文法:SQc|c Q Rb|b R Sa|a 消除左递归。 解:将终结符排序为R、Q、S。对于R不存在直接左递归。 把R带入到Q中有关的候选式: Q Sab|ab|b 现在Q同样不含直接左递归,把它带入S的有关候选式: S Sabc|abc|bc|c 经消除S的直接左递归后我们们得到整个文法 S abcS’|bcS’|cS’ S’ abcS’| Q Sab|ab|b R Sa|a 由于关于Q,R的规则式多余的则可化简
一个文法G的预测分析表M不含 多重定义入口,当且仅当该文法 是LL(1)的。 如果G是左递归和二义的,那么, M至少含有一个多重定义入口
编译原理之自顶向下语法分析方法(25页)
间接左递归 若 PP α S→Aa A→Sb A→b
2021/8/25
5
消除左递归
消除直接左递归 形如:P → P α| β α非, β不以P打头
改写为:P → βP’ P’ → αP’|
2021/8/25
6
消除左递归
例:E → E+T|T T →T*F|F F →(E)| i
G[ E]: (1) E → TE’ (2) E’ → +TE’| (3) T → FT’ (4) T’ → *FT’ | (5) F → (E)|i
A →Bb|b
2021/8/25
10
回溯问题
例:S →iEtS|iEtSeS|a
E→b
判断句子ibtaea
提取左公因子:A →αβ1|αβ2
变为:
A →αA’
A’ →β1 |β2
若A →αβ1|αβ2 |…|αβn|r
变为:
A →αA’|r
A’ →β1 |β2|…|βn
2021/8/25
11
例:S →iEtS|iEtSeS|a
2021/8/25
Procedure E’; IF sym=‘+’ then Begin advance; T;E’ End;
Procedure T’; IF sym=‘*’ then Begin advance; F;T’ End;
14
3非递归的预测分析方法(LL(1))
一、总控程序 Input
24
非LL(1)文法的改造
消除左递归 提左公因子
2021/8/25
25
22
三、LL(1)文法:
一个文法G,若它的分析表M不含多重定义入 口,则称为LL(1)文法。
《编译原理》第4章自上而下语法分析
• 需要反复试探。
•问题1:回溯(P67)
x
S A y
• 例1:设有文法 (1) S xAy (2) A **|* 现有输入串:x*y 其分析过程如右:
•消除回溯
• 方法是:反复 “提取公共左因子”,使得文法 的每个非终结符号的各个候选式的首终结符集 两两不相交,来避免回溯。 设产生式为: A→δ α1|δ α2|…|δ αn
替换为:
Aδ A' A' α1|α2|…|αn
• 例3:有如下两个产生式:
<IF语句> if E then S1 else S2; <IF语句> if E then S1;
First(A1) = {a} First(A2) = {c} First(B1) = {b} First(B2) = {d}
• 在右边给定的文法中,A 的候选式有两个,其首终 结符集为: First(A1) = {*} First(A2) = {*} 相交,就会产生回溯
(1) S xAy
(2) A **|*
结论:能够从开始符号出发推导出给定的输入串,
因此,是句子。
• 常用的语法分析方法:
根据建立语法分析树的方法来分,有两大类,分四小类:
自顶向下分析法: 从文法的开始符号出发,向下推导(使用最左推 导) ,尽可能使用各种产生式,推导出与输入串 匹配的句子,从而建立语法树。
自底向上分析法: 从输入符号串开始,逐步进行归约(最右推导的 逆过程),直至归约到文法的开始符号,从而建 立语法树。 具体分类:
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
递归下降分析技术
一、递归下降分析程序
若一个文法G不含有左递归,而且每个非终结符的所有候选式的首符集都是两两不相交的,那么就能为G中每个非终结符编写一个相应的递归过程。
把该文法中所有这样的递归过程组合起来就可能构成一个不带回溯的自上而下分析程序-递归下降分析程序。
二、递归下降分析法实现思路
三、递归下降分析法的实现
a) 使用LL(1)文法
先将文法消除左递归、提取公共左因子,使之成为LL(1)文法,后将每个非终结符
对应一个递归过程,过程体是按照相应产生式的右部符号串顺序编写。
每匹配一个
终结符,则再读入下一个符号,对产生式右部的每个非终结符,则调用响应的过程。
b)使用BNF范式
先将文法改写为BNF形式,后再书写递归子程序。
四、递归下降分析法的缺点
a) 对文法的要求高,必须满足LL(1)文法。
b) 高深度的递归调用会影响语法分析的效率,速度慢,占用空间多。