第四章(2) 自下而上语法分析

合集下载

第4章语法分析——自上而下分析

第4章语法分析——自上而下分析
<IF语句> if E then S1 else S2; <IF语句> if E then S1;
提取左因子后:
<IF语句> if E then S1 B; B else S2 |ε ;
第4章语法分析——自上而下分析
LL(1)分析条件:
是否满足:没有左递归,每个侯选式的首终结符集不相交这两个条 件,就一定能进行有效的自顶向下分析呢?
使A A。
如果是A A,则称为直接左递归,否则称为间接左递归。
例2:设有文法: (1) E->E+T|T
E E +T
(2) T->T*F|F
E +T
(3) F->(E)|i 现有输入串i*i+i, 其分析过程是:
E
+
T

产生的原因?
失败:由于使用最左推导,对左递归文法进 行自顶向下分析时,会导致死循环。
从推导的角度看,从开始符号出发,使用最左推导,试图 推导出与输入符号串相同的句子。
从语法树的角度看,从根节点出发,反复使用所有可能的 产生式,谋求输入串的匹配,试图向下构造一棵语法树, 其末端结点正好与输入符号串相同。
这是一个反复试探的过程。
第4章语法分析——自上而下分析
自顶向下分析面临的问题
第4章语法分析——自上而下分析
消除回溯的方法
反复使用“提取公共左因子”的方法来改造文法,使得文法 的每个非终结符号的各个候选式的首终结符两两不相交,来 避免回溯。
例:
设产生式为:
A→δα1|δα2|…|δαn 将其替换为:
AδA’
|…|α A’α1|α2
第4章语法分析——自上而下分析

第四章语法分析

第四章语法分析



最右推导
E rm E rm (E) rm (E + E) rm (E + id) rm (id + id)
4.1 上下文无关文法
4.1.3 分析树 例 E E + E | E E | (E ) | E | id
E

E
( E ) E + E id
id
4.1 上下文无关文法

4.2 语言和文法
4.2.7 提左因子

有左因子的文法 A b1 | b2 提左因子 A A A b 1 | b 2

4.2 语言和文法

例 悬空else的文法 stmt if expr then stmt else stmt | if expr then stmt | other 提左因子

无二义的文法
stmt matched _stmt | unmatched_stmt matched_stmt if expr then matched_stmt else matched_stmt | other unmatched_stmt if expr then stmt | if expr then matched_stmt else unmatched_stmt
句型 文法G的开始符为S,S *, 可能含有非终结符, 则叫做文法G的句型。
4.1 上下文无关文法

例 E E + E | E E | (E ) | E | id 最左推导
E lm E lm (E) lm (E + E) lm (id + E) lm (id + id)

按串长进行归纳:配对括号串可由S推出

编译原理语法分析——自下而上分析

编译原理语法分析——自下而上分析
基本思想:从输入串开始,逐步进行“归约”,直到文法的 开始符号。即从树末端开始,构造语法树。所谓归约,是指 根据文法的产生式规则,把产生式的右部替换成左部符号。
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
是的一个规范归约,如果此序列满足:

第四章 语法分析——自上而下分析

第四章 语法分析——自上而下分析

FOLLOW(Y) =FOLLOE(X)=end
则有LL(1)表:
begin
d
:
end s #
P begind : X end
X
d:X
sY
Y
:sY
第四章 语法分析--自上而下分析
[例3]:给出语言L={1na0n1ma0m|n>0, m>=0} 的LL(1)文 法G[S]并说明其理由。 解:观察句子,发现可分成两部分 1na0n 和 1ma0m两部 分中符号的个数n和m没有制约关系。则可改造成下列 文法:
T FT’
T’ *FT’|
F (E)| i
我们构造每个非终结符的FIRST和FOLLOW集合
解:FIRST(E) = { (, i }
FOLLOW(E’) = {+, }
FOLLOW(E’) = { ), #}
FIRST(T) = {(, i }
FOLLOW(T) = {+, ), # }
第四章 语法分析--自上而下分析
例题与习题解答
[例1]试构造与下列文法G[S]等价的无左递归文法。
G[S]: SSa|Nb|c
(1)
N Sd|Ne|f
(2)
对于(1)我们引入新非终结符S’
则: S NbS’ |cS’
[1]
S’ aS’|
[2]
将 S代入 (2)
N Ne |NbS’d |cS’d |f
5.1 自下而上分析基本问题 其基本问题包括下列问题:
5.1.1归约 5.1.2 规范归约简述
在这一部分应掌握短语和直接短语两个重要
概念
5.1.3 符号栈的使用与语法树的表示
第四章 语法分析--自上而下分析

z第4章 语法分析 4.2 自下而上 优先分析法

z第4章 语法分析 4.2 自下而上 优先分析法

直观算符优先分析法
使用分析表,构造分析算法
记号使用说明:
#:语句括号(栈底 w后) θ:现行栈顶符 a:刚读入字符 OPTR:运算符栈 OPND:操作符栈(和课本稍有不同)
分析算法步骤:
①下一个输入符号读至a中;
②若a为i,则a—>OPND,转第一步; ③若a为算符且θ a,θ 为OPTR栈顶符号,则调用关于θ 的处理程序(语义程序),处理子表达式 : E(1) θ E(2) ;然后重新进入第3步;其中, E(1) 、E(2) 分别为OPND栈的次栈顶和栈顶)
定义:假设a、b∈VT, a和b在句型中:
1. 为…ab…形式; 2. 为…aAb…形式,A∈VN。
规定以下优先关系: 1. 2. a a b b a的优先性低于b a的优先性等于b
3.
4.
a
b
a的优先性高于b
a与b不可能相邻,即此符号串不是句型(出错)。
如果以上四种关系中的任意两种都不会同时成立,则可以根 据终结符号之间的归约关系进行语法分析。

直观算符优先关系表的构造方法
给定文法G:E→E+E|E*E|(E)|i 其中:VT={+,*,i,(,)} 文法G的语言是算术表达式,运算符:+、*、(、)。
1.
2.
3.
句型为E+E*E时,应先处理‚E*E”,而不是‚E+E”, 所以规定符‚+”和‚*‛存在于句型…+E*…中时, ‚+”号优先级低于‚*‛号。 句型为E+E+E时,应先处理左面的‚E+E”,所以规定 当 ‚+”存在于句型…+E+E+…中时,左面的‚+”号 优先级高于‚+”号。 句型为(E)*E 时,应先处理‚(E)”,所以规定终极符 ‚(”与‚)”的优先级相同。

第04章-语法分析自上而下分析

第04章-语法分析自上而下分析
否符合语法规则。 ▪ 语法分析器的工作本质:按文法的产生式,识别
输入符号串是否为一个句子。 ▪ 语法分析器在编译器中的地位:
源程序
单词符号
词法分析器
取下一个单 词符号
语法分析器
语法分析树
编译器的 后继部分
2021/4/6
符号表
3
4.1 语法分析器的功能
▪ 语法分析方法
➢ 自上而下分析法
从文法的开始符号出发,反复使用文法的产生式, 寻找与输入符号串匹配的推导。
分析输入串x*y(记为)。
xx**yy
SS
IPIPIP xx A y * **
2021/4/6
7
4.2 自上而下分析面临的问题
▪ 当某个非终结符有多个产生式候选时,可 能带来如下问题:
➢ 1.分析过程中,当一个非终结符用某一个候选 匹配成功时,这种匹配可能是暂时的。这时, 不得不“回溯”。
➢ 2.文法左递归问题。一个文法是含有左递归的 ,如果存在非终结符P
➢ 最后所得的无左递归文法是: S→Qc | c Q→Rb | b R→bcaR | caR |a R R→ bca R |
➢ 不同排序所得的文法的等价性是显然的。
2021/4/6
17
4.3.2 消除回溯、提左因子
▪ 为了消除回溯就必须保证:对文法的任何 非终结符,当要它去匹配输入串时,能够 根据它所面临的输入符号准确地指派它的 一个候选去执行任务,并且此候选的工作 结果应是确信无疑的。
2021/4/6
14
4.3.1 左递归的消除
▪ 例4.3 考虑文法G(S)
S→Qc|c Q→Rb|b R→Sa|a
➢ 令它的非终结符的排序为R、Q、S。 ➢ 对于R,不存在直接左递归。 ➢ 把R代入到Q的有关候选后,把Q的规则变为

第四章 语法分析——自上而下分析

第四章 语法分析——自上而下分析

解二: 规定顺序:S、Q、R
则等价的无左递归的文法: SQc | c QRb| b RbcaR’ | caR’ | aR’ R’bcaR’ |
RSa | a RQca | ca | a
RRbca|bca | ca | a
RbcaR’|caR’ | aR’ R’ bcaR’|
(因为不需要试探某个候选式,而是准确地指派 某个候选式)
17
终结首符集FIRST
令文法G不含左递归,对它的所有非终结符的每 个候选式定义终结首符集 FIRST(): * FIRST()={a | a , a∈VT }
特别地 * 若 ,则规定 ∈ FIRST()
显然, FIRST()是从推导出的所有可能的开头终 结符a或 。
3
§4.2 自上而下分析面临的问题
一、带‚回溯‛的自上而下分析方法:
自上而下分析方法,就是对任何输入串,试 图用一切可能的方法,从文法的开始符号出发, 自上而下地为输入串建立一个语法树(或最左推 导)。 这种分析过程实质上是一种试探过程,即反 复使用不同的产生式以求能匹配输入串。
4
例4.1 设有文法: SxAy
解: S iCtSA | a
A | eS
C b
22
4.3.3 LL(1)分析条件 当一个文法不含左递归,并且满足每个非终结 符的所有候选首符集两两不相交,是不是一定能进 行有效的自上而下的语法分析呢?
若存在 ∈ FIRST() ,则问题较复杂,需要进 一步考虑。 定义:非终结符A的 FOLLOW 集:
* FOLLOW(A)= { a| S …Aa… ,a∈VT } 特别地, * 若S …A,则规定,构造FIRST(X)
a) 若X∈VT,则 FIRST(X)={X}。

自下而上语法分析

自下而上语法分析

自下而上语法分析1、规约:自下而上的语法分析过程:分为简单优先分析法,算符优先分析法,LR分析法。

2、自下而上的语法分析过程思想:自下而上的语法分析过程是一个最左规约的过程,从输入串开始,朝着文法的开始符号进行规约,直到文法的开始符号为止的过程。

输入串在这里是指词法分析器送来的单词符号组成的二元式的有限序列。

3、自下而上的PDA(下推自动机)工作方式:“移近-规约”方式注:初态时栈内仅有栈顶符“#”,读头指在最左边的单词符号上。

语法分析程序执行的动作:◆移进:读入一个单词并压入栈内,读头后移◆规约:检查栈顶若干符号能否进行规约,若能,就以产生式左部代替该符号串,同时输出产生式编号。

◆识别成功:移近-规约的结局是栈内只剩下栈底符号和文法的开始符号,读头也指向语句的结束符。

◆识别失败。

4、判读一语句是否是该文法的合法语句(可以用语法树)5、优先分析器:简单优先分析法(理论简单,实际比较麻烦)算符优先分析法6、LR分析器7、相邻文法符号之间的优先关系◆在句型中,句柄内各相邻符号之间具有相同的优先级。

◆由于句柄要先规约,所以规定句柄两端符号的优先级要比位于句柄之外的相邻符号的优先级高。

(#的优先级是最低的。

)9、简单优先文法:定义:一个文法G,如果它不含ε的产生式,也不含任何右部相同的不同产生式,并且它的任何符号(X,Y)-X,Y是非终结符或终结符—或者没有关系,或者存在优先级相同或低于、高于等关系之一,则这是一个简单优先文法。

10、简短优先分析的思想1)简单优先矩阵:根据优先关系的定义:将简单优先文法中各文法符号之间的这种关系用一个矩阵表示,称作简单优先矩阵。

2)PDA读入一个单词后,比较栈顶符号和该单词的优先级,若栈顶符号优先级低于该单词,继续读入;若栈顶符号优先级高于或者等于读入符号,则找句柄进行规约,找不到句柄继续读入11、简单优先法的优缺点:1、优点:算法比较好理解。

2、缺点:适用范围小,分析表尺寸太大。

自下而上语法分析

自下而上语法分析

⾃下⽽上语法分析⼀实验题⽬⾃下⽽上语法分析⼆实验⽬的1.给出PL/0⽂法规范,要求编写PL/0语⾔的语法分析程序。

2.通过设计、编制、调试⼀个典型的⾃下⽽上语法分析程序,实现对词法分析程序所提供的单词序列进⾏语法检查和结构分析,进⼀步掌握常⽤的语法分析⽅法。

3.选择最有代表性的语法分析⽅法,如算符优先分析法、LR分析法;或者调研语法分析器的⾃动⽣成⼯具YACC的功能与⼯作原理,使⽤YACC⽣成⼀个⾃底向上的语法分析器。

三实验环境Ubuntu16.04、C++语⾔、gcc⼯具链四实验内容已给PL/0语⾔⽂法,构造表达式部分的语法分析器。

分析对象(算术表达式)的BNF定义如下:<表达式>::=[-|+]<项>{<加法运算符><项>}<项>::=<因⼦>{<乘法运算符><因⼦>}<因⼦>::=<标识符>|<⽆符号整数>|‘(’<表达式>‘)’<加法运算符>::=+|-<乘法运算符>::=*|/<关系运算符>::==|#|<|<=|>|>=五实验要求1. 将实验⼀的“词法分析”的输出结果,作为表达式语法分析器的输⼊,进⾏语法解析,对于语法正确的表达式,报告“语法正确”;对于语法错误的表达式,报告“语法错误”,指出错误原因。

2. 把语法分析器设计成⼀个独⽴的⼀遍的过程。

3. 采⽤算符优先分析法或者LR分析法实现语法分析;或者调研语法分析器的⾃动⽣成⼯具YACC的功能与⼯作原理,使⽤YACC⽣成⼀个⾃底向上的语法分析器。

六设计思想我采⽤LR(0)分析法,⾸先写出表达式的⽂法,再写出⽂法的项⽬,画出识别前缀的DFA,构造LR(0)分析表,根据分析表写出程序。

四实验步骤1写出表达式的⽂法:2⽂法的项⽬:3画出识别前缀的DFA:4构造LR(0)分析表:五算法流程六源程序#include<stdio.h>#include<string.h>#include<stdlib.h>char sym[20][8]={//符号表 {'s','s','e','s','s','s','e','e'},//1 {'e','e','e','e','e','e','a','e'},//2 {'e','e','e','s','s','s','e','e'},//3 {'r','r','r','r','r','r','r','r'},//4{'r','r','r','r','r','r','r','r'},//5{'s','e','e','e','e','e','e','e'},//6 {'s','e','s','e','e','e','e','s'},//7{'r','r','r','r','r','r','r','r'},//8{'r','r','r','r','r','r','r','r'},//9{'s','s','e','s','s','s','e','e'},//10{'r','r','r','r','r','r','r','r'},//11{'e','e','e','s','s','s','e','e'},//12{'r','r','r','r','r','r','r','r'},//13{'e','e','e','s','s','s','e','e'},//14{'e','e','e','e','e','e','e','s'},//15{'s','e','e','e','e','e','e','e'},//16{'e','e','s','e','e','e','a','e'},//17{'r','r','r','r','r','r','r','r'},//18{'r','r','r','r','r','r','r','r'},//19{'r','r','r','r','r','r','r','r'}};//20char snum[20][8]={//数字表{3,4,0,7,8,9,0,0},//1{0,0,0,0,0,0,0,0},//2{0,0,0,7,8,9,0,0},//3{8,8,8,8,8,8,8,8},//4{11,11,11,11,11,11,11,11},//5{11,0,0,0,0,0,0,0},//6{11,0,13,0,0,0,0,17},//7{26,26,26,26,26,26,26,26},//8{28,28,28,28,28,28,28,28},//9{3,4,0,7,8,9,0,0},//10{6,6,6,6,6,6,6,6},//11{0,0,0,7,8,9,0,0},//12{19,19,19,19,19,19,19,19},//13{0,0,0,7,8,9,0,0},//14{0,0,0,0,0,0,0,17},//15{11,0,0,0,0,0,0,0},//16{0,0,13,0,0,0,0,0},//17{32,32,32,32,32,32,32,32},//18{15,15,15,15,15,15,15,15},//19{23,23,23,23,23,23,23,23}};//20int go[20][6]={//goto表{2,1,0,0,0,6},//1{0,0,0,0,0,0},//2{0,0,5,0,0,6},//3{0,0,0,0,0,0},//4{0,0,0,0,0,0},//5{0,0,0,10,0,0},//6{0,0,0,0,12,0},//7{0,0,0,0,0,0},//8{0,0,0,0,0,0},//9{2,14,0,0,0,6},//10{0,0,0,0,0,0},//11{0,0,15,0,0,6},//12{0,0,0,0,0,0},//13{0,0,0,0,0,16},//14{0,0,0,0,0,0},//15{0,0,0,18,0,0},//16{0,0,0,0,19,0},//17{0,0,0,0,0,0},//18{0,0,0,0,0,0},//19{0,0,0,0,0,0}};//20void main(){int step=1;/*number of analysis step*/int length=0;/*length of string*/int i,j,m,n;int l=0;/*length of state & ch*/int k=0;int num,x=1;int state[20]={0};/*initial state stack*/char ch[20]={'#'};/*initial character stack*/char str[20];/*define array of string*/char cha;char how;/*how include's','r','a'and null*/char A;//clrscr();printf("please input a string:");do{scanf("%c",&cha);str[length]=cha;length++;}while(cha!='#');/*input a string calculate it's length*/printf("\n--------------------------------------------------------------------------\n"); printf("step\tstate\t\tcharacter\tstring\t\taction\n");printf("--------------------------------------------------------------------------\n"); do{//if(step==10) {printf("\nhhh:%c %c\n",ch[1],ch[2]);}switch(str[k])/*judge str[k]*/{case '+':j=0;break;case '-':j=1;break;case '*':j=2;break;case 'i':j=3;break;case 'n':j=4;break;case '(':j=5;break;case '#':j=6;break;case ')':j=7;break;default:j=-1;break;}if(j!=-1){how=sym[state[l]][j];/*judge how*/num=snum[state[l]][j];/*state's number*/if(how=='s'){printf("%d\t",step);/*output step*/for(i=0;i<=l;i++){printf("%d ",state[i]);/*ouput state stack*/}if(l>=3) printf("\t");else printf("\t\t");for(i=0;i<=l;i++){if(ch[i]==' ' && x==1){ch[i]='*';x++;}printf("%c",ch[i]);/*ouput character stack*/}printf("\t\t");for(i=0;i<k;i++){str[i]=' ';printf("%c",str[i]);}for(i=k;i<length;i++){printf("%c",str[i]);/*output string stack*/}printf("\t");printf("push state %d!\n",num);/*output action*/ l=l+1;state[l]=num;ch[l]=str[l-1];//printf("ch:%c\n",ch[l]);step=step+1;k=k+1;/*next rotate value*/}else if(how=='r'){printf("%d\t",step);/*output step*/for(i=0;i<=l;i++){printf("%d ",state[i]);/*ouput state stack*/}if(l>=3) printf("\t");else printf("\t\t");for(i=0;i<=l;i++){if(ch[i]==' ' && x==2){ch[i]='i';x++;}printf("%c",ch[i]);/*ouput character stack*/}printf("\t\t");for(i=0;i<k;i++){str[i]=' ';printf("%c",str[i]);}for(i=k;i<length;i++){printf("%c",str[i]);/*output string stack*/ }printf("\t");switch(num)/*judge num*/{case 8:A='S',m=1;l=l-m;printf("s->+");break;case 11:A='S',m=1;l=l-m;printf("S->-");break;case 26:A='F',m=1;l=l-m;printf("F->i");break;case 28:A='F',m=1;l=l-m;printf("F->n");break;case 6:A='E',m=3;l=l-m;printf("E->STA");break;case 19:A='T',m=2;l=l-m;printf("T->FB");break;case 32:A='F',m=5;//printf("l=%d",l);//3l=l-m;printf("F->(E)");//F->(F+F)break;case 15:A='A',m=3;l=l-m;printf("A->+TA");break;case 23:A='B',m=3;l=l-m;printf("B->*FB");break;}switch(A)/*judge A*/{case 'S':n=0;break;case 'E':n=1;break;case 'T':n=2;break;case 'A':n=3;break;case 'B':n=4;break;case 'F':n=5;break;}num=go[state[l]][n];printf(",push%d!\n",num);l=l+1;state[l]=num;ch[l]=A;//if(l==1) l++;step=step+1;k=k;}else if(how=='a'){printf("%d\t",step);/*output step*/for(i=0;i<=l;i++){printf("%d ",state[i]);/*ouput state stack*/}if(l>=3) printf("\t");else printf("\t\t");for(i=0;i<=l;i++){printf("%c",ch[i]);/*ouput character stack*/}printf("\t\t");for(i=0;i<k;i++){str[i]=' ';printf("%c",str[i]);}for(i=k;i<length;i++){printf("%c",str[i]);/*output string stack*/}printf("\t");//\tprintf("acc!\n");printf("语法正确!\n");exit(1);}else{printf("ERROR!\n");exit(1);}}else{printf("wrong character!\n");exit(1);}}while(str[k]!='\0');printf("--------------------------------------------------------------------------\n");return ;}七调试数据及结果调试数据:(i+n)*i最终结果:⼋实验体会这次实验为了更⽅便观察⾃下⽽上的分析过程,我将标识符的符号简写为i,将数字的符号简写为n,将加号简写为+,将减号简写为-,将括号简写为(),其实可以从词法分析输出的⽂件中使⽤ident、plus等符号来进⾏分析,但上述符号的表⽰⽅法更符合书中的分析过程,并且更易观察程序分析的对错。

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

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

• 例 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)所得的文法。即去除那些从开始符号出发永 远无法到达的非终结符的产生规则。

第四章(2)自下而上语法分析

第四章(2)自下而上语法分析

练习
给定文法G[S]:
S T a | (T) T,S | S
(a,(a,a)) 开始 #
a,(a,a))# 移进 ,(a,a))# 移进 ,(a,a))# 归约 ,(a,a))# 归约 (a,a))# 移进 a,a))# 移进 ,a))# 移进 ,a))# 归约 ,a))# 归约 a))# 移进 ))# 移进 ))# 归约 ))# 归约 )# 移进 )# 归约 )# 归约 # 移进
最左推导(Left-most Derive)
每次推导都替换当前句型的最左边的非终结符.— —与最右归约对应
最右推导(Right-most Derive) 最右推导
每次推导都替换当前句型的最右边的非终结符.— —与最左归约(规范归约)对应,得规范句型 例:设有文法G[S]: (1) S → aAcBe (2) A → b (3) A → Ab (4) B → d 使用最右推导: ( 2 ) (1 ) (4 ) (3 ) 因为S aAcBe aAcde aAbcde abbcde,所以 rm rm rm rm abbcde是文法G的句子.
(1) E T | E+T (2) T F | T*F (3) F i | (E) E
T E T F id1 + T F id2 * F id3
所得的结果是: 所得的结果是:用产生式序列表示语法分析树
1
#
#( #(a #(S #(T #(T, #(T,( #(T,(a #(T,(S #(T,(T #(T,(T, #(T,(T,a #(T,(T,S #(T,(T #(T,(T) #(T,S #(T #(T)
存 放 句 型 前 缀 ) 栈 X1 X2 X3 … # ( 输入串 a1 a2 a3 …… # 输出 "移进-归约" 分析程序

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

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

二、算符优先文法和优先表的构造
1 算符优先文法(OPG文法)
两个非终结符相邻
(1)算符文法(OG文法):设有一文法G,若G中没有形如
S→…QR…产生式,(S,Q,R∈VN)则称文法G为算符文 法。 (2)定义优先关系:设文法G是一个OG文法,令a,b是任意两 个终结符号,P , G , R 是非终结符号,定义: . ① a = b 当且仅当文法G中含有形如P→…ab…或 P→…aQb…规则。 ② a <. b 当且仅当文法G中含有形如P→…aR…的 规则, 其中:R=>b…或R=>Qb…。 ③ a .> b 当且仅当文法G中含有形如P→…Rb…的 规则, 其中:R=>…a 或 R=>…aQ。
3
S S→aAcBe A→b | Ab a A c B e B→d 问abbcde是不是该文法的句子? A b d 步骤 符号栈 输入流 动作 0 # abbcde# b 1 #a bbcde# 移进 2 #ab bcde# 移进 3 #aA bcde# 归约,用A→b 4 #aAb cde# 移进 5 #aA cde# 归约,用A→Ab 6 #aAc de# 移进 7 #aAcd e# 移进 8 #aAcB e# 归约,用B→d 9 #aAcBe # 移进 10 #S # 归约,用S →aAcBe 4 11 #S # 成功 例:设文法G[S]:
10
优先关系的例子

文法:S→bAb
A→(B | a B→Aa) //S→bAb //A→(Aa)|a
语言:{bab, b(aa)b, b((aa)a)b, } 可以从语法树里面导出部分优先关系。

S b b<a A a b a>b
S
b

《编译原理课程教案》第4章:自下而上语法分析

《编译原理课程教案》第4章:自下而上语法分析

构造识别活前缀的DFA, 并根据DFA构造分析表
构造过程中需要消除直接 左递归和提取左因子等操 作
SLR(1)文法及其分析表的构造
SLR(1)文法是LR(0)文法 的简化版本,通过引入 FOLLOW集解决冲突问题
FOLLOW集表示在当前非 终结符之后可能出现的终 结符集合
ABCD
构造SLR(1)分析表时,需 要计算每个非终结符的 FOLLOW集
算符优先分析算法
01
02
03
算符优先分析算法是一 种自下而上的语法分析 方法,通过不断归约和
移进来构造语法树。
在分析过程中,需要维 护一个分析栈和一个输 入缓冲区,分别用于存 储已经分析过的部分和
待分析的部分。
根据优先关系表和分析 栈顶的元素,可以确定 下一步的操作是移进还
是归约。
算符优先分析法的局限性
《编译原理课程教案》第4章:自 下而上语法分析
contents
目录
• 引言 • 自下而上语法分析基本概念 • 算符优先分析法 • LR分析法 • 自下而上语法分析的优化技术 • 实验环节:自下而上语法分析器设计 • 章节小结与拓展思考
01 引言
编译原理课程概述
编译原理是计算机科学的一个重 要分支,研究将高级语言程序转 换为机器语言程序的原理和技术。
总结经验教训
总结实验过程中的经验教训,包括设计思路 的合理性、实现过程的难点和易错点等,为 今后的学习和工作提供参考。
07 章节小结与拓展思考
章节小结:关键知识点回顾
自下而上语法分析基本概念
从输入串开始,逐步进行归约,直到文法的 开始符号。
LR分析法
利用移进-归约思想,结合栈和状态转移表 进行语法分析。

第04章自上而下语法分析2

第04章自上而下语法分析2

if (sym= =‘#’)
见E'
F(); T ( ); }
见F
printf (“success”);
else printf (“fail”); 返回下一页 }2021/2/22
见T'
17
4.2.4 递归下降分析法
F() {
if (sym= = ‘id’) Scaner ( ); else if (sym= = ‘(’) {
第一个输入符号读进a S栈顶符号出栈放入 X中
将y1y2∙∙∙yn逆序放 入S栈中,若右部 符号串为ε,则ε 不进S栈
Y
X=a ?
Y
YN
将下一个输 入符号读入a
2021/2/22
X∈VT? N
N 出错
X=‘#’ ? N Y
X=a ? Y
STOP
查M[X,a]=X →y1y2···yn ?
N 出错
25
E → TE' E' → +TE' | ε T → FT' T' → *FT' | ε F → (E) | id
2021/2/22
main( )
{
Scaner ( );
E ( );
if (sym= =‘#’)
printf (“success”);
else printf (“fail”);
}
13
4.2.4 递归下降分析法
2.计算文法G’[S]每个非终结符的FIRST集 和FOLLOW集。
3.判断文法G’[S] 是否LL(1)文法。
4.试构造文法G’[S] 的预测分析表。
52021./2给/22 出输入串(a)# 的分析过程。

第四章语法分析-自上而下分析

第四章语法分析-自上而下分析

n
N T * T,则aFIRST(X)。
T
,则 FIRST(X)={X}。 ,且有产生式Xa,aV
N
1 2 i VN , 而有产生式X Y1 ,,Yn 。当Y1 ,Y2 ,,Yi-1 都 时,(其中 1≤i≤n),则FIRST(Y1 ,)-{},,FIRFIRST(Yj )包含把加到
FOLLOW(T)= FOLLOW(T)= #,),+ FOLLOW(F)= #,),+,* 七、证明上述文法是否为LL(1)文法 对于产生式A: 1、若 ,证明侯选式,的首字符集是否相交。 FIRST()∩FIRST()= Ф 例:F(E)i FIRST(()∩FIRST(i)= Ф 2、若=ε,证明FIRST(A)和FOLLOW(A)是否相交。 FIRST(A)∩FOLLOW(A)=φ 例:E`+TE` FIRST(E`)∩FOLLOW(E`) = +, ∩ ),# =φ 八、构造分析表的算法 1、对文法G的每个产生式A→α执行第二步和第三步; 2、对每个终结符aFIRST(),把A→α加至M[A,a]中; 3、若εFIRST(α),则对任何bFOLLOW(A)把A→α(或A)加至 M[A,b]中; 4、把所有无定义的M[A,a]标上“出错标志” 例: E→TE` , E`→+TE`´|ε T→FT` , T`→*FT`´|ε F→(E)|i 求其FIRST的集合: FIRST(E)=FIRST(T)=FIRST(F)={(,i )} FIRST(E)={ +,ε},FIRST(T)={ *,ε} 求其FOLLOW的集合: FOLLOW(E)= FOLLOW(E)= #,) FOLLOW(T)= FOLLOW(T)= #,),+ FOLLOW(F)= #,),+,* 根据算法构造LL(1)的分析表:

语法分析—自上而下分析

语法分析—自上而下分析
是一种试探过程,是反复使用不同产生 式谋求匹配输入串的过程。
9
§4.2 自上而下面临的问题
例:文法 SxAy A**|*
输入串α :x*y
S x Ay
S x Ay **
S x Ay
*
10
注:
• 回溯法也称试探法,它的基本思想是:从问题的 某一种状态(初始状态)出发,搜索从这种状态 出发所能达到的所有“状态”,当一条路走到“ 尽头”的时候(不能再前进),再后退一步或若 干步,从另一种可能“状态”出发,继续搜索, 直到所有的“路径”(状态)都试探过。这种不 断“前进”、不断“回溯”寻找解的方法,就称 作“回溯法”。
三、分析条件
1.当一个文法不含左递归,并且满足每个非终结符的 所有候选首符集两两不相交的条件,是不是就一定能 进行有效的自上而下分析了呢?
28
§4.3 LL(1)分析法
例:文法
EE+T|T TT*F|F F(E)|i
E T E’
经消去直接左递归后变成 ETE’ E’+TE’|ℇ TFT’ T’*FT’|ℇ F(E) |i
FIRST(A)
2.A→ε
3.A→X1 X2......XK
*
(1) * a..X2....... FIRST(X1)/{ε}
(2) * ε X2.......
FIRST(X2)/{ε}
ε
(3) * εε......ε
36
FIRST集
1.First(X)集合构造,X∈VT∪VN
例:求下题的FIRST集
25
§4.3 LL(1)分析法
3.提取公共左因子 A.事实上,许多文法均存在这样的非终结符,
其所有候选的终结首符集并非两两不相交。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

• 关键是如何识别可归约的符号串?
语法分析中问题的提出:
① 在构造语法树的过程中,何时归约?
当可归约串出现在栈顶时就进行归约。 ② 如何知道在栈顶符号串中已经形成可归约串? 如何进行归约? 通过不同的自底向上的分析算法来解释,不 同的算法对可归约串的定义是不同的,但分析过 程都有一个共同的特点:边移进边归约。 规范归约:使用句柄来定义可归约串 算符优先:使用最左素短语来定义可归约串
动作
1) 2) 3) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 准备 移进 归约 归约 归约 移进 移进 归约 归约 移进 移进 归约 归约 归约 接受

输入缓冲区
F→id T→F E→T
F→id T→F
F→id T→T*F E→E+T
# id1+id2*id3# #id1 +id2*id3# #F +id2*id3# #T +id 2*id3# #E +id2*id3# #E+ id2*id3# #E+id2 *id3# #E+F *id 3# #E+T *id 3# #E+T* id3# #E+T*id3 # #E+T*F # #E+T # #E #
算符优先关系表的构造算法
• 1.FIRSTVT集
–定义:对每个非终结符P, + + FIRSTVT(P)={a|P=>a...或P=>Qa...,a为终结 符,P,Q为非终结符}
由优先性低于的定义和FIRSTVT集合的定义可以得出: 若存在某个产生式:…aP…,对所有:b∈firstVT(P) 都有:a < b。
输入串 a1 a2 a3 …… 栈 X 存 1 放 X2 句 X3 型 前 缀 # ( )
#
输出
―移进-归约” 分析程序

• 3. 过程描述: do{ do { 将输入串最左边的符号移入栈内;} while (在栈里符号串中找到一个可归约串); 归约可归约串 while (文法开始符号出现在栈顶或者发现错误);
注: 每次归约的部分就是分析为句柄的字符串(最右推导)。
在规范归约中,关键问题就转化为如何识别句柄?
回到上例用句柄对句子abbcde进行归约有:
句型 abbcde aAbcde aAde aABe 归约规则 (2) Ab
(3)A Abc
(4)B d
(1)S aABe
(1)S aABe (2)A b (3)A Abc (4)B d
构造FIRSTVT集算法:
a
b
S
该分析过程反复执行“移进”和“归约”两个动作,直到栈中只有开始符号为止。
―移进-归约”分析法中栈的使用
• 移进-归约分析器使用了一个符号栈和一个输入缓冲区 • 1、句型表示 一般形式: 符号栈的内 剩余输入串 容 # 初态: 输入串# #S # 终态: 符号栈内容 + 输入缓冲区内容 = # 当前句型 # • 2、分析器结构
• 分析成功的条件:栈顶为文法符号,输入串为空。 • 注意:该过程并未涉及如何在栈里找可归约串。实际 上,不同的找可归约串的方法,构成了不同的分析算 法。
分析器的四种动作
• 1) 移进:读入下一个输入符号并把它下推进栈。 • 2) 归约:当栈顶符号串形成一个可归约的串(如:句 柄)时,直接进行归约,即用产生式左侧的非终结符替 换栈顶的句柄。 • 3) 接受:当栈底只有“#‖和开始符号,而输入也已经 到达右端标志符号“#‖时,识别出符号串是句子,执行 该动作,表示分析成功,是归约的一种特殊情况。 • 4) 出错:栈顶的内容与输入符号相悖,即当识别程序 发现输入符号串不是句子时,进行出错处理。 • 注意:决定移进和归约的依据是什么? 栈顶是否出现了可归约的符号串。
(1) E->E+T|T (2) T->T*F|F (3) F->(E)|id
E
T E T T F id2 * F id3
F
id1 +
所得的结果是:用产生式序列表示语法分析树
移进归约分析中的问题
• 1) 移进-归约冲突
–在分析到某一步时,既可以移进,又可以归约 –上例第10)步可以移进*,也可以按产生式 E→E+T进行归约。
• 自下而上语法分析主要有以下三种方法:
①简单优先分析法(规范归约)——文法按 一定原则规定文法符号的优先关系 ②算符优先分析法(不规范归约)——规定
算符之间的优先关系
③ LR分析法(规范归约)—— LR(0)、 LR(1)、SLR(1)和LALR(1)
语法分析树的生成演示
S aABe aAde aAbcde abbcde
1
2
3
4
5
6
7
8
9
10
移 移 归 移 移 归 移 归 移 归 进 进 约 进 进 约 进 约 进 约 动作 a b 2 b c 3 d 4 e 1 c b b A A A a a a e d B B A A A A a a a a
(1)S aABe (2)A b (3)A Abc (4)B d
由E->E+T
E * i, 得i > + => * E => E+T, 得+ > +
* E => T*F, 得* > + * E => (E), 得 ) > +
#
终结符+‗#‘
对于结束符#和其它终结符a有关系: # < a ;a > #
• 在优先表中,空白部分是一种错误关系 • 相同的终结符之间的优先关系不一定是 • 如果有a b,不一定有b a(不具传递 性),因为只定义相邻运算符之间的优先 关系,a,b相邻时,不一定b,a相邻。 • a,b之间未必有优先关系( , , )
–从语法树的角度看:从语法树的树叶开始,逐 步向上归约构造分析树,直到形成根结点。是 推导的逆过程。
• 最左推导(Left-most Derive)
– 每次推导都替换当前句型的最左边的非终结符。 – 与最右归约对应。
• 最右推导(Right-most Derive)
– 每次推导都替换当前句型的最右边的非终结符。 – 与最左归约(规范归约)对应,得规范句型。
• 3.算符优先文法
–算符文法G的任何终结符a,b之间要么没有优先 关系,若有优先关系,至多有 = ,< , > 中的一 种成立,则G为一算符优先文法。
例:E→E+E | E*E | (E) | i
因为:E→E+E , EE*E
证明不是算符优先文法。
则有 + *
又因为:E→E*E, EE+E
所以不是算符优先文法。
例:设有文法G[S]:
(1) S aABe (2) A b (3) A Abc (4) B d 使用最右推导: 2) (1 ) ( (3 ) aABe 因为S rm aAde aAbcde rm rm abbcde是文法G的句子。
abbcde,所以
rm (4 )
最左归约过程是最右推导的逆过程, 对输入串abbcde的 移进—归约过程如下: 步骤
• 2) 归约-归约冲突
–存在两个可选的句柄,可对栈顶符号进行归约 –例如上述第13)步,可以用T→F进行归约,又可 以按T→T*F进行归约。
• 各种分析方法中处理冲突的技术不同
算符优先分析
• 算符优先分析法的思想源于表达式的分析,即利用相邻 终结符号之间的关系来寻找可归约串。
• 将句型中的终结符号当作“算符”,借助于算符之间的 优先关系确定句柄。 • 显然,在一个符号串中,任意两个相邻终结符号a和b之 间,只可能存在以下四种优先关系: (1) a, b优先性相同,记作a b。 (2) a优先性高于b, 记作a b。 (3) a优先性低于b ,记作a b。 (4) a与b不可能相邻,即此符号串不是句型(出错)。 如果以上四种关系中的任意两种都不会同时成立,则可 以根据终结符号之间的归约关系进行语法分析。
自下而上的语法分析的一般过程
• 实现思想
–从输入符号串开始,从左到右进行扫描,将输 入符号逐个移入一个栈中,边移入边分析,一 旦栈顶符号串形成某个产生式的右部时,就用 该产生式的左部非终结符代替,称为归约。重 复这一过程,直到归约到栈中只剩下文法的开 始符号时,则分析成功, 称为“移进-归约” 方法。
• ―移进—归约”语法分析小结:
– 从输入串的开始依次读入单词(移进栈中) 。 – 一旦发现可归约串(某个产生式的右端)就立即归约。
– 归约就是将栈顶的一串符号用文法产生式的左部代 替,归约可能重复多次,然后继续移进。
– 若最终能归约成文法的开始符号,则分析成功(接 受);否则出错。
– 由于总是将句型的最左边的可归约串替换成非终结 符,该方法通常得到是最右推导。
S aABe A Abc | b Bd abbcde aAbcde aAde aABe 例
S aABe A Abc | b Bd abbcde aAbcde aAde aABe S 例
S aABe A Abc | b Bd abbcde aAbcde aAde aABe S S rm aABe rm aAde rm aAbcde rm abbcde 例
第四章(2) 自下向上语法分析
本章要求: 1. 掌握自下向上语法分析的基本思想和基本概念 2. 了解算符优先语法分析;求FIRSTVT集和 LASTVT集,构造算符优先关系表;能运用算 符优先分析方法进行表达式分析(选学) 3. 掌握句柄的定义与判定 4. 理解规范归约的过程和LR分析过程中的实现 5. 掌握LR语法分析的实现过程
相关文档
最新文档