所谓LL1(1)文法是一种预测分析文法。
从文法的开始符号出发,从每一步推导过程中根据当前句型的最左非终结符A和当前输入符号a能够就能够确定出一个产生式。这样就是预测分析文法的工作过程。仔细想这个过程,假设有S -> aBC 和 S->aDE两个产生式,当输入指针指向a的时候,发现两个产生式都是合适的,那么我们应该选择那个产生式呢?这就是预测分析文法会面临的问题,这个就涉及到我们所说的FOLLOW集合等概念了。
LL(1)文法的意思是:L(从左往右输入,每次读入一个非终结符进行推导),L(产生式使用最左推导),1表示每次每一步只需要向前看一个符号就能确定下一步的语法分析动作。那么LL1文法是怎么确定分析动作的唯一性呢?我们首先了解三个概念:
1. FOLLOW集:FOLLOW(A)表示非终结符A的后继符号集。意思是在某个句型中能够紧跟在A后边的终结符a的集合。定义如下:
是不是感觉有点抽象?我们举个例子:
比如上面的文法S。我们看B:B有三个产生式分别是(2)(3)(4),从(1)我们可以按照FOLLOW的定义推导出来S => aBC => aB(a|c) 所以从定义的角度,我们就可以确定,ac是B的follow集合的元素了。所以,当我们要推导B的时候,当输入是b和d的时候我们能够分别确定是产生式(2)(3),当输入是ac的时候,我们就知道只能用(4)了。
2. SELECT产生式的可选集SELECT。 产生式的可选集表示的是可以选用该产生式进行推导的对应的输入符号的集合,记为SELECT(A->β)。
这个相对来说好理解一下,比如SELECT(A -> aβ) = {a}这是因为对于这个产生式,当当前输入符号为a的时候,可以用这个产生式来进行推导。
3. 串首非终结符集合FIRST.
给定一个文法符号穿α,α的串首终结符FIRST(α)定义为可以从α推导出的所有串首终结符构成的集合。如果α能推导出空串,那么空也被记为FIRST(α)中。
有了上面的概念,我们就可以定义LL1文法了:
看起来很复杂,我们来解释一下:
(2)α和β至多能有一个推导出空串。因为如果α和β都包括空串,那么对于SELECT(A->α)和SELECT(A->β)中就都包含了FOLLOW(A)中的元素。也就是两个的SELECT集合是相交的。这样不符合唯一性,因为这样会导致多个可选的终结符。
(3)条件,为什么FIRST(α)和FOLLOW(A)交集是空呢?因为如果β能推导出空串,那么SELECT(β)就包含FOLLOW(A)中的元素了。如果FIRST(α)和FOLLOW(A)有交集,那么SELECT(A->α)和SELECT(A->β)就会有交集。这样同样不符合唯一性。下面一个条件同理。
其实上面的所有条件,就是为了保证同一个产生式的可选集SELECT不相交。这样就可以保证对于推导过程中的任何一个非终结符,都有唯一对应的非终结符。这样就可以为LL1文法构造分析器。