编译原理词法分析器语法分析器实验报告.docx

上传人:b****6 文档编号:6729349 上传时间:2023-01-09 格式:DOCX 页数:8 大小:19.35KB
下载 相关 举报
编译原理词法分析器语法分析器实验报告.docx_第1页
第1页 / 共8页
编译原理词法分析器语法分析器实验报告.docx_第2页
第2页 / 共8页
编译原理词法分析器语法分析器实验报告.docx_第3页
第3页 / 共8页
编译原理词法分析器语法分析器实验报告.docx_第4页
第4页 / 共8页
编译原理词法分析器语法分析器实验报告.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

编译原理词法分析器语法分析器实验报告.docx

《编译原理词法分析器语法分析器实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理词法分析器语法分析器实验报告.docx(8页珍藏版)》请在冰豆网上搜索。

编译原理词法分析器语法分析器实验报告.docx

编译原理词法分析器语法分析器实验报告

编译原理词法分析器语法分析器实验报告

班级网络0802学号

姓名叶晨舟指导老师朱玉全

2021年7月4日

一、目的

编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。

从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。

二、任务及要求

基本要求:

1.词法分析器产生下述小语言的单词序列

这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:

对于这个小语言,有几点重要的限制:

首先,所有的关键字(如IFpWHILE等)都是“保留字”。

所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。

例如,下面的写法是绝对禁止的:

IF(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。

也就是说,对于关键字不专设对应的转换图。

但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。

当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。

再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。

例如,一个条件语句应写为

IFi0i=1;而绝对不要写成

IFi0i=1;

因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。

这个小语言的单词符号的状态转换图,如下图:

2.语法分析器能识别由加+减-乘*除/乘方^括号()操作数所组成的

算术表达式,其文法如下:

E→E+T|E-T|TT→T*F|T/F|FF→P^F|Pp→(E)|i

使用的算法可以是:

预测分析法;递归下降分析法;算符优先分析法;

LR分析法等。

3.中间代码生成器产生上述算术表达式的中间代码(四元式序列)

三、实现过程

给出各题目的详细算法描述,数据结构和函数说明,流程图。

1、词法分析器的流程图

2、语法分析器主程序图

3、中间代码生成器流程图:

四、源程序

词法分析器:

#includestring.h#includemalloc.h

#includeiostreamusingnamespacestd;

typedefstructtable//分析表存储结构{

charm;}table;

tableM;//定义分析表

typedefstructstacknode//定义栈内元素节点(带头结点(为空)的){

chardata;

structstacknode*next;}stackk;

voidinitlink(stackk*s)//初始化新栈{

s=(stackk*)malloc(sizeof(stackk));s-next=NULL;}

voidpoplink(stackk*s)//顶元素出栈{

stackk*p;charv;

if(s-next!

=NULL){

p=s-next;

v=p-data;s-next=p-next;}free(p);}

voidpushlink(stackk*s,charx)//新元素入栈{

stackk*p;

p=(stackk*)malloc(sizeof(stackk));p-data=x;

p-next=s-next;s-next=p;}

voiddisplay(stackk*s)//打印现实显示栈内元素{

inti=0,j;charst;p=s-next;

while(p!

=NULL){

st[i++]=p-data;p=p-next;}for(j=i-1;jj--)printf(“%c“,st[j]);

for(j=0;j16-i;j++)//打印对齐格式printf("%c",'');}

chargettop(stackk*s)//返回栈顶元素值{

if(s-next==NULL)return0;else

returns-next-data;}

intfind(charc,chararray[])//查找函数,{inti;

intflag=0;

for(i=0;ii++){

if(c==array[i])flag=1;}

returnflag;}

intlocation(charc,chararray[])//定位函数,指出字符所在位置{inti;

for(i=0;ii++){

if(c==array[i])

}}

voiderror()//出错函数定义{

printf("%15c出错!

\n",'');}

voidanalyse(charVn[],charVt[]){

inti,j,m,p,q,length,t,h;charw,X;charstr;opt0:

scanf("%s",str);

for(i=0;istrlen(str);i++){

if(!

find(str[i],Vt)){

printf("输入字符串有误!

请重新输入!

");gotoopt0;break;}}

stackk*st;initlink(st);

pushlink(st,'#');pushlink(st,Vn);//#与识别符号入栈j=0;

h=1;w=str;

printf("步骤%-12c分析栈%-24c剩余输入串%-12c所用产生式\n",'','','');opt1:

printf("%-16d",h);//显示步骤h++;

display(st);//显示分析栈中内容X=gettop(st);//上托栈顶符号放入Xpoplink(st);

for(intk=0;k14+j;k++)//打印对齐格式

printf("%c",'');

for(t=j;tstrlen(str);t++)

{

printf("%c",str[t]);//显示剩余字符串}

if(find(X,Vt)X!

='#')//分析栈的栈顶元素和剩余输入串的第一个元素相比较{

if(X==w){printf("%15c匹配\n",X);j++;w=str[j];gotoopt1;}else

error();}else{

if(X=='#'){

if(X==w){

printf("%8c是该文法的句子!

\n",'');}else

error();}else{

p=location(X,Vn);q=location(w,Vt);

char*S1="null",*S2="NULL";

if(strcmp(M[p][q].m,S1)==0||strcmp(M[p][q].m,S2)==0)//查找产生式error();else

{

charstr0;

strcpy(str0,M[p][q].m);

printf("%15c--%s\n",X,str0);//显示对应的产生式if(strcmp(str0,"$")==0)gotoopt1;else{

length=strlen(str0);//逆序进栈for(m=length-1;mm--){

pushlink(st,str0[m]);}

gotoopt1;}}}}}

intmain(){

inti,k,n,r;

charVn,Vt,select;

printf("******************************************************************\n");printf("对任意输入LL

(1)文法的分析表,判断验证字符串是否为该文法的句子\n");printf("并能给出分析和演示过程。

\n");

printf("******************************************************************\n");opt2:

printf("请输入各终结符(#号表示结束)Vt[i]:

\n");for(i=0;ii++){

scanf("%c",Vt[i]);if(Vt[i]=='#'){

r=i;break;}}

printf("请输入非终结符个数:

\n");scanf("%d",getchar();

for(i=0;ii++){

printf("请输入非终结符Vn[%d]:

\n",i);scanf("%c",Vn[i]);getchar();

printf("请输入此非终结符对应各终结符的产生式右部(null或NULL表示出错;$表示空串):

\n");

for(k=0;kk++){

scanf("%s",M[i][k].m);getchar();}}opt3:

printf("请输入要分析的字符串,且以#结束:

\n");analyse(Vn,Vt);

printf("********************请选择***********************\n");printf("1:

输入字符串\n");printf("2:

输入新分析表\n");printf("0:

退出\n");printf("*************************************************\n");opt4:

cinselect;switch(select){

case'1':

{gotoopt3;break;}case'2':

{gotoopt2;}case'0':

{break;}

default:

{printf("输入错误!

请重新选择:

");gotoopt4;break;}}

return0;}

运行结果:

语法分析器源程序:

#includestring.h#includeiostreamusingnamespacestd;charprog,token;charch;

intsyn,p,m=0,n,row,sum=0;

char*rwtab={"dim","if","do","stop","end","and","begin","bool","case","char","false","for","int","not","or","set","then","true","until","while"};

voidscaner(){for(n=0;nn++)token[n]=NULL;ch=prog[p++];while(ch==''){ch=prog[p];p++;}if((ch='a'ch='z')||(ch='A'ch='Z'))

{m=0;while((ch='0'ch='9')||(ch='a'ch='z')||(ch='A'ch='Z')){token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=21;for(n=0;nn++){if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}}elseif((ch='0'ch='9')){{sum=0;while((ch='0'ch='9')){sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=7+15;if(sum*****)syn=-1;}elseswitch(ch){

case'=':

syn=8+15;token=ch;break;case'+':

syn=9+15;token=ch;break;case'*':

m=0;token[m++]=ch;ch=prog[p++];if(ch=='*'){

syn=11+15;token[m++]=ch;}else{syn=10+15;p--;}

break;

case',':

syn=12+15;token=ch;break;case'(':

syn=13+15;token=ch;break;case')':

syn=14+15;token=ch;break;case'#':

syn=0;token=ch;break;case'':

m=0;token[m++]=ch;ch=prog[p++];if(ch==''){syn=17+15;token[m++]=ch;}elseif(ch=='='){syn=16+15;token[m++]=ch;}else{syn=15+15;p--;}break;

case'':

m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=19+15;token[m++]=ch;}else{syn=18+15;p--;

}break;

case':

':

m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=21+15;token[m++]=ch;}else{syn=20+15;p--;}break;

case'/':

syn=22+15;token=ch;break;case'-':

syn=23+15;token=ch;break;case';':

syn=24+15;token=ch;break;default:

syn=-1;break;}}

voidmain(){p=0;row=1;coutendlendlendl;cout"***************************小型词法**********************************"endlendl;cout"请输入一段程序(以#结束):

";do{cin.get(ch);prog[p++]=ch;}while(ch!

='#');p=0;coutendl"**************************词法分析*********************************"endl;cout"种别编码自身值"endl;do{scaner();switch(syn)

分析结果如器

{case22:

cout"("syn","sum")"endl;break;case-1:

cout"Errorinrow"row"!

"endl;break;

default:

cout"("syn","token")"endl;break;}}while(syn!

=0);}

运行结果:

}

中间代码生成器源程序:

表达式生成四元式递归子程序法

#includestring#includeiostreamusingnamespacestd;

#define*****_SIZE100

charEMachine(charw);//表达式E的自动机charTMachine(charw);//表达式T的自动机charFMachine(charw);//表达式F的自动机boolZMachine();//表达式Z的自动机stringintToString(inta);//整形变成字符串形函数

classstack//栈类定义{

private:

inttop;

string*stacka;intmaxsize;public:

stack(intsize=*****_SIZE);~stack(){delete[]stacka;}voidpush(conststringitem);stringpop(void);

stringgettop(void)const;

boolempty(void)const{return(top==-1);}

boolfull(void)const{return(top==maxsize-1);}voidclear(void){top=-1;}};

stack:

:

stack(intsize)//栈类的构造函数{

top=-1;

maxsize=size;

stacka=newstring[maxsize];if(!

stacka){

cerr"allocatememoryfailed."endl;exit

(1);}}

voidstack:

:

push(conststringitem)//压栈操作{

if(full()){

cerr"stackfull,cannotpush."endl;return;}

top++;

stacka[top]=item;}

stringstack:

:

pop(void)//出栈操作{

if(empty()){

cerr"stackempty,cannotpop."endl;exit

(1);}

stringitem=stacka[top];top--;

returnitem;}

stringstack:

:

gettop(void)const//取栈顶操作{

if(empty()){

cerr"stackempty,cannotgettop."endl;exit

(1);}

returnstacka[top];}

staticstackwordStack;//符号栈staticintnoOfQuet=0;//静态四元式个数记录staticintnoOfT=1;//静态状态个数记录

voidmain(){//主函数charyesOrNo;//进行一个循环操作控制do{cout"请输入算术表达式:

"endl;noOfT=1;//每次结束询问ZMachine();coutendl"Continue?

YesorNot:

";cinyesOrNo;//输入“Y”则继续}while(yesOrNo=='y');//否则程序结束}

boolZMachine(){//Z自动机charw;cinw;w=EMachine(w);//调用E自动机

if(w=='#'){//遇到“#”则结束returntrue;}else{returnfalse;}}

charEMachine(charw){//E自动机stringoperate,a,b,c;stringstate;w=TMachine(w);//调用T自动机while(w=='+'||w=='-'){//是加或减符号operate=w;cinw;//读入下一字符w=TMachine(w);//调用T自动机b=wordStack.pop();//字符栈弹出a=wordStack.pop();//两个操作字符cout"(\""operate"\","a","b",t"noOfT")"endl;c="t"+intToString(noOfT);//输出四元式wordStack.push(c);//新状态压栈noOfT++;//状态计数加一}returnw;}

charTMachine(charw){stringoperate,a,b,c;stringstate;w=FMachine(w);//调用F自动机while(w=='*'||w=='/'){//是乘除号operate=w;cinw;//读取下一字符w=FMachine(w);//调用F自动机b=wordStack.pop();//符号栈弹出a=wordStack.pop();//两个操作字符cout"(\""operate"\","a","b",t"noOfT")"endl;c="t"+intToString(noOfT);//输出四元式wordStack.push(c);//新状态压栈noOfT++;//状态计数加1}returnw;}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1