预测分析表
对于LL(1)文法来说,在使用最左推导时,非终结符号的每一步推导使用的产生式是确定的,不用进行试探和回溯。
预测分析表的作用:
有一个进行语法分析的输入串,开始符号经过最左推导最终与输入串匹配。在匹配过程中,非终结符号需要进行下一步推导时,会根据当前需要匹配的终结符号选择确定的一个产生式。f(需要推导的非终结符号,需要匹配的终结符号)→确定的一个产生式
这样的映射关系所组成的矩阵,就是预测分析表。
1.预测分析表中要填什么?
经过上面的介绍,预测分析表中的每一个格子填入一个产生式,这样推到的时候就不会有“第二个”选择
非ε产生式应该填在哪里?
有这样一个产生式A→α
,对于矩形中的非终结符号A来说,使用产生式A→α
会推出一个句子,这个句子的第一个终结符号属于FIRST(α)。
如果当前需要推导的非终结符号是A,使用A→α
产生式最终会推导出FIRST(α)中的终结符号;反过来分析一下,首先有一个前提,文法是LL(1)文法,对非终结符A进行推导后,得到了FIRST(α)中的终结符号,则一定使用了产生式A→α
如图所示,通过A推导出FIRST(α)中的符号,经过了唯一的路径A→α
,因此,如果给定A和FIRST(α),可以找到唯一的路径A→α
。经过归纳,给定一个非终结符号A,给定A可以推导出的终结符号,有且只有一条路径(产生式)。
上面BB了这么多,应该很容易想到,非ε产生式A→α
是非终结A到FIRST(α)的路径,因此,如果当前推导的符号是A,当前需要匹配的终结符号属于FIRST(α),使用的产生式就是A→α
。FIRST(α)中的每一个终结符号a,表格项M(A,a)=A→α
空串产生式应该填在哪里?
有空串产生式A→ε
,在进行推导过程中,如果使用该产生式进行推导,非终结符号A推导出的句子的第一个终结符号在FOLLOW(A)
中。A→ε
是非终结符号A到FOLLOW(A)的一条路径。
因此,如果给定A和FOLLOW(A)中的符号,可以通过路径A→α
。
如果当前推到的非终结符号是A,需要匹配的终结符号是FOLLOW(A)中的元素,则非终结符A使用了ε产生式推导。FOLLOW(A)中的每一个终结符号b,表格项M(A,b)=A→ε
2.构建一个预测分析表
给定一个LL(1)文法
考察每一个产生式如果是非空串产生式A→α,求FIRST(α),对于FIRST(α)中的每一个终结符号a,M(A,a)=A→α
如果是空串产生式A→α,求FOLLOW(A),对于FOLLOW(A)中的每一个终结符号b,M(A,B)=A→ε
3.错误条目
将产生式填入表之后,会发现,表不会被填满,有很多空白条目
。
空白条目表示:当前正在推到的非终结符A,没有产生式可以推导出当前要匹配的终结符号,所以,空白条目表示出错。
4.举个例子
有如下LL(1)文法,请构造它的预测分析表。
逐个分析产生式:
E→TE'
:因为是非空串产生式,所以,求FIRST(TE’)-{ε}={(,i}
M(E,()=M(E,i)=E→TE
E'→+TE'
:因为是飞空串产生式,所以,求FIRST(+TE’)-{ε}={+}
M(E’,+)=E’→+TE’
E'→ε
:因为是空串产生式,所以求FOLLOW(E’)={#,)}
M(E’,#)=M(E’,))=E’→ε
T→FT'
:因为是非空串产生式,所以求FIRST(FT’)-{ε}={(,i}
M(T,()=M(T,i)=T→FT’
T'→*FT'
:FIRST(*FT’)-{ε}={*}
M(T’,*)=T’→*FT
T'→ε
:FOLLOW(T’)={#,+,)}
求FOLLOW(T’)的过程可能比较混乱,可以借用一张草稿纸上的图来使结构明确
M(T’,#)=M(T’,+)=M(T’,))=T’→ε
F→(E)
:FIRST((E))={(}
M(F,()=F→(E)
F→i
:FIRST(i)=i
M(F,i)=F→i
综上,可以画出一个二维的矩阵: