从输入串开始,逐步进行“归约”,直至归约到文法的开始符号。
从语法树末端开始,步步向上“归约”,直至根结。
基本思想:用一个寄存符号的先进后出栈,把输入符号一个一个地移进到栈里,当栈顶形成某个产生式的候选式时,即把栈顶的这一部分替换成(归约为)该产生式的左部符号。
归约中,尽可能把更多归约为一个——贪心思想
自下而上分析过程:边输入单词符号(移进符号栈),边归约。
核心问题:识别可归约串
规范归约
令G是一个文法,S是文法的开始符号,假定abd是文法G的一个句型,如果有
则b称是句型abd相对于非终结符A的短语。
如果有AÞb,则称b是句型abd相对于规则A® b的直接短语。
一个句型的最左直接短语称为该句型的句柄。
规范归约是关于α的一个最右推导的逆过程,也称最左归约。
最右推导——规范推导,所得句型为规范句型。
若文法G是无二义的,那么规范推导的逆过程必定是规范归约。
规范归约的实质:在移进过程中,当发现栈顶呈现句柄时就用相应产生式的左部符号进行替换。
栈是语法分析的一种基本数据结构。
#的使用:
(1)在分析开始时,‘#’预先进栈,作为栈底符
(2)作为输入串的结束符
语法分析对符号栈的使用有四类操作:移进,归约,接受,出错处理
算符优先分析法
定义算符之间的优先关系,借助这种关系来寻找“可归约串”和进行归约
1、定义两个终结符‘a’与‘b’的优先关系
(1)a=.b 表示a的优先性等于b
(2)a>.b 表示a的优先性大于b
(3)a<.b 表示a的优先性小于b
注意: =. >. <. 不同于数学上的 =< >
2、算符文法
一个文法,如果它的任一产生式的右部都不含两个相继(并列)的非终结符,即不含如下形式的产生式右部:…QR…,则我们称该文法为算符文法,也称OG文法。
3、终结符之间优先关系的定义
假定G是一个不含e产生式的算符文法。对于任何一对终结符a、b,我们说:
1. a =. b 当且仅当文法G中含有形如P→…ab…或P→…aQb…的产生式;
2. a <. b 当且仅当G中含有形如P→…aR…的产生式,而R b…或R Qb…;
3. a>.b 当且仅当G中含有形如P→…Rb…的产生式,而R …a或R …aQ。
4、算符优先文法
如果一个算符文法G中的任何终结符对(a,b)至多只满足下述三关系之一:
a=.b,a>.b,a<.b,则称G是一个算符优先文法(OPG文法)。
5、构造算符优先关系表
(1)通过检查产生式的每一个候选式可以找出满足a=.b(即P→…ab…或P→…aQb…的产生式)
(2)为了满足<.和>.,需对G中每个非终结符P构造两个集合:
①若有产生式P→a…或P→Qa…,则aÎFIRSTVT(P);
②若aÎFIRSTVT(Q),且有产生式P→Q…,则aÎFIRSTVT(P)。
①若有产生式P→… a或P→… aQ ,则aÎ LASTVT(P);
②若aÎ LASTVT(Q),且有产生式P→… Q ,则aÎ LASTVT(P)。
7、算符优先分析算法
素短语:指一个句型的短语,它至少包括有一个终结符号且除去它本身之外不再含任何更小的素短语。
最左素短语:处在句型最左端那个素短语成为最左素短语。
8、一个算符优先文法G的任何句型的最左素短语是满足如下条件的最左子串Njaj…NiaiNi+1,
aj-1 <. aj
aj =. aj+1,aj+1 =.aj+2,…,ai-1 =. ai
ai >. ai+1
注意:出现在左端或右端的非终结符一定属于这个素短语
9、优先函数
用优先函数f和g,把每个终结符q与两个自然数f(q)与g(q)相对应,使得
若q1 <. q2,则f(q1) < g(q2)
若q1 =. q2,则f(q1) = g(q2)
若q1 >. q2,则f(q1) > g(q2)
f称为入栈优先函数,g称为比较优先函数。
注意:f和g不是唯一的,只要存在一对,就存在无穷多对。
优点:便于比较,节省空间;
缺点:原来不存在优先关系的两个终结符变成可以比较的,要进行一些特殊的判断。
LR分析法的归约过程是规范推导的逆过程,所以LR分析过程是一种规范归约过程
四种不同分析表的构造方法:
LR(0)表构造法
简单LR(SLR)表构造法
规范LR表构造法
向前LR(LALR)表构造法
LR分析器
实质:一个带先进后出存储器(栈)的确定有限状态自动机。
核心:分析表。包括动作表和状态转换表,都是二维数组
(1)动作表:ACTION[s,a]:当状态s面临输入符号a时,应采取什么动作
每一项ACTION[s,a]所规定的四种动作:
(2)状态转换表:GOTO[s,X]:状态s面对文法符号X时,下一状态是什么
一个文法,若能用一个每步至多向前检查K个输入符号的LR分析器进行分析,则文法称为LR(k)文法。一般而言,k=0,1就足够了。
LR(0)项目集族和分析表的构造
1、前缀:该字的任意首部
2、活前缀:规范句型的一个前缀,该前缀不含句柄之后的任何符号(不超过句柄的右端)。
该前缀加上被分析串中未被分析的终结符,就可以构成一个规范句型
只要输入串的已扫描部分可归约成一个活前缀,意味着扫描过的部分没有错误
3、文法G的每一个产生式的右部添加一个圆点称为G的一个LR(0)项目。
特别的,对形如A→ε的产生式,A→·。
文法的全部LR(0)项目将是构造识别它的所有活前缀的有限自动机的基础。
4、构成识别一个文法活前缀的DFA项目集(状态)的全体称为这个文法的LR(0)项目集规范族。
构造识别文法活前缀DFA的两种方法
1、求出文法的所有项目,按一定规则构造识别活前缀的NFA再确定化为DFA。
2、把拓广文法的第一个项目{S′→·S}作为初态集的核,通过求核的闭包和转换函数, 求出LR(0)项目集规范族,再由转换函数建立状态之间的连接关系得到识别活前缀的DFA。
一个项目集可能包含多种项目
A)移进和归约项目同时存在。移进-归约冲突
B)归约和归约项目同时存在。归约-归约冲突
LR(0)项目集规范族不存在移进-归约,或归约-归约冲突,称为LR(0)文法。
SLR 分析表的构造
文法不能满足 LR(0)文法的条件,即其规范族中会有含有冲突的项目集(状态)。
对于有冲突的状态,向前查看一个符号,以确定采用的动作。
总结:
LR(0)
SLR(1):生成的LR(0)项目集如有冲突,则根据非终结符的FOLLOW集决定。
LR(1)、LR(k):项目由心与向前搜索符组成,搜索符长度为1或k。
LALR(1):对LR(1)项目集规范族合并同心集
学第四章的时候感觉第四章已经很难了,到了第五章才发现没有最难只有更难……第五章讲的是语法分析的第二种情况,自下而上分析,即归约。前面部分主要是一些概念,比如短语、句柄的判断,终结符之间优先关系的判断等,这些知识点还是相对简单的,通过做题可以加深印象熟练掌握。后面构造识别文法活前缀DFA的两种方法和前面的章节有很大的联系,课后复习的时候还是回前面吧DFA、NFA的知识又看了一遍才搞明白的。然后就是四种LR分析表的构造问题,这一部分理解起来有点困难,还是要将课本知识反复琢磨并多练习。