语法分析实验报告
实验目的
编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
二、实验要求
利用C语言编制递归下降分析程序,并对简单语言进行语法分析。
2.1 待分析的简单语言的语法
用扩充的BNF表示如下:
1)<程序>::=begin<语句串>end
2)<语句串>::=<语句>{;<语句>}
3)<语句>::=<赋值语句>
4)<赋值语句>::=ID:=<表达式>
5)<表达式>::=<项>{+<项>| -<项>}
6)<项>::=<因子>{*<因子>| /<因子>
7)<因子>::=ID | NUM |(<表达式>)
2.2 实验要求说明
输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。
例如:
输入 begin a:=9; x:=2*3; b:=a+x end #
输出 语法分析成功
输入 x:=a+b*c end #
输出 语法分析
2.3 语法分析程序的酸法思想
1)主程序示意图如图2-1所示。
图2-1 语法分析主程序示意图
2)递归下降分析程序示意图如图2-2所示。
3)语句串分析过程示意图如图2-3所示。
图2-2递归下降分析程序示意图图2-3 语句串分析示意图
4)statement语句分析程序流程如图2-4、2-5、2-6、2-7所示。
图2-4statement语句分析函数示意图图2-5 expression表达式分析函数示意图
图 2-6term分析函数示意图
图2-7 factor分析过程示意图
三、语法分析程序的C语言程序源代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char prog[100],ch,token[8];
int p=0,syn,n,i;
char *keyword[6]={"begin","then","if","while","do","end"};
void scaner();
void Irparse();
void statement();
void expression_r();
void term();
void factor();
void main()
{
int select=-1;
p=0;
printf("please input sentence, end of '#' !n");
do
{
ch=getchar();
prog[p++]=ch;
}while(ch!='#');
p=0;
printf("请输入1 或 2 n 1.词法分析n2.语法分析n");
scanf("%d",&select);
if(select==1)
{
do
{
scaner();
switch(syn)
{
case -1:printf("词法分析 出错n");break;
default:printf("<%d,%s>n",syn,token);break;
}
}while(syn!=0);
printf("词法分析 成功n");
}
elseif(select==2)
{
scaner();
if(syn==1)
{Irparse();}//begin
else
{printf("语法分析出错! 请检查begin关键字n");return;}
if(syn==6)//end
{
scaner();
if(syn==0)
{
printf("恭喜 语法分析 成功n");
}
else
{printf("语法分析出错! 请检查是否缺少'#'n");}
}
else{printf("语法分析出错! 请检查是否缺少'end'n");}
}
getchar();
}
void scaner()
{
for(n=0;n<8;n++)
{token[n]=' ';}
n=0;
ch=prog[p++];
while(ch==' '){ch=prog[p++];}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
do{
token[n++]=ch;
ch=prog[p++];
}while((ch>='a'&&ch<='z')||(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9'));
syn=10;
for(n=0;n<6;n++)
{if(strcmp(token,keyword[n])==0)
{
sy n=n+1;
}
}
p--;
//return;
}
elseif(ch>='0'&&ch<='9')
{
p--;
do
{
token[n++]=prog[p++];
ch=prog[p];
}while(ch>='0'&&ch<='9');
syn=11;
return;
}
else
{
//ch=prog[p++];
switch(ch)
{
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=17;token[0]=ch;
ch=prog[p++];
if(ch=='='){token[1]=ch;syn++;}
else p--;
break;
case '<':syn=20;token[0]=ch;
ch=prog[p++];
if(ch=='>'){token[1]=ch;syn++;}
else if(ch=='='){token[1]=ch;syn=syn+2;}
else p--;
break;
case '>':syn=23;token[0]=ch;
ch=prog[p++];
if(ch=='='){token[1]=ch;syn++;}
else p--;
break;
case '=':syn=25;token[0]=ch;break;
case ';':syn=26;token[0]=ch;break;
case '(':syn=27;token[0]=ch;break;
case ')':syn=28;token[0]=ch;break;
case '#':syn=0;token[0]=ch;break;
default: printf("词法分析出错! 请检查是否输入非法字符n");syn=-1;break;
}
//return;
}
}
void Irparse()
{
scaner();
statement();
while(syn==26)//;
{
scaner();
statement();
}
}
void statement()
{
if(syn==10)
{
scaner();
if(syn==18)
{
scaner();
expression_r();
}
else
{
printf("语法分析出错! 请检查表达式是否正确n");return;
}
}
else
{
printf("语法分析出错! 请检查语句是否正确n");return;
}
}
void expression_r()
{
term();
while(syn==13||syn==14)//+ -
{
scaner();
term();
}
}
void term()
{
factor();
while(syn==15||syn==16)//* /
{
scaner();
factor();
}
}
void factor()
{
if(syn==10||syn==11)
{
scaner();
}
else if(syn==27)
{
scaner();
expression_r();
if(syn==28)
{
scaner();
}
else {printf("语法分析出错! 请检查是否缺少')'n");return;}
}
else {printf("语法分析出错! 请检查是否输入非法字符n");return;}
}
四、程序测试结果
1)开始调试的界面
2)对源程序begin a:=9; x:=2*3; b:=a+x end #的源文件,经过语法分析后如下图4-1所示:
图 4-1 正确结果输出
3)对源程序x:=a+b*c end #的源文件,经过语法分析后如下图4-2所示:
图 4-2 错误结果输出
五、总结
通过对语法分析程序的设计和编写,使自己获得了很大的收获,并且使自己对语法分析程序的功能有了更进一步认识。虽然在程序的设计和编写过程中出现了一些错误,但是经过同学的帮助和指导,顺利的将程序中存在的错误顺利解决,从而顺利完成了本程序的设计和编