概述
上一节已经讲到了上下文无关文法以及一些基础定义。本节我们讨论上下文无关文法中的 自上而下分析法。
自上而下分析法
语法的分为两种,一种是自上而下分析法和自下而上分析法,区分的主要依据是语法分析树构造的过程不同。
计算机如何构造语法分析树的?
本质上来说,是试探性的字符串匹配过程。先取下一个字符,看是否能和正规式匹配,如果匹配,就用终结符替换,不匹配,就回溯,重新匹配,直到没有非终结符为止。如果直到最后都无法全部替换,那么说明输入错误。
由于字符串是从左到右匹配的,就有可能发生左递归的情况。
匹配串的时候,有很大可能第一步成功匹配,而第二步没有匹配成功的情况,这时候就要进行回溯。即 返回到上一级,重新匹配。
因此,自上而下分析法有很大的问题存在:
消除左递归
简单来说,消除左递归,就是要消除P=》Pa。理解文法所定义的句型,然后用另一种表示来表示句型。
以上被称为 直接左递归,还有如下的间接左递归:
消除间接递归,简单来讲,就是把间接左递归写成直接左递归,然后再消除直接左递归
消除回溯,提公因子
就是说,我输入一个a,那么以a开头的有且只有一个,我只能匹配这个,再来一个b那么我就a开头第二个是b的。终结符是唯一的,而非终结符能匹配的范围比较大。回溯主要是针对非终结符。
由此引出了新的语法函数:
FIRST集合计算方法
看起来很复杂,简单来解释。就是说,如果关于X的推导,第一个字符是终结符,那么可以确定的说,这个终结符在X的FIRST集合中。
如果说X的第一个终结符为空,即ε,那么,ε也属于X的FIRST集合。
最麻烦的就是非终结符,如果X推导中,第一个字符是非终结符(假设是Y)(或者第一个非终结符为空),那么Y的第一个终结符,也属于X的FIRST集合(或者非终结符的FIRST集合中有ε,那么它接着的终结符,或非终结符的第一个终结符表示,也在X的FIRST集合中)。
举例说明
对于A B没有争议,对于S,S的FIRST集合来自于A、B,所以是A∪B。
如果A的FIRST集合中有ε,那么S的FIRST集合还包含p。为空,就假设这个字符不存在。
此外,为了消除回溯,还得有进一步的限制:
就是说,每个FIRST集合都是不同的,这样的话,匹配就不会出现有两个匹配都能匹配的情况。
如何保证同一非终结符的首符集不相交?
提取公共左因子:(就如同数学中,提公因式一样的思想)
思想就是提取公因式,所以,只要会数学中,提取公因式的方法,这里同样适用。
LL(1)分析法
这里有了新的概念FOLLOW集合,其实明白了FIRST集合的概念,FOLLOW集合的概念也能明白。(就是求起来比较麻烦)
解释起来,就是跟着的终结符或#(引用#是为了判断,存在ε的时候,什么时候用ε来匹配字符串。)
举个例子
求得FIRST集合如下:
找FOLLOW集合主要看推导式的右半部分。
对于E来说,跟在E后面的,是 ),没有其他(只有F的推导式中存在E,其他推到式都没有E),再加上E是开始符,所以E的FOLLOW集合
再看E’,E‘总是最后一个,应当有#,而且,E’是E的最后一个,也就是说,E的FOLLOW集合,也是E’的FOLLOW集合。(因为把E展开得到TE’,就意味着跟在E后面的字符等同于跟在E’后面)
后面的依旧按照这样的方法,可以得到T、T’、F的FOLLOW集合。
自此,对于这个例子的FIRST集合和FOLLOW集合都得到了,也知道了LL(1)分析法。
在此得出这个例子的LL(1)分析表
怎么构造,先给出方法
M[A,a],指的是,A和a所对应的单元格(A行a列)。
先把First集合加在对应的位置上,(FIRST(E)={ ),i },所以在 )和 i 都有E的推导式)。如果出现③的情况,就是在b输入时,A推到为ε
对LL(1)文法进行无回溯的自上而下分析
自上而下分析,就是自上而下构建语法分析树。
例子:
按照输出,构建分析树。