语法分析实验报告.docx
- 文档编号:30253015
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:17
- 大小:101.11KB
语法分析实验报告.docx
《语法分析实验报告.docx》由会员分享,可在线阅读,更多相关《语法分析实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
语法分析实验报告
编译原理实验报告
题目:
语法分析器
班级:
04计算机3班
姓名:
林世昌
学号:
2004374314
实验内容:
设计并实现一个C语言的的小型语法分析程序,要求能够分析简单说明语句、赋值语句、条件语句、循环语句。
设计要求:
要给出所分析语法结构的上下文无关文法描述,以及所采用的分析方法的算法及步骤的详细描述。
实验分析:
1)程序实现的功能是:
输入一个完整的程序源码进行语法分析,如何程序没有语法上的错误,则成功,反之则错误,对于待分析的输入源码可以包含有说明语句,赋值语句,条件语句和循环语句。
2)单词符号对应的种别码
这个主要应用在扫描子程序上,与词法分析类似
单词符号
Syn
单词符号
Syn
单词符号
Syn
变量
10
<
21
/
15
数字
11
<=
22
{
16
Main
30
>
23
}
17
Int
31
>=
24
(
18
If
32
=
25
)
19
Else
33
==
26
1
While
34
+
12
;
2
Do
35
-
13
#
0
Char
36
*
14
其他
-1
3)程序的结构和算法思想流程图
递归下降分析程序lrparser()示意图语句串分析函数yucu()
程序源码:
#include"stdio.h"
#include"string.h"
#include"iostream.h"
#include"stdlib.h"
intkk=0;
charprog[80],token[10];
charch;
intsyn,p,m,n,sum;
intfactor();
intterm();
intexpression();
intStatement_Block();
voidnextchar()
{
ch=prog[p];
p++;
}
voidback_one()
{
p--;
ch=prog[p];
}
intreserve(charc[])
{
if(strcmp(token,"main")==0)return1;
if(strcmp(token,"if")==0)return3;
if(strcmp(token,"int")==0)return4;
if(strcmp(token,"while")==0)return6;
if(strcmp(token,"for")==0)return7;
if(strcmp(token,"char")==0)return2;
if(strcmp(token,"else")==0)return5;
return10;
}
voidlex_scanner()
{
for(n=0;n<8;n++)
token[n]=NULL;
nextchar();//读下一个字符;
while(ch=='')
nextchar();
if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z'))
{
m=0;
while((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9'))
{
token[m++]=ch;
nextchar();
}
token[m++]='\0';
back_one();
syn=reserve(token);
}
else
{
if((ch>='0'&&ch<='9'))
{
sum=0;
while((ch>='0'&&ch<='9'))
{
sum=sum*10+ch-'0';
nextchar();
}
back_one();
syn=11;
}
else
switch(ch)
{
case'<':
m=0;
token[m++]=ch;
nextchar();
if(ch=='>')
{
syn=18;
token[m++]=ch;
token[m]='\0';
}
elseif(ch=='=')
{
syn=17;
token[m++]=ch;
token[m]='\0';
}
else
{syn=19;token[m]='\0';back_one();}
break;
case'>':
m=0;
token[m++]=ch;
nextchar();
if(ch=='=')
{
syn=20;
token[m++]=ch;
token[m]='\0';
}
else
{syn=23;token[m]='\0';back_one();}
break;
case':
':
m=0;
token[m++]=ch;
nextchar();
if(ch=='=')
{
syn=22;
token[m++]=ch;
token[m]='\0';
}
else
{syn=21;token[m]='\0';back_one();}
break;
case'=':
m=0;
token[m++]=ch;
nextchar();
if(ch=='=')
{
syn=44;
token[m++]=ch;
token[m]='\0';
}
else
{syn=12;token[m]='\0';back_one();}
break;
case'+':
syn=13;token[0]=ch;token[m]='\0';break;
case'-':
syn=14;token[0]=ch;break;
case'*':
m=0;
token[m++]=ch;
nextchar();
if(ch=='/')
{
syn=50;
token[m++]=ch;
token[m]='\0';
}
else
{syn=15;token[m]='\0';back_one();}
break;
case'/':
m=0;
token[m++]=ch;
nextchar();
if(ch=='*')
{
syn=51;
token[m++]=ch;
token[m]='\0';
}
else
{syn=16;token[m]='\0';back_one();}
break;
case'\n':
syn=24;token[0]='\n';break;
case';':
syn=26;token[0]=';';break;
case'"':
syn=27;token[0]='"';break;
case'?
':
syn=28;token[0]='?
';break;
case'!
':
m=0;
token[m++]=ch;
nextchar();
if(ch=='=')
{
syn=60;
token[m++]=ch;
token[m]='\0';
}
else
{syn=29;token[m]='!
';back_one();}
break;
case'%':
syn=32;token[0]='%';break;
case'{':
syn=33;token[0]='{';break;
case'}':
syn=34;token[0]='}';break;
case'\t':
syn=35;token[0]='\t';break;
case'|':
syn=36;token[0]='|';break;
case'_':
syn=37;token[0]='_';break;
case'&':
syn=38;token[0]='&';break;
case'(':
syn=39;token[0]='(';break;
case')':
syn=40;token[0]=')';break;
case'.':
syn=41;token[0]='.';break;
case'[':
syn=42;token[0]='[';break;
case']':
syn=43;token[0]=']';break;
case'#':
syn=0;token[0]=ch;break;
default:
syn=-1;token[0]=ch;break;
}
}
if(token[0]=='\n')
lex_scanner();
}
intfactor()
{
if(syn==10||syn==11)
lex_scanner();
elseif(syn==39)
{
lex_scanner();
expression();
if(syn==40)
lex_scanner();
else
{
printf("')'错误\n");
kk=1;
}
}
else
{
printf("表达式出错\n");
kk=1;
}
return0;
}
intterm()
{
factor();
while(syn==15||syn==16)
{
lex_scanner();
factor();
}
return0;
}
voidCondition()
{
expression();
if(syn==20||syn==23||syn==44||syn==19||syn==17||syn==60)
lex_scanner();
else{kk=1;return;}
expression();
}
intexpression()
{
term();
while(syn==13||syn==14)
{
lex_scanner();
term();
}
return0;
}
intstatement()
{
switch(syn)
{
case10:
lex_scanner();
if(syn==12)
{
lex_scanner();
expression();
}
else{
printf("赋值号错误\n");
kk=1;
}
break;
case3:
lex_scanner();
if(syn==39)
lex_scanner();
else{kk=1;return0;}
Condition();
if(syn==40)
lex_scanner();
else{kk=1;return0;}
Statement_Block();
break;
case6:
lex_scanner();
if(syn==39)
lex_scanner();
else{kk=1;return0;}
Condition();
if(syn==40)
lex_scanner();
else{kk=1;return0;}
Statement_Block();
break;
}
return0;
}
intyucu()
{
statement();
while(syn==26)
{
lex_scanner();
statement();
}
return0;
}
intStatement_Block()
{
if(syn==33)
lex_scanner();
else{
kk=1;
return0;
}
yucu();
if(syn==34)
lex_scanner();
else{
kk=1;
return0;
}
while(syn==3||syn==6)
yucu();
return0;
}
intIrparser()
{
if(syn==1)
lex_scanner();
else{
kk=1;
return0;
}
if(syn==39)
lex_scanner();
else{
kk=1;
return0;
}
if(syn==40)
lex_scanner();
else{
kk=1;
return0;
}
Statement_Block();
}
voidmain()
{
inttemp=0;
inttem=0;
p=0;
printf("**************\n\n词法分析器\n\n**************\n请输入要进行词法分析的源程序以(main()开头,以#结束)\n");
do
{
scanf("%c",&ch);
prog[p++]=ch;//放缓冲区
}while(ch!
='#');//监测结束符
intq=p;
p=0;
lex_scanner();
Irparser();
if(kk==0)
printf("success\n");
if(kk==1)
printf("error\n");
}
测试结果:
输入题目要求的源程序,成功!
语法没错。
输入不完整的程序,出错!
实验总结:
这是一个递归下降的语法分析程序,从课本P65的LL
(1)文法了解了相关递归下降语法分析程序编写的思想和BNF文法的扩充原理,结合课本后面实验的框架完全本次实验的编写。
语法分析与词法分析有相当大的联系,算法结构也颇为复杂,,程序能运行通过,由于能力和时间问题,但是功能还不算完善,还有较多问题尚待解决。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语法分析 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)