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

17
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
分析输入串x*y(记为)。
x*y
S
IP x A y **
18
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
分析输入串x*y(记为)。
x*y
S
IP x A y **
19
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
(4.3)
虽没有直接左递归,但S、Q、R都是左递归的
SQcRbcSabc
一个文法消除左递归的条件
丌含以为右部的产生式
丌含回路
PP
30
例 文法G(S): S→Qc|c Q→Rb|b R→Sa|a
(4.3)
虽没有直接左递归,但S、Q、R都是左递归的
SQcRbcSabc
Q
Q
ⅹ
S
R
S→Qc|c Q→Rb|b R→Sa|a
35
例 考虑文法G(S)
S→Qc|c Q→Rb|b R→Sa|a
消除S的直接左递归后: S→abcS | bcS | cS S→abcS | Q→Sab |ab | b R→Sa|a
关于Q和R的觃则已是多余的,化简为:
S→abcS | bcS | cS
S→abcS |
(4.4)
36
注意,由于对非终结符排序的丌同,最 后所得的文法在形式上可能丌一样。但 丌难证明,它们都是等价的。
分析输入串x*y(记为)。
x*y
S
IP
15
例3.4.1 假定有文法G(S): (1) S→xAy (2) A→**|*
分析输入串x*y(记为)。
04 语法分析-自上而下分析

待分析的输入串: 待分析的输入串:i+i
只有当a 只有当a是允许出 现在非终结符A 现在非终结符A后 面的终结符时, 面的终结符时, 才可能允许A 才可能允许A自动 匹配。 匹配。
尾随集的定义: VN尾随集的定义:
=*>…Aa Aa…, FOLLOW(A)={a|S =*> Aa , a∈VT}; 特别地,如果S=*> S=*>…A 那么# FOLLOW(A)。 特别地,如果S=*> A,那么# ∈FOLLOW(A)。
例子
文法: S→xAy A→**|* 文法: 输入串:x*y 输入串: S => => => => xAy x**y xAy x*y (S→ xAy) (A→**) 回溯) (回溯) (A→*)
带回溯自上而下分析面临的问题
问题: 问题: 文法的左递归问题 回溯问题 虚假匹配问题 出错位置不确定 低效
实现思想: 实现思想:
分析程序由一组递归过程组成。 分析程序由一组递归过程组成。每一过程 对应于一个非终结符号。 对应于一个非终结符号。 每一个过程的功能是:选择正确的右部。 每一个过程的功能是:选择正确的右部。 在右部中有非终结符号时, 在右部中有非终结符号时,调用该非终结 符号对应的过程。 符号对应的过程。
消除文法的左递归
文法不含回路(形如P=+> P推导 推导) 文法不含回路(形如P=+> P推导) 不含回路 前提: 前提: 不含以ε 也不含以ε 为右部的产生式 结论: 那么可以通过执行消除文法左递 结论: 那么可以通过执行消除文法左递 归的算法消除文法的一切左递归 归的算法消除文法的一切左递归 改写后的文法可能含有以ε (改写后的文法可能含有以ε 为右部的产生式)。 为右部的产生式)。
理学自上而下的语法分析

b∈follow(A),把A→α加至M[A][b]。 ⑤把所有未定义的M[A][c]标上“出错标志”
(c∈VT)。
4.7 预测分析法
㈢预测分析控制程序实现 ①数据结构 M:二维数组,存放预测分析表。 stack:符号栈,初始时为“#S”(S为开
中ε∈afi∈rsVt(XT ,)。则 a∈first(X) ; 若 X→ε , 则 ③观察每个产生式,若有X→Y……,其
中为fYir∈st(VYN),/ε)则加将到fifrisrts(tY(X)中)中的。非ε元素(记
4.5 first集和follow集
考虑更一般情况, Y2、…Yi-1∈VN。
始符号)。 X:表示栈顶符号 t.code:当前处理单词种别
4.7 预测分析法
②算法描述 预测分析控制程序任何时刻的动作,都
按照栈顶符号X和当前输入符号t.code行 事,控制程序每次执行下述三种可能的 动作之一(暂不考虑出错情况)。 l 若X 和 t.code 均为 '#',则分析成功, 输入串为合法句子,终止分析过程。
4.1 带回溯的自上而下分析法概 述
从文法的开始符号出发进行推导,最终 推出确定的输入串(由单词种别构成的 源程序)。
4.1 带回溯的自上而下分析法概 述
从根结点出发,试图用一切可能的办法, 自上而下地为输入串建立一棵语法树。 或者说,为输入串寻找一个最左推导。
4.1 带回溯的自上而下分析法概 述
A→α1|α2|…|αn|ε 设当前输入符号为a,根据下述原则
if (a∈first(αi))
用A→αi推导(1≤i≤n)
else if (a∈follow(A))
自上而下分析

实验二语法分析(自上而下分析)一、实习目的熟悉并设计一个表达式的语法分析器二、实验内容1.设计表达式的语法分析器算法2.编写代码并上机调试运行通过要求:输入表达式输出——表达式语法是否正确三、实验要求运用算术表达式的LL(1)分析算法来设计的表达式的语法分析器。
LL(1)文法是一个自上而下的语法分析方法,它是从文法的识别符号出发,生成句子的最左推导,从左到右扫描源程序,每次向前查看一个字符,便能确定当前应该选择的产生式。
LL(1)分析需要用一个分析表和一个符号栈。
分析表是一个矩阵,它的元素可以存放一个非终结符的产生式,表明当符号栈的栈顶元素非终结符遇到当前输入字符时,所应选择的产生式;分析表的元素还可以是存放一个出错标志,说明符号栈S 的栈顶元素非终结符不应该遇到当前输入符(终结符)。
重复调用LL(1)分析方法对每一个输入字符进行分析,直到输入栈为空为止。
四、运行结果注:此程序只能对由‘i’,’+’,’*’,’<’,’>’构成的以‘#’结速的字符串进行分析。
五、源程序(此程序只能在VC++中运行)#include<stdio.h>#include<stdlib.h>#include<string.h>#include<dos.h>char A[20];/*分析栈*/char B[20];/*剩余串*/char v1[20]={'i','+','*','(',')','#'};/*终结符*/ char v2[20]={'E','G','T','S','F'};/*非终结符*/int j=0,b=0,top=0,l;/*L为输入串长度*/typedef struct type/*产生式类型定义*/ {char origin;/*大写字符*/char array[5];/*产生式右边字符*/int length;/*字符个数*/}type;type e,t,g,g1,s,s1,f,f1;/*结构体变量*/type C[10][10];/*预测分析表*/void print()/*输出分析栈*/{int a;/*指针*/for(a=0;a<=top+1;a++)printf("%c",A[a]);printf("\t\t");}/*print*/void print1()/*输出剩余串*/{int j;for(j=0;j<b;j++)/*输出对齐符*/ printf(" ");for(j=b;j<=l;j++)printf("%c",B[j]);printf("\t\t\t");}/*print1*/void main(){int m,n,k=0,flag=0,finish=0;char ch,x;type cha;/*用来接受C[m][n]*//*把文法产生式赋值结构体*/ e.origin='E';strcpy(e.array,"TG");e.length=2;t.origin='T';strcpy(t.array,"FS");t.length=2;g.origin='G';strcpy(g.array,"+TG");g.length=3;g1.origin='G';g1.array[0]='^';g1.length=1;s.origin='S';strcpy(s.array,"*FS");s.length=3;s1.origin='S';s1.array[0]='^';s1.length=1;f.origin='F';strcpy(f.array,"(E)");f.length=3;f1.origin='F';f1.array[0]='i';f1.length=1;for(m=0;m<=4;m++)/*初始化分析表*/for(n=0;n<=5;n++)C[m][n].origin='N';/*全部赋为空*//*填充分析表*/C[0][0]=e;C[0][3]=e;C[1][1]=g;C[1][4]=g1;C[1][5]=g1;C[2][0]=t;C[2][3]=t;C[3][1]=s1;C[3][2]=s;C[3][4]=C[3][5]=s1;C[4][0]=f1;C[4][3]=f;printf("提示:本程序只能对由'i','+','*','(',')'构成的以'#'结束的字符串进行分析,\n");printf("请输入要分析的字符串:");do/*读入分析串*/{scanf("%c",&ch);if ((ch!='i') &&(ch!='+') &&(ch!='*')&&(ch!='(')&&(ch!=')')&&(ch!='#')){printf("输入串中有非法字符\n");exit(1);}B[j]=ch;j++;}while(ch!='#');l=j;/*分析串长度*/ch=B[0];/*当前分析字符*/A[top]='#'; A[++top]='E';/*'#','E'进栈*/printf("步骤\t\t分析栈\t\t剩余字符\t\t所用产生式\n"); do{x=A[top--];/*x为当前栈顶字符*/printf("%d",k++);printf("\t\t");for(j=0;j<=5;j++)/*判断是否为终结符*/if(x==v1[j]){flag=1;break;}if(flag==1)/*如果是终结符*/{if(x=='#'){finish=1;/*结束标记*/printf("acc!\n");/*接受*/getchar();getchar();exit(1);}/*if*/if(x==ch){print();print1();printf("%c匹配\n",ch);ch=B[++b];/*下一个输入字符*/flag=0;/*恢复标记*/}/*if*/else/*出错处理*/{print();print1();printf("%c出错\n",ch);/*输出出错终结符*/exit(1);}/*else*/}/*if*/else/*非终结符处理*/{for(j=0;j<=4;j++)if(x==v2[j]){m=j;/*行号*/break;}for(j=0;j<=5;j++)if(ch==v1[j]){n=j;/*列号*/break;}cha=C[m][n];if(cha.origin!='N')/*判断是否为空*/ {print();print1();printf("%c->",cha.origin);/*输出产生式*/for(j=0;j<cha.length;j++)printf("%c",cha.array[j]);printf("\n");for(j=(cha.length-1);j>=0;j--)/*产生式逆序入栈*/A[++top]=cha.array[j];if(A[top]=='^')/*为空则不进栈*/top--;}/*if*/else/*出错处理*/{print();print1();printf("%c出错\n",x);/*输出出错非终结符*/exit(1);}/*else*/}/*else*/}while(finish==0);}/*main*/。
第四章 语法分析——自上而下分析

解二: 规定顺序: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、教学⽬的及要求:本章介绍编译程序的第⼆个阶段语法分析的设计⽅法和实现原理,包括⾃上⽽下分析的⽆回朔的递归下降分析、 LL(1)分析法。
要求理解递归下降分析、LL(1)⽂法的基本概念;掌握⽆回朔的递归下降分析的设计和实现、LL(1)分析表的构造与分析⽅法。
◇能够对⼀个给定的⽂法判断是否是LL(1)⽂法;◇能构造预测分析表;◇能⽤预测分析⽅法判断给定的输⼊符号串是否是该⽂法的句⼦;◇能对某些⾮LL(1)⽂法做等价变换:①消除左递归②提取左公共因⼦可能会变成LL(1)⽂法。
这样可扩⼤⾃顶向下分析⽅法的应⽤。
2、教学内容:语法分析器的功能,⾃上⽽下语法分析(递归下降分析法,预测分析程序),LL(1)分析法,递归下降分析程序构造,预测分析程序。
3、教学重点:递归下降⼦程序,预测分析表构造,LL(1)⽂法。
4、教学难点:对⼀个⽂法如何判断是否是LL(1)⽂法,由于在判断 LL(1)⽂法时⽤到⽂法符号串的开始符号集合(FIRST集)和⾮终结符后跟符号集合(FOLLOW集)的计算,⽽⼀般学⽣往往因概念不清或不够细⼼对这两个集合的计算常常出错,导致判断和分析结果的错误。
5、课前思考为了了解⾃顶向下(⾃上⽽下)分析的⼀般过程和问题,请学⽣⾸先回顾本章之前介绍的有关基本概念:◇句⼦、句型和语⾔的定义是什么?◇什么叫最左推导?◇什么叫最右推导和规范推导?◇什么叫确定的⾃顶向下语法分析?◇⾃顶向下语法分析是从⽂法的开始符号出发,反复使⽤各种产⽣式,寻找与输⼊符号匹配的推导。
◇确定的⾃顶向下语法分析中⽤的是哪种推导?◇在确定的⾃顶向下语法分析过程中,当以同⼀个⾮终结符为左部的产⽣式有多个不同右部时,如何选择⽤哪个产⽣式的右部替换当前的⾮终结符?◇确定的⾃顶向下语法分析对⽂法有何限制?6、章节内容第⼀节概述第⼆节 LL(1)分析⽅法第三节递归下降分析法5.1 概述LL分析法确定的⾃上⽽下分析⾃上⽽下分析递归下降分析法语法分析不确定的⾃上⽽下分析——即带回溯的分析⽅法算符优先分析⾃下⽽上分析LR分析⼀、带回溯的⾃顶向下分析⽅法是⾃顶向下分析的⼀般⽅法,即对任⼀输⼊符号串,试图⽤⼀切可能的办法,从树根结点(识别符号)出发,根据⽂法⾃上⽽下地为输⼊串建⽴⼀棵语法树,或者说,从识别符号开始,根据⽂法为输⼊串建⽴⼀个推导序列,这种分析过程本质上是⼀种试探过程,是反复使⽤不同规则谋求匹配输⼊串的过程。
语法分析—自上而下分析

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.事实上,许多文法均存在这样的非终结符,
其所有候选的终结首符集并非两两不相交。
编译原理-自上而下的语法分析

高效性
由于从文法的最顶端开始分析, 一旦发现不匹配,就可以立即终 止当前分支的搜索,避免不必要 的计算,提高了编译器的效率。
易于处理左递归文
法
自上而下的分析方法可以很方便 地处理含有左递归的文法,而左 递归是许多实际编程语言的重要 特征。
局限性
无法处理左边界问题
自上而下的分析方法在处理某些含有左边界的文法时可能 会遇到问题,因为这种方法会优先匹配最左边的符号,而 左边界问题需要从右往左匹配符号。
案例三
在编译器优化中,自上而下的语法分析被用 于识别和修改源代码中的冗余和低效的语法 成分。例如,在C编译器的实现中,自上而 下的语法分析可以用于优化循环结构,减少 不必要的循环次数,提高程序的执行效率。
自上而下的语法分析还可以用于代码生成和 代码生成器的实现。通过识别和解析源代码 中的语法成分,可以生成更高效、更安全的 机器代码或字节码,提高程序的执行效率和
安全性。
THANKS
感谢观看
详细描述:递归下降分析算法易于理解,每个产生式规 则对应一个函数,函数的实现相对简单明了。
详细描述:对于每个产生式规则,需要编写相应的递归 函数,可能会导致代码冗余。
移入-规约分析算法
总结词
基于栈的算法
详细描述
移入-规约分析算法是一种自上而下的语法分 析算法,它将目标语句从左到右依次读入, 并根据文法的产生式规则进行移入或规约操 作,直到找到目标语句的语法结构。
词法分析
词法分析是编译过程的第一步,也称为扫描或词法扫描。它的任务是从左 到右读取源代码,将其分解成一个个的记号或符号。
词法分析器通常使用正则表达式或有限自动机来识别和生成记号,这些记 号可以是关键字、标识符、运算符、标点符号等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第四章语法分析—自上而下分析知识结构:带回溯分析法回溯自上而下分析面临的问题左递归问题的解决语法分析-求FIRST、FOLLOW集合的算法自上而下分析LL(1)分析法证明LL(1)文法构造LL(1)分析表递归子程序的构造思想递归子程序法递归子程序的特点递归子程序的设计第一节语法分析综述一、语法分析的任务按照语言即定的语法规则,对字符串形式的源程序进行语法检查,并识别出相应的语法成分。
即语法结构是否符合语法规则。
二、语法分析器在编译程序中的地位(一遍扫描)三、语法分析方法通常把语法分析方法分为两大类,既自上而下分析与自下而上分析。
1、自上而下分析方法实际上是一种产生的方法,分析过程是一个推导过程。
⑴自上而下分析过程从文法G的开始符号S出发,通过反复使用产生式,逐步推导出与输入的符号串完全相匹配的句子。
采用最左推导,以文法开始符号为根结点,逐步为输入串自上而下地构造一棵语法树。
面临的输入符号为a,A所有的产生式:A12n①若a FISRT(i),则指派去执行匹配任务。
②若a不属于任何一个候选首字符集,则:a、若属于某个FISRT(i)且a FOLLOW(A),则让A 与自动匹配;b、否则,a的出现是一种错误。
例:设有文法G和输入符号串W:a*a+aG:S aA aA BaAB +-*/推导过程:S aA aBaA a*aA a*aBaA a*a+aA a*a+a=W 构造语法树:Sa AB a A* B a A+⑵自上而下分析法自上而下分析法又可分为确定和不确定的两种。
①不确定的分析法(带回溯)是一种穷举的试探方法,效率低、代价高,极少使用。
②确定的分析法(不带回溯)实现方法简单、直观,便于手工构造或自动生成语法分析器,是目前常用的方法之一。
但是对文法有一定的限制。
2、自下而上分析法⑴自下而上分析过程分析过程是归约过程。
从给定的输入串W开始,不断寻找与文法G中某个产生式P的侯选式(右部)进行匹配,并用P代替也称为归约。
⑵自下而上分析法①算符优先分析法定义算符(广义讲是文法的终结符号)之间的某种优先和结合关系,借助这种关系来寻找并确定可归约字符串,并进行归约。
②LR分析法是一类自左向右对输入串进行扫描的自下而上分析方法,分析过程是规范归约的序列。
适用于语法分析器的自动构造。
第二节自上而下分析面临的问题一、不确定的自上而下分析方法是从文法的开始S出发,试图用一切可能的方法向下推导,产生句子,这种分析过程的本质是一种试探推导过程。
例:文法G⑴S aAd⑵A ab a构造W=aad的最左推导:S aAd aad。
构造语法树:①产生树的根结点,即文法的开始符号。
②选用文法G的文法规则去延伸树。
③判断当前延伸的子结与输入串扫描到的字符是否匹配。
④若不匹配注销掉当前延伸的子树,选用文法规则的另一个产生式延伸分析树。
⑤直到输入串与语法树末端结点相匹配,分析结束。
S S Sa A d a A d a A da b这种试探识别句子的过程,只会使分析的过程不确定。
二、不确定性的原因由于分析过程中选择的侯选式不确定,造成输入串匹配的假象,甚至会导致算法实现的失败。
1、左递归问题由于采用最左推导,左递归将使得输入串的分析过程陷入无限循环之中。
2、回溯问题⑴采用试探的方法,如匹配不成功回溯到前面分析的某一步。
⑵可能出现假匹配,造成对输入串识别的失败。
⑶不能准确报告输入串的出错位置。
三、确定的自上而下分析方法1、确定的自上而下分析方法的必要条件⑴消除文法中的左递归;⑵消除文法中的回溯问题。
2、消除文法的左递归文法的左递归可以通过对文法产生式进行改写,使之不含有左递归的非终结符号。
左递归一般有两种情况,直接左递归和间接左递归。
⑴直接左递归如果文法中任意一个非终结符P,若P P(V N U V T),并且在最左推导中有P P形式,称为直接左递归。
⑵间接左递归在最左推导中有P +=>P形式,称为间接左递归。
①消除直接左递归P→Pα |改写为:P→PP P例:表达式文法E E+T T改写为:E TEE+TET T*F F改写为:T FTT*FTF(E) i②消除文法的左递归一般规则P→P1P2…… P m12……n i≠ε改写为:P→1P2P………n PP→1P2P………m P③消除间接左递归A→B…B→C…间接左递归: A B…C…A…C→A…例:文法GS→Qc|cQ→Rb|bR→Sa|a最左推导:S⇒Qc⇒Rbc⇒Sabc(间接左递归)⑶清除间接左递归非终结符排序为R,Q,S。
R不存在直接左递归,把R代入Q的规则:Q→Sab | ab | b再把Q代入S:S→Sabc | abc | bc | c消除S的左递归:S→abcS| bcS| cSS→abcS| εQ和R的产生式不再被引用,将Q和R删除。
非终结符排序为S,Q,R。
S不存在直接左递归,Q的产生式不包含S,再把S代入得到R:R→Rbca | bca | ca | a消除S的左递归:R→bcaR| caR| aRR→bcaR| ε改写为:S→Qc|c 不能删除Q→Rb|b 不能删除R→bcaR|caR|aRR→bcaR|ε3、消除回溯,提取左因子⑴消除回朔文法G不包含左递归,则G中非终结符号的每个候选式首字符集FIRST()为:FIRST()={a *=>a…,a V T,(V N U V T)*}若*=>,则∈ FIRST()。
⑵提取最左公共因子采用提取最左公共因子的方法改写文法,使得所有侯选式的首字符集两两不相交。
A→12……n12……m提取公因子:A→(12……n) 12……m改写后为:A→A12……mA→12……n4、确定的自上而下分析方法⑴预测分析法(LL(1)分析法)。
⑵递归子程序法。
第三节预测分析法(LL(1)分析法)一、LL(1)分析方法1、是按自左(第一个“L”)向右的顺序扫描输入字符串;2、在分析过程中产生句子的最左(第二个“L”)推导;3、“1”表示在分析过程中,每一步推导,最多只能向前查看(向右扫描)一个字符。
二、LL(K)分析方法如果分析过程的每一步推导,要向前查看K个输入字符,则称为LL(K)分析法。
三、LL(1)文法的定义该文法是上下文无关的一个子集,是自上而下分析技术的一类文法。
四、LL(1)分析法的必要条件1、文法中的非终结符号不包含左递归;2、对于文法中的每一个非终结符A的各个产生式的侯选首字符集两两不相交。
对于产生式A:⑴若ε,证明侯选式,的首字符集是否相交。
FIRST()∩FIRST()= Ф⑵若=ε,证明FIRST(A)和FOLLOW(A)是否相交。
FIRST(A)∩FOLLOW(A)=φ五、构造FIRST集合的算法对每一文法符号X(V N U V T)*1、若X V T ,则FIRST(X)={X}。
2、若X V N ,且有产生式X a,a V T,则a FIRST (X)。
3、若X V N ,X,则FIRST(X)4、若X V N,且Y1,Y2,,Y i V N,而有产生式X Y1,,Y n。
当Y1,Y2,,Y i-1都* =>ε时,(其中1≤i≤n),则FIRST(Y1,)-{},,FIRST(Y i-1)-{},FIRST(Y i)都包含在FIRST(X)中。
若FIRST(Y j)包含把加到FIRST(X)中。
例文法GE →T E`E`→+TE`|εT →F T`T`→*FT`|εF→(E)|iFIRST(E)=FIRST(T)=FIRST(F)={(,i )}FIRST(E)={ +,ε}FIRST(T)={ *,ε}六、构造FOLLOW集合的算法FOLLOW (A)={a | S *=>….Aa…. , a V T }若S *=>…A, 则#FOLLOW (A)FOLLOW (A)为所有句型中紧跟在非终结符A后面的所有终结符集合。
构造算法:1、对文法开始符号S,将“#”置于FOLLOW(S)中。
即FOLLOW(S) = # 。
2、若A →αBβ是一个产生式,则把FIRST(β)-{ε}加至FOLLOW(B)中。
3、若A →αB是一个产生式,或A→αBβ是一个产生式,而β⇒ε(即FIRST());则把FOLLOW(A)加至FOLLOW(B)中。
例文法GE→T E`E`→+TE`|εT →F T`T`→*FT`|εF→(E)|i求FOLLOW(E):因为F→(E),所以FIRST())加入FOLLOW(E)中,FOLLOW(E) = );又因为E→TE`,E是文法的开始符号,则#加至FOLLOW(E)中,所以FOLLOW(E)= # U FOLLOW(E)=#,) 。
求FOLLOW(E`):因为E→TE`, 满足算法(3)若A →αB是一个产生式,则把FOLLOW(A)加至FOLLOW(B)中,所以FOLLOW(E`)= FOLLOW(E)U FOLLOW(E)= #,)求FOLLOW(T):因为E→T E`, 满足算法⑵若A →αBβ是一个产生式,则把FIRST(β)\{ε}加至FOLLOW(B)中,所以FOLLOW(T) = FOLLOW(T) U FIRST(E`)\{ε}= {+}又因为E`⇒ε,满足算法(3)若A→αBβ是一个产生式,而β⇒ε,则把FOLLOW(A)加至FOLLOW(B)中。
所以FOLLOW(T) = FOLLOW(E) U FOLLOW(T)= #,) U+= #,),+求FOLLOW(T`):因为T→F T`,满足算法(3)若A →αB是一个产生式,则把FOLLOW(A)加至FOLLOW(B)中,所以FOLLOW(T) = FOLLOW(T) U FOLLOW(T`)= #,),+求FOLLOW(F):因为T→F T`, 满足算法⑵若A →αBβ是一个产生式,则把FIRST(β)\{ε}加至FOLLOW(B)中,所以FOLLOW(F) = FOLLOW(F) U FIRST(T`)\{ε}= {*}又因为T`⇒ε,满足算法(3)若A→αBβ是一个产生式,而β⇒ε,则把FOLLOW(A)加至FOLLOW(B)中。
所以FOLLOW(F) = FOLLOW(T) U FOLLOW(F)= #,),+U*= #,),+,*连续使用上述三条规则,直到每个FOLLOW不再增大为止。
FOLLOW(E)= FOLLOW(E)= #,)FOLLOW(T)= FOLLOW(T)= #,),+FOLLOW(F)= #,),+,*七、证明上述文法是否为LL(1)文法对于产生式A:1、若ε,证明侯选式,的首字符集是否相交。
FIRST()∩FIRST()= Ф例:F(E)iFIRST(()∩FIRST(i)= Ф2、若=ε,证明FIRST(A)和FOLLOW(A)是否相交。