软件学院实验卡和实验报告学号:xxxxxxxxxxx姓名:xxx年级专业班级:xxxxxxxxxxxxxxxxxxxxxx实验室组别:____实验日期:2xxx年xx月xxx日课程名称编译原理实验课时4实验名称和序号语义分析4同组者姓名实验目的通过上机实验,加深对语法制导翻译的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。实验环境(1)软件环境:MicrosoftVisualStudio6.0;(2)硬件环境:Windows2000操作系统。实验内容和原理对给定的程序通过语义分析器能够判断语句串是否正确。正确则输出三地址指令形式的四元式代码,错误则抛出错误信息。实验步骤方法关键代码(1)输入待分析的字符串。语法如下:a.关键字:begin,if,then,while,do,end.b.运算符和界符::=+-*/===;()#c.其他单词是标识符(ID)和整形常数(NUM):ID=letter(letter|digit)*,NUM=digitdigit*d.空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。(2)扫描字符串,采用递归向下进行分析。主要函数如下:a.scaner()//词法分析函数,chartoken[8]用来存放构成单词符号的字符串;b.parser()//语法分析,在语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。只对表达式、赋值语句进行翻译。c.emit(char*result,char*arg1,char*op,char*ag2)//该函数功能是生成一个三地址语句返回四元式表中。d.char*newtemp()//该函数返回一个新的临时变量名,临时变量名产生的顺序为T1,T2,…。((接上页)实验步骤方法关键代码四元式表的结构如下:struct{charresult[8];charag1[8];charop[8];charag2[8];}quad[20];(3)输出为三地址指令形式的四元式序列。例如:语句串begina:=2+3*4;x:=(a+b)/c;end#,输出的三地址指令如下:t1=3*4t2=2+t1a=t2t3=a+bt4=t3/cx=t4测试记录分析结论对于正确的语句串,例如:begina:=2+3*4;x:=(a+b)/c;end#,运行结果如图:对于缺少赋值符号、“end”、“begin”、“(”、“)”等均可做出错误判断并给出相应提示。小结实现了输出为三地址指令形式的四元式序列。通过上机实验,加深了对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。加深了对C++语言的用途的理解。以下由实验教师填写记事评议成绩评定平时成绩_______实验报告成绩________综合成绩_________指导教师签名:附录1程序功能1.1操作实例例如:对源程序begina:=2+3*4;x:=(a+b)/c;end#进行判断;首先运行程序,程序出现提示:“请输入字符串,以#号结束:”,在光标处输入begina:=2+3*4;x:=(a+b)/c;end#,回车,结果如图:程序给出了三地址码形式的四元式。1.2错误处理(1)如果用户在语句串开头处没有输入“begin”,程序提示“缺少begin!”;如果用户没有输入“end”,程序提示“end!错误”;(2)如果用户输入的语句串中缺少赋值符号(“:=”),程序提示“缺少赋值符号!”;(3)如果用户输入的语句串中“(”和“)”不匹配,程序提示“缺少“(”!”或“缺少“)!”。2源程序#includestdio.h#includestring.h#includestdlib.hcharprog[80],token[8];charch;intsyn,p,m,n,sum;intkk=0,ii,N,nn=0;intk=0,t,i=0;chartt;char*keywords[6]={begin,if,then,while,do,end};//关键字表。intscaner();intparser();intstatement();intsentence();char*term();char*factor();char*expression();voidemit(char*result,char*ag1,char*op,char*ag2);struct//四元式的结构。{charresulted[8];charag1ed[8];charoped[8];charag2ed[8];}quad[20];voidmain(){p=0;printf(请输入字符串,以#号结束:\n);do{scanf(%c,&ch);prog[p++]=ch;}while(ch!='#');//没有遇到结束符,则首先调用scaner()进行词法分析,之后进行语义分析。p=0;scaner();parser();}char*newtemp(void)//返回一个新的临时变量名,临时变量名产生的顺序为t1,t2,…。{char*P;charM[8];P=(char*)malloc(8);k++;itoa(k,M,10);strcpy(P+1,M);P[0]='t';return(P);}intparser()//在语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。只对表达式、赋值语句进行翻译。{intschain=0;kk=0;if(syn==1){scaner();schain=sentence();//调用语句串分析函数进行分析。if(syn=6)//“end”。{scaner();if(syn==0&&(kk==0))printf(success);}else{if(kk!=1)printf(缺end错误);//输出“end”错误。kk=1;}}else{printf(begin错误);//输出“begin”错误。kk=1;}return(schain);}intsentence()//语句串分析函数。{intschain=0;schain=statement();//调用语句分析函数进行分析。while(syn==26)//“;”。{scaner();schain=statement();//调用语句分析函数进行分析。}return(schain);}intstatement()//语句分析函数。{chartt[8],eplace[8];intschain=0;switch(syn){case10:strcpy(tt,token);scaner();if(syn==18)//赋值语句。{scaner();strcpy(eplace,expression());emit(tt,eplace,,);schain=0;}else{printf(缺少赋值号);//缺少“:=”错误。kk=1;}return(schain);break;}}char*expression(void){char*tp,*ep2,*eplace,*tt;tp=(char*)malloc(12);//分配空间。ep2=(char*)malloc(12);eplace=(char*)malloc(12);tt=(char*)malloc(12);strcpy(eplace,term());//调用term分析产生表达式计算的第一项eplace。while(syn==13||syn==14)//加减。{strcpy(tt,token);scaner();strcpy(ep2,term());//调用term()分析产生表达式计算的第二项ep2。strcpy(tp,newtemp());//调用newtemp()产生临时变量tp存储计算结果。emit(tp,eplace,tt,ep2);//生成四元式送入四元式表。strcpy(eplace,tp);}return(eplace);}char*term(void){char*tp,*ep2,*eplace,*tt;tp=(char*)malloc(12);ep2=(char*)malloc(12);eplace=(char*)malloc(12);tt=(char*)malloc(12);strcpy(eplace,factor());while(syn==15||syn==16)//乘除。{strcpy(tt,token);scaner();strcpy(ep2,factor());strcpy(tp,newtemp());emit(tp,eplace,tt,ep2);strcpy(eplace,tp);}return(eplace);}char*factor(void){char*fplace;fplace=(char*)malloc(12);strcpy(fplace,);if(syn==10)//字母。{strcpy(fplace,token);scaner();}elseif(syn==11)//数字。{itoa(sum,fplace,10);scaner();}elseif(syn==27)//“(”。{scaner();strcpy(fplace,expression());if(syn==28)//有“)”。scaner();else{printf(')'错误);//只有“(”,缺少“)”。kk=1;}}else{printf('('错误);kk=1;}return(fplace);}voidemit(char*result,char*ag1,char*op,char*ag2)//生成一个三地址码并返回到四元式代码中。{strcpy(quad[nn].resulted,result);strcpy(quad[nn].ag1ed,ag1);strcpy(quad[nn].oped,op);strcpy(quad[nn].ag2ed,ag2);printf((%d)%s=%s%s%s\n,nn+1,quad[nn].resulted,quad[nn].ag1ed,quad[nn].oped,quad[nn].ag2ed);nn++;}scaner()//此函数为词法分析。{for(n=0;n8;n++)token[n]=NULL;ch=prog[p++];m=0;while(ch=='')ch=prog[p++];if((ch='a')&&(ch='z'))//判断是否是字母。{while((ch='a')&&(ch='z')||(ch='0')&&(ch='9'))//判断下一个是否是字母或数字。{token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=10;for(n=0;n6;n++)if(strcmp(token,keywords[n])==0)//判断是否匹配关键字。{syn=n+1;break;}}elseif(ch='0'&&ch='9')//判断数字。{sum=0;while((ch='0')&&(ch='9'))//判断下一个是否是数字。{sum=sum*10+(int)ch-'0';ch=prog[p++];}p--;syn=11;}elseswitch(ch){case''://是否是“”。m=0;token[m++]=ch;if(ch=='')//是否是“”。{syn=21;token[m++]=ch;}elseif(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++]