这一篇是补昨天的。 前天发了一个关于求FIRST,FOLLOW集的方法的特辑,但是还有一种没有提到,就是求SELECT集由于SELECT其实就是对前两个的运用,所以没有提到前面去说,这里先补充以下:求SELECT(A->a)就是相当于求FIRST(a)然后如果FIRST(a)中没有空字符串那么SELECT(A->a)=FIRST(a),如果有,那么SELECT(A->a)=FIRST(a)和FOLLOW(A)的并集。下面是一个语法定义举例和分析程序的关系:(我推测出来的,对于不准确的地方后期学习过程中会重新编辑改正)
<program>::=<statement>{statement}"#"
这里我们就知道开头是用了program这个函数,然后program这个函数里面至少有一个statement以"#"作为结尾,中间有0~n个statement
<statement>::=<expression>"\n"
然后statement这个函数里面有一个以"\n"作为结尾的expression
<expression>::=<multiplicative_expression>{"+"<multiplicative_expression>|"-"<multiplicative_expression>}然后这里我们的expression里面有一个以一个multiplicative_expression为开头,0~n个以"+"或"-"加multiplicative_expression为结尾的式子。。。
类似分析所以得出来的递归程序大概就是:
<program>::=<statement>{statement}"#"
while(token!='#')
statement();
<statement>::=<expression>"\n"
if(token!='\n')
expression();
<expression>::=<multiplicative_expression>{"+"<multiplicative_expression>|"-"<multiplicative_expression>}
multiplicative_expression();
while(token=='+'||token=='-')
{
get_token(); //取符号
multiplicative_expression();
}
后面的就不推下去了,其实大同小异。
最后来说一下特殊情况:
如果一个文法中有左递归:A->Ab(这个就是左递归),其中A->a,a,b中有ε、a中没有那么这个时候直接改为:A->bA1,A1->aA1|ε
左公共因子:A->ab|ac这个时候其实等价于A->a(b|c)那么再转换以下就有:A->aA1A1->b|c
为什么要转换?
因为我们写的都是自定向下的分析法,这个方法要求文法必须为LL(1)此时如果出现上面的情况则不是LL(1)文法,所以要进行转换