语法分析-递归下降分析法
实验2-1 语法分析—递归下降法
一、实验目的
通过本实验,掌握自上而下语法分析的要求和特点,以及递归下降分析的原理和过程。调试一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
二、实验内容
利用C语言完善递归下降分析程序,并对简单语言进行语法分析。
1、要点回顾
标识符ID=letter(letter| digit)* 整型常数NUM=digit digit *
2、待分析的简单语言的语法
用扩充的BNF表示如下: (1)::=beginend (2)::={;} (3)::= (4)::=ID:= (5)::={+|-} (6)::={*|/} (7)::=ID| NUM|()
3、实验要求说明
输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。
三、完整源程序代码
#include #include #include using namespace std;
char prog[80];//缓冲区
int p=0;//缓冲区prog的指针
char token[8];//单词
int m=0;//单词token的指针
char ch;//需要分析的字符
int syn=0;//单词的种别码
int sum=0;//计算整数
int n=0;//计数器 int kk=0;
char *rwtab[6]={"begin","if","then","while","do","end"};//关键字
void scaner();//扫描函数 void factor();//因子 void term();//项
void expression();//表达式 void statement();//语句 void yucu();//语句串
void lrparser();//语法分析
//扫描函数 void scaner() { for(n=0;n
ch=prog[p++];
while(ch==' ') { ch=prog[p++];//过滤空格。(也可用do„„while) }
if((ch>='A'&&ch='a'&&ch='A'&&ch='a'&&ch='0'&&ch
token[m++]='\0';//结束符 p--;//指针归位 syn=10;//假定是变量
for (n=0;n='0'&&ch='0'&&ch
switch (ch) { case'>' : m=0; token[m++]=ch; ch=prog[p++]; if (ch=='=') { syn=24;//是">=" token[m++]=ch;//将"="存入单词 } else { syn=23;//是">" p--;//指针归位 } break;
case'') { syn=21;//是"" token[m++]=ch;//将">"存入单词 } else { if (ch=='=') { syn=22;//是"
token[m++]=ch; ch=prog[p++]; if (ch=='=') { syn=18; token[m++]=ch; } else { syn=17; p--; }
break;
case'-': syn=13; token[0]=ch; break; case'+': syn=14; token[0]=ch; break; case'*': syn=15; token[0]=ch; break; case'/': syn=16; token[0]=ch; break; case';': syn=26; token[0]=ch; break; case'(': syn=28; token[0]=ch; break;
case')': syn=27; token[0]=ch; break; case'#': syn=0; token[0]=ch; break; default:syn=-1; } }
//因子
void factor()
{//问题---补充程序代码 if(syn==11||syn==10)//当扫描的是数字或字母时,继续扫描 { scaner(); } else if(syn==28) //当扫描的'('时,继续扫描 { scaner(); expression(); if(syn==27) //当扫描的是')'时,继续扫描 scaner(); else { cout
void term()
factor(); //问题---补充判断条件 while(syn==15 || syn==16)//当开头扫描的是'*'或'/'时,继续扫描 { scaner(); factor(); } return; }
//表达式
void expression() { //问题---补充程序代码 term(); while(syn==14 || syn==13)//当开头扫描的是'+'或'-'时,继续扫描 { scaner(); term(); } return; }
//语句
void statement() { //问题---补充判断条件 if(syn==10) //当开头扫描的是字母时,继续扫描 { scaner(); if(syn==18)//赋值 { scaner();//问题---补充执行语句 expression(); } else { cout
cout
//语句串 void yucu() { statement(); while(syn==26)//";" { scaner(); statement(); } }
//语法分析 void lrparser() { if(syn==1)//begin { scaner(); yucu(); if(syn==6)//end { scaner(); //问题---补充判断条件 if(syn==0 && kk==0)//当串最后扫描的是'#',而且并无出错,分析成功 cout
int main() { //接收用户输入 p=0; cout>ch; //不认识空格,当不存在 prog[p++]=ch; } while (ch!='#'); //当遇到'#',结束输入 cout
四、结果验证
(1)输入:begin_a:=9; x:=2*3; b:=a+x end#
输出:
success!
(2)输入:x:=9;if x>0 then x:=2*x+1/3;end# 输出:缺begin错误
!
(3)输入:begin x:=10;x:=x-3;a:=a+x*7 # 输出:缺end错误
!
(4)输入:begin x=x+1;m9;end#
输出:缺:=错误
!
(5)输入:begin x:=x*7;m:=m+(x*7;end#
输出:错误,表达式缺乏‘)’
五、收获(体会)
由于已经有实验一的基础,看懂程序没有很大问题。在填写补充内容时,必须要注意细节问题,稍有不慎,在运行时便会出各种很奇怪的问题。这次的补充内容是环环相扣的,错了前面的一个,后面的一个也不会正确。必须要弄清楚什么是因子、项、表达式等。
通过这次实验,我加深了自己对语法组成的理解,对于递归下降分析方法更加的得心应手了。
吴雨霜
1108140222
计算机111班