语法分析器实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
语法分析器实验报告
一、实验内容
编写一个语法分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
利用编程语言实现语法分析程序,并对简单语言进行语法分析。
1.待分析的简单语言的语法
用扩充的BNF表示如下:
⑴<程序>::=begin<语句串>end
⑵<语句串>::=<语句>{;<语句>}
⑶<语句>::=<赋值语句>
⑷<赋值语句>::=ID:=<表达式>
⑸<表达式>::=<项>{+<项> | -<项>}
⑹<项>::=<因子>{*<因子> | /<因子>
⑺<因子>::=ID | NUM | (<表达式>)
2.实验要求说明
输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。
例如:
输入begin a:=9; x:=2*3; b:=a+x end #
输出success!
输入x:=a+b*c end #
输出error
测试以上输入的分析,并完成实验报告。
二、实验设计和实现
语法分析程序的算法思想:
(1)主程序示意图如图1-1所示。
图1-1 语法分析主程序示意图
(2)递归下降分析程序示意图如图1-2所示。
(3)语句串分析过程示意图如图1-3所示。
图1-3 语句串分析示意图
图1-2 递归下降分析程序示意图
(4)statement 语句分析程序流程如图1-4、1-5、1-6、1-7所示。
图1-4 statement语句分析函数示意图图1-5 expression表达式分析函数示意图
图1-7 factor分析过程示意图
程序首先定义全局变量,指针,数组:
char prog[100],token[8],ch;
char *rwtab[6]={"begin","if","then","while","do","end"};//关键字
int syn,kk,p,m,n,sum;//p是缓冲区prog的指针,m是token的指针
然后声明下面几个函数来实现:
void scaner();//词法分析算法
void lrparser();//递归下降分析
void yucu();//语句串分析
void statement();//表达式分析
void expression();//表达式运算分析
void term();//运算符分析
void factor(); //因子分析
最后:
主函数调用scaner函数和lrprarser函数进行语法分析。
三、实验结果与分析
主函数:
int main()
{
//置初值
p=0;
kk=0;
printf("input string:\n");
do
{
ch=getchar(); //读入源程序字符串
prog[p++]=ch;//送到缓冲区
}
while(ch!='#');//不读到“#”时,将字符串存到缓冲区prog中
p=0; //重置p重新读入字符串
scaner(); //读下一个二元式
lrparser();//递归下降分析
printf(“\n”);
return 0;
}
scaner函数:
void scaner()//词法分析算法
{
int i,j;
for(i=0;i<8;i++)//初始化
{
token[i]=NULL;
}
m=0;
ch=prog[p++];//读下一个字符
while(ch==' ')
{
ch=prog[p++];
}
if((ch<='z'&&ch>='a')||(ch<='Z'&&ch>='A') )//ch是字母
{
while((ch<='z'&&ch>='a')||(ch<='Z'&&ch> ='A')||(ch<='9'&&ch>='0'))
{
token[m++]=ch;
ch=prog[p++];
}
token[m++]='\0';
ch=prog[--p];//回退一个字符
syn=10;
for(j=0;j<6;j++)//关键字进行匹配
{
if(strcmp(token,rwtab[j])==0)
{
syn=j+1;
break;
}
}
}
else
{
if(ch<='9'&&ch>='0')//ch为数字字符
{
sum=0;
while(ch<='9'&&ch>='0')
{
sum=sum*10+ch-'0';
ch=prog[p++];
}
ch=prog[--p];
syn=11;
}
else
{
switch(ch)//其他运算符和界符
{
case '<':
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21;
token[m++]=ch;
}
else
{
if(ch=='=')
{
syn=22;
token[m++]=ch;
}
else
{
syn=20;
ch=prog[--p];
}
}
break;
case '>':
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=24;
token[m++]=ch;
}
else
{
syn=23;
ch=prog[--p];
}
break;
case ':':
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=18;
token[m++]=ch;
}
else
{
syn=17;
ch=prog[--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=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:
syn=-1;
}
}
}
}
lrparser函数:
void lrparser()//递归下降分析
{
if(syn==1)//从begin开始
{
scaner();//读下一个二元式
yucu();//语句串分析
if(syn==6)//遇到end
scaner();//读下一个二元式
if(syn==0&&kk==0)//end后跟#
{
printf("success\n");//打印分析成功
}
}
else //不end
{
if(kk!=1)
{
printf("error\n");//报错
}
kk=1;
}
}//不以begin开头
else
{
printf("error\n");//报错
kk=1;
}
}
yucu函数:
void yucu()//语句串分析
{
statement();//表达式分析
while(syn==26)//遇到;时
{
scaner();//读下一个二元式
statement();//表达式分析
}
}
statement函数:
void statement()//表达式分析
{
if(syn==10)//ID
{
scaner();//读下一个二元式
if(syn==18)//:=
{
scaner();//读下一个二元式
expression();//表达式运算分析
}
{
printf("error\n");
kk=1;
}
}
else
{
printf("error\n");
kk=1;
}
}
expession函数:
void expression()//表达式运算分析
{
term();//运算符分析
while(syn==13||syn==14)//+或者-
{
scaner();//读下一个二元式
term();//运算符分析
}
}
term函数:
void term()//运算符分析
{
factor();//因子分析
while(syn==15||syn==16)//*或者/
{
scaner();//读下一个二元式
factor();//因子分析
}
}
factor函数:
void factor()//因子分析
{
if(syn==10||syn==11)//ID或者NUM
{
scaner();//读下一个二元式}
else if(syn==27)//(
{
scaner();//读下一个二元式
expression();//表达式运算分析
if(syn==28)//)
scaner();//读下一个二元式
}
else
{
printf("error\n");
kk=1;
}
}
else
{
printf("error\n");
kk=1;
}
}
运行结果:
四、实验总结和体会
经过本次的实验,使我真正的了解语法分析器的实现过程,让我更加深刻的语法分析器的实现原理,虽然在本次试验中遇到了各种各样的困难和错误,但在同学的帮助下还是把错误改正过来了,使语法分析器能够正确的识别相应的语法和表达式。