编译原理(九)——递归下降法

背景:

  1. 自定向下的语法分析方法,LL(1)是一种非常直观的方法,它的分析过程是按照句子的定义来进行的,也就是说从开始符出发对要分析的串进行推导,如果推导成功就证明这个被分析的串是一个合法的句子,否则的话就有语法错误,但是在推导过程中,对文法进行了一些限定,保证推导过程是唯一的 。
  2. 总体上说,LL(1)就是在选择规则的时候加入了约束条件,考虑到输入流中的第一个符号,以及推导过程中的非终极符的规则选择,只有当头符属于当前Vn为左部的某条规则的Predict 集的时候,才使用该规则进行推导,否则即错。对规则的限定就是说规则要唯一,所以P集交集为空。
  3. 构造语法分析器的方法也很简单,分成输入流、分析栈、LL(1)分析表、驱动程序四个部分,构造表的目的是提高分析器的效率,驱动程序中的动作无非4个——替换、查找、成功、失败。这样就把结构用程序描述出来了,得到语法分析器。

递归下降法是另一种自顶向下的语法分析方法

一、递归下降法的基本原理

编译原理(九)——递归下降法_第1张图片
先不考虑左递归的问题,在定义语法分析程序的时候,每一个非终极符都定义成一个过程或者函数:

  1. 每棵子树都是以根节点的非终极符推导出来的短语
  2. 可以考虑每个非终极符构造一个函数,去匹配子树的叶节点
    从树中即可看出,加入每一个非终极符都定义成一个过程或者是函数,选择一个规则的时候就让它和规则的右边进行匹配,遇到终极符就可能直接匹配上了,遇到非终极符还是要调用该非终极符所对应的过程或者是函数
对文法的要求:编译原理(九)——递归下降法_第2张图片

实际上这里就是一个条件:交集为空,因为含有直接左递归的文法一定不满足第二个条件,间接左递归也不行。

二、语法分析程序的构造

编译原理(九)——递归下降法_第3张图片
程序中有一个全局变量token,用来存储输入流的第一个语法符号,分析的时候需要一个一个往里读,token保存当前字符串的第一个字符;遇到非终极符的时候有一个匹配的动作即Match(a),如果满足Match后面的函数的内容可以读取下一个语法符号了。

非终极符的过程或者函数的写法:

编译原理(九)——递归下降法_第4张图片

编译原理(九)——递归下降法_第5张图片


子程序构造方法:

编译原理(九)——递归下降法_第6张图片

  1. 同一个非终极符推导出来的规则写在一个函数中,每个规则的Predict集作为if条件判断中的布尔表达式的一部分(这里也体现了第二条规则的满足,即没有交集);
  2. 对于终极符,直接执行Match部分
  3. 如果当前的X属于空集,则当前执行的语句是空语句

主程序构造方法:

  1. 执行ReadToken();把字符串读入
  2. 执行开始符对应的子程序
  3. 进行终止判断(就是#部分的判断)

编译原理(九)——递归下降法_第7张图片


整体的问题解决方法

编译原理(九)——递归下降法_第8张图片

相关例题:

编译原理(九)——递归下降法_第9张图片
函数部分:

E(){
if token ∈ {i,(}
then{
 T();
 E'();
}
}

E'(){
if token ∈ {+}
then{
 match(+);
 T();
 E'();
}
if token ∈ {#,)}
then skip;
}

T(){
if token ∈ {i,(}
then {
F();
T'();
}
}

T'(){
if token ∈ {*}
then {
match(*);
F();
T'();
}
if token ∈ {+,#,)}
then skip;
}

F(){
if token ∈ {(}
then{
match('(');
E();
match(')');
}
if token ∈ {i}
then match(i);
}

main(){
ReadToken();
E();
if(token=='#')
  return true;
else
  return false;
}

相应语法分析部分:

编译原理(九)——递归下降法_第10张图片

编译原理(九)——递归下降法_第11张图片
子函数部分:

Predict(Z->aBa) :{a}
Predict(B->bB) :{b}
Predict(B->c) :{c}
B没有交集 

Z(){
if token ∈ {a}
then{
match(a);
B();
match(a);
}

B(){
if token ∈ {b}
then{
match(b);
B();
}
if token ∈ {c}
then{
match(c);
}
}

main(){
 ReadToken();
 Z();
 if token == '#'
 then return true;
 else return false;
}

编译原理(九)——递归下降法_第12张图片

三、编译程序的自动生成

编译原理(九)——递归下降法_第13张图片
每个函数的写法规则是唯一的 ,但是文法规则是灵活的,使用固定的规则实现可变的文法。

你可能感兴趣的:(编译原理)