类似于词法分析, 语法分析也可以有自动生成器, 之前讨论了递归下降的分析算法(适用于手撸词法分析器), 接下来几节来研究生成器生成分析器的内部实现原理... 还是自顶向下, 先看第一类...

接下来是结合具体的分析表进行分析 ... (其实我在这边也是疑问有点多啊 ... 也不知道这表是怎么生成的, 但是先忍着吧, 到后面应该会懂)

表驱动的具体过程就是, 比如刚开始先取出一个token(这里是g), 然后结合状态S和g 在表中找到了状态0, 然后popS再压入CFG的第0列的右部(这就是所谓的压入正确的右部而不是下一个, 因为在这里有表做指导, 然后在继续结合N和g找到CFG的第3列, 然后抛出N1, 因为是最左推导所以是先N1, 不懂的可以看我之前的文章, 抛出N1之后, 放入g, 然后再循环得出token == 栈顶元素g, i++完成第一个token的分析, 具体就是这样...)

 

在接着往下看之前先提出一个概念, 叫做first集合...

这又是一个不动点算法, 那么它为什么会终止 ?  感觉上确实是会终止的, 但是解释确实不太好解释(数学水平有限), 希望有读者能解释一波...

其实你会发现我在上面提出的问题已经在这里在概念上得到了解决, 因为事实上生成LL1分析表的过程就是在求该CFG的first集...

但此时似乎有点过于乐观了...我们并没有考虑到这种冲突的情况, 然后还有对于冲突的检测 : 我感觉这里说的太不准确了, 我感觉准确来讲应该是 : 对于任何同一非终结符的产生式规则, 都不应该出现其中两条规则的first集相交不为空, 若出现, 则发生冲突...

 

同时还有另外一个问题, 上面求解空集的方式似乎有点漏洞, 当非终结符可以推出空的时候, 那么上面的算法显然是不严密的.

在提出更加严密的算法之前, 再提出一个概念... Nullable ---> 如果一个非终结符A是Nullable的话, 有两种情况 :

1. A -> ε 

2. A -> BCDE... (其中BCDE...都表示非终结符, 并且这些非终结符都是Nullable的时候)

下面给出了Nullable的求解算法 :

这同样是一个不动点算法, 但是至于为什么会停止... 这个应该是很简单, 最差的情况, 所有的非终结符都是nullable, 那么当所有的非终结符都被加入Nullable之后, 循环结束, 或者说在之前某一轮就开始停止变化, 循环同样结束. 两种情况下, 由于非终结符是有限的, 那么肯定会结束. 我感觉这个算法要思考的并不是这个地方, 而是为什么nullable没有变化就可以判断循环结束, 这个问题如果是单从结束的角度讲, 很好理解, 既然这次没有变化, 那么下次给出同样的结果当然还是没变化, 这时候不跳出循环就要无限循环了... 但是从正确性的角度想, 为什么结束的时候所有的nullable的非终结符都已经被算出来了呢 ? 我是这样想的, 对于直接能推出nullable的非终结符(也就是 X ->  ε 的情况, 只要存在非终结符, 就必须要存在这种情况...) 我称之为nullable1, 在第一次循环之后, 所有的nullable1 都已经在nullable中, 再次循环, 所有包括nullable1的非终结符Nullable2都必须在nullable中, 如果此时并不存在这样的Nullable2, 由于nullable的非终结符无外乎两种情况, 第一种已经在nullable1中了, 第二种如果存在的话, 必定是由在nullable1中的非终结符组成的, 既然不存在这样的情况, 同时由于文法规则的推导方向是向简推导的(就是说任何一条文法规则推导到后面都是越来越多的终结符在里面, 但具体原因这里因为涉及到文法的递归实在是说不清...), 那么既然没有nullable2, 就不可能存在又nullable2组成的nullable3...

 

posted on 2016-05-15 21:27  内脏坏了  阅读(245)  评论(0编辑  收藏  举报