例 文法
S → aCb C
cd | c
为输入串w = acb建立分析树
不能处理左递归的例子
不能处理左递归、复杂的回溯技术、回溯导致语义工作推倒重来、难以报告出错的确切位置、效率低
对文法加什么样的限制可以保证没有回溯?
先定义两个和文法有关的函数
LL(1)文法定义
LL(1)文法有一些明显的性质
查找非终结符的First集
Step 1. 按产生式顺序来,从开始符找起;
Step 2. 如果右部的串首为终结符,则直接将该终结符填入左部非终结符的First集中;
Step 3. 如果右部的串首为非终结符,则左部非终结符的First集等价于串首非终结符的First集。因而,需要利用Step 2和Step 3继续寻找串首非终结符的First集。
查找非终结符的Follow集
Step 1. 按产生式顺序来,从开始符找起(开始符的Follow集必定包含$);
**Step 2. **从所有产生式右部寻找目标非终结符,若其后紧跟终结符,则将终结符填入目标非终结符的Follow集。特别地,若其后紧跟$,则目标非终结符的Follow集等价于产生式左部非终结符的Follow集。
Step 3. 从所有产生式右部寻找目标非终结符,若其后紧跟非终结符,则将该非终结符的First集元素填入目标非终结符的Follow集。特别地,若该非终结符的First集元素中包含?,则需针对?情况时做特殊处理,即目标非终结符的Follow集等价于产生式左部非终结符的Follow集。
一个辅助过程
void match (terminal t) {
if (lookahead == t) lookahead = nextToken( );
else error( );
}
void type( ) {
if ( (lookahead == integer) || (lookahead == char) ||
(lookahead == num) )
simple( );
else if ( lookahead == ??? ) { match(???); match(id);}
else if (lookahead == array) {
match(array); match( ?[? ); simple( );
match( ?]? ); match(of ); type( );
}
else error( );
}
void simple( ) {
if ( lookahead == integer) match(integer);
else if (lookahead == char) match(char);
else if (lookahead == num) {
match(num); match(dotdot); match(num);
}
else error( );
}
分析表的一部分
预测分析器接受输入id * id + id的前一部分动作
1、先对编译器的错误处理做一个概述
2、分析器对错误处理的基本目标
3、非递归预测分析在什么场合下发现错误
栈顶的终结符和下一个输入符号不匹配
4、非递归预测分析:采用紧急方式的错误恢复
发现错误时,分析器每次抛弃一个输入记号,直到输入记号属于某个指定的同步记号集合为止
5、同步
原文:https://www.cnblogs.com/hardworking-fairy/p/14776149.html