编译原理之语法分析(一)

我们知道,词法分析的主要目的是分析输入的字符流中的所有字符串是否合法,而接下来语法分析的目的是分析字符流的书写规则是否符合规定的格式。为了对所有表达式进行一般化的处理,在编译原理的理论上提出了文法这个概念,该文法和语言中的文法有很大区别。现在我们重点来讨论LL(1)文法。

在LL(1)文法中引入了两个集合,分别是first集合和follow集合,那为啥要引入这两个集合了,难道引入这概念的人吃多了没事干么(开玩笑),其实不然,为了理解为何引入这个概念,我们先来看下如下文法:

 非终结符S为开始符号。

同时给出acbc输入串,分析该串是否符合该文法的描述。

为了验证输入串是否符合该文法的描述,直观的方式就是直接代入文法中,一条一条的进行匹配。如下所示:

 通过一步一步的不断匹配,可以看到该串确实是符合该文法的描述。

那我们现在开始分析我们的步骤,首先,我们先拿出给定的出入串的第一个字符,该字符为a,发现产生式1能够匹配我们的输入,此时我们得到推导式aBc,依此类推,我们能够匹配我们的字符串。可以看出,我们每次匹配所得到的推导其实是根据文法中右边的第一个终结符是否和输入相等来判断的,因此,我们就可以将这些字符放到一起,这些字符能够引导我们选择文法中的哪个产生式,我们将这些字符的所有集合称之为First集合,很显然上面文法中的first集合为:

那什么是follow集合呢?不知道读者是否留意上面的推导步骤,步骤step2被我用蓝色圈标出,这里有个不同的地方,就是aBSc-->aSc这步,这里加入我们按找之前的方式进行匹配,发现B的first集合中没有b,这样就导致我们的推导失败,很显然该串是符合该文法的,因此是我们的推导不对,但是我们可以从产生式4得出非终结符B可以是空,这样我们可以将非终结符B去掉而变为了aSc,从上面来看貌似好像不需要其他东西,但是对于计算机而言,它并不知道B可以推导空。所以我们这里需要进行特殊处理,对于每个非终结符而言,当遇到first中没有匹配的字符时,我们还不能判断此串就是不符合文法,有点操之过急,还需要进一步判断。可以看到进一步判断就是当非终结符能够推导出空时,此非终结符可以省略,但是我们不能说把他删除了,我们必须找到一个字符与之匹配,很显然对于上面的文法而言,该字符就是b,这个b是由S右边决定的,也就是当非终结符的first集合没有与之匹配的字符时,我们需要找该终结符紧跟后面的一个非终结符或终结符,很显然,如果是终结符,那最好了,可以直接确定此符号就是要找的那个与之匹配的字符,如果是非终结符,则对其终结符进行推导,必然能够找到一个终结符。我们将上面要找的终结符的集合称之为Follow集,这样我们判断输入的字符时先判断是否在first集中,如果是则将此产生式的替代该非终结符,如果不是,则在follow集中进行查找,看是否由匹配的字符,如果有,则直接将该非终结符替代,如果没有,直接输出该输入串不符合定义的文法。

知道了上面的步骤,我们很容易来实现上面的分析过程,实现方法很多,但基本思想都是一致的,下面我们使用二维数组的方式实现该过程,

后续更新(时间太紧了,抱歉)

猜你喜欢

转载自www.cnblogs.com/listenscience/p/11935926.html