1、编译原理语义分析实验报告软工082班兰洁200831104044一、 实验内容二、 实验目的三、 实验要求四、 程序流程图五、 程序代码与主要过程说明六、 测试用例七、 输出结果八、 实验心得一、 实验内容 定义模拟的简单语言的语义成分,将语义分析程序编制成一个子程序,在实验2分析出个语法单位后,分析其含义,并将可执行语句或表达式翻译成四元式输出,并将错误信息输出。二、 实验目的 通过上机实验,加深对语义制导翻译原理的理解,掌握将语法分析所识别的语法成分变换成为中间代码的语义翻译方法。三、 实验要求 采用递归下降语法制导翻译方法,对算术表达式、赋值语句进行语义分析并生成四元式序列。例如:对于语
2、句串Functiona=2+3*4;x=(a+b)/c;endfunc#输出的三地址指令如下l t1=3*4l t2=2+t1l a=t2l t3=a+bl t4=t3/cl x=t4四、 程序流程图由于语义分析的的方法就是在语法分析过程中,根据每个产生式所对应的语义子程序进行翻译,为每个产生式配上一个翻译子程序,并在语法分析的同时执行这些子程序。所有对应的流程图与语法分析流程图大同小异,关于各类函数的流程图我已经在词法分析报告与语法分析报告中详细画出,所以这里只说明程序主要流程。五、 程序代码与主要过程说明/*语义分析源代码*/# include# include# include# inc
3、lude# includestruct quad / 四元式表char result12;char ag112;char op12;char ag212; ;struct quad quad30;int count=0;char *expression(void);char prog200,token9;char ch;int syn,p,m,n,sum=0;int kk=0,k=0;char *rwtab6=function,if,then,while,do,endfunc;void scaner()m=0; for(n=0;n=a& ch=A & ch=a& ch=A&ch=0&ch=9)
4、tokenm+=ch;ch=progp+;/end of whiletokenm+=0;p-;syn=10;for(n=0;n=0&ch=0&ch=9)sum=sum*10+ch-0;ch=progp+;p-;syn=11;elseswitch(ch)case:m=0;tokenm+=ch;ch=prog+p;if(ch=)syn=24;tokenm+=ch;elsesyn=23;ch=prog-p;break;case=:m=0,tokenm+=ch;ch=prog+p;if(ch=)syn=25;tokenm+=ch;elsesyn=18;ch=prog-p;break;case!:m=0
5、;tokenm+=ch;ch=prog+p;if(ch=)syn=22;tokenm+1=ch;elsesyn=-1;break;case+:syn=13;token0=ch;break;case-:syn=14;token0=ch;break;case*:syn=15;token0=ch;break;case/:syn=16;token0=ch;break;case;:syn=26;token0=ch;break;case(:syn=27;token0=ch;break;case):syn=28;token0=ch;break;case#:syn=0;token0=ch;break;defa
6、ult:syn=-1;/end of scanervoid emit(char *result,char *ag1,char *op,char *ag2) /将三地址代码送到四元式表strcpy(quadcount.result,result);strcpy(quadcount.ag1,ag1); strcpy(quadcount.op,op);strcpy(quadcount.ag2,ag2);count+;return;char *newtemp() /返回临时变量t1,t2. char *p;char m8;p=(char *)malloc(8);k+;itoa(k,m,10); /功能
7、将整数装换为字符串。并将值保存在m中。10是基数 表示将k的值转化为10进制数。strcpy(p+1,m);p0=t;return(p);char *factor()char *fplace;fplace=(char *)malloc(12);strcpy(fplace, );if(syn=10)strcpy(fplace,token);scaner();else if(syn=11)itoa(sum,fplace,10);scaner(); else if(syn=27)scaner();fplace=expression();if(syn=28)scaner();elseprintf(n)
8、ERROR);kk=1;elseprintf(n(ERROR);kk=1;return(fplace);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)if(syn=15)tt0=*;tt1=0;else if(syn=16)tt0=/;tt1=0;scaner();strcpy(ep
9、2,factor();strcpy(tp,newtemp(); /tp为临时变量emit(tp,eplace,tt,ep2); /将三地址代码送到四元式表strcpy(eplace,tp);return(eplace); char *expression()char*tp,*ep2,*eplace,*tt;tp=(char*)malloc(12);ep2=(char*)malloc(12);eplace=(char*)malloc(12);tt=(char*)malloc(12);strcpy(eplace,term();while(syn=13|syn=14)if(syn=13)tt0=+;
10、tt1=0;else if(syn=14)tt0=-;tt1=0;scaner();strcpy(ep2,term();strcpy(tp,newtemp();emit(tp,eplace,tt,ep2);/strcpy(eplace,tp);return(eplace); statement()char tt8,eplace8;int schain=0;switch(syn)case 10:strcpy(tt,token);scaner();if(syn=18)scaner();strcpy(eplace,expression();emit(tt,eplace, , );schain=0;e
11、lseprintf(n缺少赋值语句n);kk=1;break;return(schain); yucu()int schain=0;schain=statement(); /进行语句分析while(syn=26) /一个语句识别结束,继续识别scaner();schain=statement();return(schain); irparser()/在原来语法分析的基础上插入相应的语义动作,据每个产生式所对应的语义子程序进行翻译,为每个产生式配上一个翻译子程序,并在语法分析的同时执行这些子程序即将输入串翻译成四元式序列。 int schain=0;kk=0;if(syn=1) scaner()
12、;schain=yucu();if(syn=6)scaner();if(syn=0 & kk=0)printf(n语法,语义分析成功);elseif(kk!=1)printf(n缺endfuncn);kk=1;elseprintf(n缺functionn);kk=1;return(schain); void main()int i;p=0;printf(请输入语句(以#结束,不要换行):);doch=getchar();progp+=ch;while(ch!=#);p=0;printf(种别码 单词符号n);doscaner();switch(syn)case 11: printf(%-3d
13、%dn,syn,sum);break;case -1: printf(词法分析失败,程序终止!n);return;default:printf(%-3d %sn,syn,token);while(syn!=0);printf(词法分析成功,按任意键进行语法,语义分析);getch();p=0;scaner();irparser();if(kk!=0)printf(词法分析失败,程序终止!);return;printf(n三地址指令如下:n);for(i=0;icount;i+)printf(%s=,quadi.result); /t1= /x=printf(%s,quadi.ag1); /a
14、/t1printf(%s,quadi.op); /+printf(%s ,quadi.ag2); /b printf(n);getch();return;六、 测试用例测试用例1输出结果测试用例2输出结果functiona=1;b=2;c=a+b;endfunc#种别码 单词符号1 function10 a18 =11 126 ;10 b18 =11 226 ;10 c18 =10 a13 +10 b26 ;6 endfunc0 #词法分析成功,按任意键进行语法,语义分析语法,语义分析成功三地址指令如下:a=1 b=2 t1=a+b c=t1function x=(a+b)/c;b=1+2*c
15、;endfunc#种别码 单词符号1 function10 x18 =27 (10 a13 +10 b28 )16 /10 c26 ;10 b18 =11 113 +11 215 *10 c26 ;6 endfunc0 #词法分析成功,按任意键进行语法,语义分析语法,语义分析成功三地址指令如下:t1=a+b t2=t1/c x=t2 t3=2*c t4=1+t3 b=t4七、 输出结果用例一用例二八、 实验心得通过编译原理实验三语义分析实验,使得自己对语义分析的语法制导翻译以及三地址代码的四元式表现方式有了更深刻的了解,虽然源代码并非由自己设计,但是在调试程序的过程中,逐步理解程序递归下降语法制导思想,也掌握了将语法分析所识别的语法成分变换为中间代码的语义翻译方法,受益匪浅。通过试验结果可以看出,这个程序实现了输出为三地址指令形式的四元式序列。