2024年5月25日发(作者:)

一、实验目的:

根据某一文法编制调试递归下降分析程序,以便对任意输入的符号串进行分

析.本次实验的目的主要是加深对递归下降分析法的理解.

二、程序算法描述

这次的实习主要是根据以下文法实现一个递归下降分析器,依据文法如下:

(1)E—>TG

(2)G—〉+TG|-TG|ε

(3)T-〉FS

(4)S—〉*FS|/FS|ε

(5)F—>(E)|i

在这个递归下降分析器程序中每一个非终结符E、G、T、S和F构造相应的

递归函数,函数的名字表示文法左部的非终结符,函数中就是按文法中每个非终

结符右部的候选式依次进行匹配,根据对输入串的分析如果非终结符可以用其中

的一个候选式替代就返回1,否则返回0。因为该文法中有五个非终结符,所以

定义了五个函数,分别为E(),G(),T(),S()和F()。当输入一串字符串后,

就对该字符串进行分析,首先从开始符号分析,所以首先调用E()函数,在E()

函数中会调用T()和G(),就是每个非终结符的候选式中出现了哪个非终结符就

调用哪个函数。所以,将字符串的第一个字符和E中的每个候选式匹配,如果成

功就匹配输入字符串的下一个字符,当最后剩下的字符为'#’时,匹配成功。其

实这个工程就是构造一个语法树。

程序总流程图如下:

图1 程序总流程图

三、关键性代码

这个工程的主要工作用五个非终结符生成的句子是否和输入字符串匹配,所

以主要的工作是函数E(),G(),T(),S()和F()的编写。

1. 对非终结符E处理的函数E()

这个函数主要是根据文法中的E-〉TG,在E()中调用了T()和G()来进行递归

分析,这个就是构造生成树的一个分支。

int E()

{ int f,t;//变量

printf(”E—-〉TGt");//输出根据的文法

flag=1;

outDeduce ();//输出字符串

outputRemain ();//输出剩余字符

f=T();

if (f==0) return(0);

//表示当前分析字符可由非终结符T推导出

t=G();

if (t==0) return(0);

//表示当前分析字符可由非终结符G推导出

else return(1);

2. 对非终结符G处理的函数G()

这个函数主要是根据文法中G—>+TG|-TG|ε,在函数中调用了T()和G()

函数。将当前字符和候选式的第一个字符进行匹配,如果匹配成功,就调用该候

选式中涉及到得第一个非终结符对应的函数,一次递归嵌套调用。如果不是由第

一个候选式推出然后依次匹配剩下的候选式。

int G()

{ int f;

if(ch=='+’) {//当前字符式‘+’

b[i1]=ch;

printf(”G-—>+TGt");//说明用的是第一个候选式

e[0]=’G';

e[1]=’=’;

e[2]=’>’;

e[3]=’+';

e[4]=’T’;

e[5]='G';

e[6]=’#';

Compute ();//计算推导式

flag=0;

outDeduce ();//输出字符串

outputRemain ();//输出剩余字符

ch=a[++i1];//读取当前字符的下一个字符

if (f==0) return(0);

//表示当前分析字符可由非终结符T推导出

t=G();

if (t==0) return(0); //表示当前分析字符可由非终结符G推导出

if(ch=='-') {//当前字符是‘—’

b[i1]=ch;

printf("G-->+TGt”);//说明用的是第二个候选式

e[0]='G';

e[1]='=';

e[2]=’>';

e[3]=’+’;

e[4]='T';

e[5]=’G';

e[6]='#’;

Compute();//输出推导式

flag=0;

outDeduce ();//输出字符串

outputRemain ();//输出剩余字符

ch=a[++i1];//读取当前字符的下一个字符

f=T();

if (f==0) return(0); //表示当前分析字符可由非终结符T推导出

G();//判断当前分析字符是否是非终结符G的一个产生式

return(1);