编译原理语义分析实验报告软工082班兰洁200831104044一、实验内容二、实验目的三、实验要求四、程序流程图五、程序代码与主要过程说明六、测试用例七、输出结果八、实验心得一、实验内容定义模拟的简单语言的语义成分,将语义分析程序编制成一个子程序,在实验2分析出个语法单位后,分析其含义,并将可执行语句或表达式翻译成四元式输出,并将错误信息输出。二、实验目的通过上机实验,加深对语义制导翻译原理的理解,掌握将语法分析所识别的语法成分变换成为中间代码的语义翻译方法。三、实验要求采用递归下降语法制导翻译方法,对算术表达式、赋值语句进行语义分析并生成四元式序列。例如:对于语句串Functiona=2+3*4;x=(a+b)/c;endfunc#输出的三地址指令如下t1=3*4t2=2+t1a=t2t3=a+bt4=t3/cx=t4四、程序流程图由于语义分析的的方法就是在语法分析过程中,根据每个产生式所对应的语义子程序进行翻译,为每个产生式配上一个翻译子程序,并在语法分析的同时执行这些子程序。所有对应的流程图与语法分析流程图大同小异,关于各类函数的流程图我已经在词法分析报告与语法分析报告中详细画出,所以这里只说明程序主要流程。五、程序代码与主要过程说明/*语义分析源代码*/#includestdio.h#includestring.h#includeconio.h#includemalloc.h#includeSTDLIB.Hstructquad//四元式表{charresult[12];charag1[12];charop[12];charag2[12];};structquadquad[30];intcount=0;char*expression(void);charprog[200],token[9];charch;intsyn,p,m,n,sum=0;intkk=0,k=0;char*rwtab[6]={function,if,then,while,do,endfunc};voidscaner(){m=0;for(n=0;n8;n++)token[n]='\0';ch=prog[p++];while(ch=='')ch=prog[p++];if((ch='a'&&ch='z')||(ch='A'&&ch='Z')){while((ch='a'&&ch='z')||(ch='A'&&ch='Z')||(ch='0'&&ch='9')){token[m++]=ch;ch=prog[p++];}//endofwhiletoken[m++]='\0';p--;syn=10;for(n=0;n6;n++){if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}//endoffor}elseif(ch='0'&&ch='9'){sum=0;while(ch='0'&&ch='9'){sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}else{switch(ch){case'':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=22;token[m+1]=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=25;token[m++]=ch;}else{syn=18;ch=prog[--p];}break;case'!':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){syn=22;token[m+1]=ch;}else{syn=-1;}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=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;}}//endofscaner}voidemit(char*result,char*ag1,char*op,char*ag2)//将三地址代码送到四元式表{strcpy(quad[count].result,result);strcpy(quad[count].ag1,ag1);strcpy(quad[count].op,op);strcpy(quad[count].ag2,ag2);count++;return;}char*newtemp()//返回临时变量t1,t2...{char*p;charm[8];p=(char*)malloc(8);k++;itoa(k,m,10);//功能将整数装换为字符串。并将值保存在m中。10是基数表示将k的值转化为10进制数。strcpy(p+1,m);p[0]='t';return(p);}char*factor(){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();fplace=expression();if(syn==28)scaner();else{printf(\n')'ERROR);kk=1;}}else{printf(\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){tt[0]='*';tt[1]='\0';}elseif(syn==16){tt[0]='/';tt[1]='\0';}scaner();strcpy(ep2,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){tt[0]='+';tt[1]='\0';}elseif(syn==14){tt[0]='-';tt[1]='\0';}scaner();strcpy(ep2,term());strcpy(tp,newtemp());emit(tp,eplace,tt,ep2);//strcpy(eplace,tp);}return(eplace);}statement(){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(\n缺少赋值语句\n);kk=1;}break;}return(schain);}yucu(){intschain=0;schain=statement();//进行语句分析while(syn==26)//一个语句识别结束,继续识别{scaner();schain=statement();}return(schain);}irparser()//在原来语法分析的基础上插入相应的语义动作,据每个产生式所对应的语义子程序进行翻译,为每个产生式配上一个翻译子程序,并在语法分析的同时执行这些子程序即将输入串翻译成四元式序列。{intschain=0;kk=0;if(syn==1){scaner();schain=yucu();if(syn==6){scaner();if(syn==0&&kk==0)printf(\n语法,语义分析成功);}else{if(kk!=1){printf(\n缺endfunc\n);kk=1;}}}else{printf(\n缺function\n);kk=1;}return(schain);}voidmain(){inti;p=0;printf(请输入语句(以#结束,不要换行):);do{ch=getchar();prog[p++]=ch;}while(ch!='#');p=0;printf(种别码单词符号\n);do{scaner();switch(syn){case11:printf(%-3d%d\n,syn,sum);break;case-1:printf(词法分析失败,程序终止!\n);return;default:printf(%-3d%s\n,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=,quad[i].result);//t1=//x=printf(%s,quad[i].ag1);//a//t1printf(%s,quad[i].op);//+printf(%s,quad[i].ag2);//bprintf(\n);}getch();return;}六、测试用例七、输出结果用例一测试用例1输出结果测试用例2输出结果functiona=1;b=2;c=a+b;endfunc#种别码单词符号1function10a18=11126;10b18=11226;10c18=10a13+10b26;6endfunc0#词法分析成功,按任意键进行语法,语义分析语法,语义分析成功三地址指令如下:a=1b=2t1=a+bc=t1functionx=(a+b)/c;b=1+2*c;endfunc#种别码单词符号1function10x18=27(10a13+10b28)16/10c26;10b18=11113+11215*10c26;6endfunc0#词法分析成功,按任意键进行语法,语义分析语法,语义分析成功三地址指令如下:t1=a+bt2=t1/cx=t2t3=2*ct4=1+t3b=t4用例二八、实验心得通过编译原理实验三语义分析实验,使得自