语义分析
- 格式:doc
- 大小:169.50 KB
- 文档页数:14
编译原理实验三语义分析1.实验目的通过实验掌握语法制导分析的翻译理论、原理和方法,为为代码优化、生成做准备。
2.实验内容:选择所学过的语义分析技术之一实现下面文法G的语义分析程序。
文法G:简单算术表达式的文法E →T{+T|-T}T →F{*F|/F}F →(E) | a | b | c简单算术表达式的运算分量只能是单词符号a、b、c要求:如果是文法正确句子,输出相应的四元组输出是Error 不是文法正确句子例如输入a+b*c# 输出(*,entry (b),entry (c),t1)(+,entry (a),t1,t2)输入a+c+b*c-a# 输出(+,entry (a),entry (c),t1)(*,entry (b),entry (c),t2)(+,t1,t2,t3)(-,t3,entry (a),t4)输入d+f# 输出error输入a+b*+c# 输出error输入a(b)# 输出error3.实验要求:(1)上机前编写完整的实验报告,报告中要体现分析→设计→实现等几个过程;如无实验报告,则取消本次上机资格,实验成绩以0分记。
(2)严禁相互抄袭,否则实验成绩以0分记;(3)有完整的源代码,源码有规范的注释,无明显的语法错误;4.实验步骤(1)分析与设计(2)1设置语义过程(1)emit(char *result,char *arg1,char *op,char *ag2)该函数功能是生成一个三地址语句送到四元式表中。
四元式表的结构如下:struct {char result[8];char ag1[8];char op[8];char ag2[8];}quad[20];(2) char *newtemp()该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2,….Char *newtemp(void){char *p;char m[8];p=(char *)malloc(8);k++;itoa(k,m,10);strcpy(p+1,m);p[0]=’t’;return(p);}(3)编码实现//对字符的扫描void scaner() {for(n=0;n<8;n++)token[n]=NULL;ch=prog[p++];while(ch==' ') {ch=prog[p];p++;}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) {if((ch>='a'&&ch<='c')||(ch>='A'&&ch<='C')){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=10;for(n=0;n<6;n++) {if(strcmp(token,rwtab[n])==0) {syn=n+1;break;}}}elsecout<<"Error!"<<endl;}else if((ch>='0'&&ch<='9')) {{sum=0;while((ch>='0'&&ch<='9')) {sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=11;if(sum>32767)syn=-1;}else switch(ch){case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>') {syn=21;token[m++]=ch;}else if(ch=='='){syn=22;token[m++]=ch;}else {syn=23;p--;}break;case'>':m=0;token[m++]=ch;ch=prog[p++];if(ch=='=') {syn=24;token[m++]=ch;}else {syn=20;p--;}break;case':':m=0;token[m++]=ch;ch=prog[p++];if(ch=='=') {syn=18;token[m++]=ch;}else {syn=17;p--;}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=25;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;break;}}(4)系统调试5.实验总结通过试验结果可以看出,这个程序实现了输出为三地址指令形式的四元式序列。
通过上机实验,加深了对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。
以及还复习了对vc的应用。
附完整代码#include<stdio.h>#include<string.h>#include<iostream.h>#include<stdlib.h>struct {char result[12];char ag1[12];char op[12];char ag2[12];}quad;//变量的定义char prog[80],token[12];char ch;int syn,p,m=0,n,sum=0,kk; //p是缓冲区prog的指针,m是token的指针char *rwtab[6]={"begin","if","then","while","do","end"};void scaner();char *factor(void);char *term(void);char *expression(void);int yucu();void emit(char *result,char *ag1,char *op,char *ag2);char *newtemp();int statement();int k=0;void emit(char *result,char *ag1,char *op,char *ag2) {strcpy(quad.result,result);strcpy(quad.ag1,ag1);strcpy(quad.op,op);strcpy(quad.ag2,ag2);//cout<<quad.result<<"="<<quad.ag1<<quad.op<<quad.ag2<<endl;cout<<"( "<<quad.op<<", "<<"entry("<<quad.ag1<<"), "<<"entry("<<quad.ag2<<"), "<<quad.result<<")\n"<<endl;//cout<<"entry("<<quad.ag1<<"entry("<<quad.op<<quad.ag2<<endl;}char *newtemp() {char *p;char m[12];p=(char *)malloc(12);k++;itoa(k,m,10);strcpy(p+1,m);p[0]='t';return (p);}//对字符的扫描void scaner() {for(n=0;n<8;n++)token[n]=NULL;ch=prog[p++];while(ch==' ') {ch=prog[p];p++;}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) {if((ch>='a'&&ch<='c')||(ch>='A'&&ch<='C')){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=10;for(n=0;n<6;n++) {if(strcmp(token,rwtab[n])==0) {syn=n+1;break;}}}elsecout<<"Error!"<<endl;}else if((ch>='0'&&ch<='9')) {{sum=0;while((ch>='0'&&ch<='9')) {sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=11;if(sum>32767)syn=-1;}else switch(ch){case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>') {syn=21;token[m++]=ch;}else if(ch=='='){syn=22;token[m++]=ch;}else {syn=23;p--;}break;case'>':m=0;token[m++]=ch;ch=prog[p++];if(ch=='=') {syn=24;token[m++]=ch;}else {syn=20;p--;}break;case':':m=0;token[m++]=ch;ch=prog[p++];if(ch=='=') {syn=18;token[m++]=ch;}else {syn=17;p--;}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=25;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;break;}}int lrparser(){//cout<<"调用lrparser"<<endl;int schain=0;kk=0;if(syn==1) {scaner();schain=yucu();//cout<<"SYN= "<<syn<<endl;if(syn==6) {scaner();if(syn==0 && (kk==0))cout<<"success!"<<endl;}/* else{if(kk!=1)cout<<"缺end!"<<endl;kk=1;} */}else{cout<<"Error!"<<endl;kk=1;}return(schain);}int yucu() {// cout<<"调用yucu"<<endl;int schain=0;schain=statement();while(syn==26) {scaner();schain=statement();}return(schain);}int statement(){//cout<<"调用statement"<<endl;char *eplace,*tt;eplace=(char *)malloc(12);tt=(char *)malloc(12);int schain=0;switch(syn) {case 10:strcpy(tt,token);scaner();// if(syn==18) {scaner();strcpy(eplace,expression());emit(tt,eplace,"","");schain=0;/* }else {cout<<"缺少赋值符!"<<endl;kk=1;} */return (schain);break;}return (schain);}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分析产生表达式计算的第一项eplacewhile((syn==15)||(syn==16)) {if(syn==15)strcpy(tt,"+");elsestrcpy(tt,"-");scaner();strcpy(ep2,term()); //调用term分析产生表达式计算的第二项ep2strcpy(tp,newtemp()); //调用newtemp产生临时变量tp存储计算结果emit(tp,eplace,tt,ep2); //生成四元式送入四元式表strcpy(eplace,tp);}return(eplace);}char *term(void) {// cout<<"调用term"<<endl;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==13)||(syn==14)) {if(syn==13)strcpy(tt,"*");else strcpy(tt,"/");scaner();strcpy(ep2,factor()); //调用factor分析产生表达式计算的第二项ep2strcpy(tp,newtemp());//调用newtemp产生临时变量tp存储计算结果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();}else if(syn==11) {itoa(sum,fplace,10);scaner();}else if(syn==27) {scaner();fplace=expression();//调用expression分析返回表达式的值if(syn==28)scaner();else {cout<<"缺)错误!"<<endl;kk=1;}} else {cout<<"缺(错误!"<<endl;kk=1;}return(fplace);}void main() {p=0;cout<<"**********语义分析程序**********"<<endl;cout<<"Please input string:"<<endl;do {cin.get(ch);prog[p++]=ch;}while(ch!='#');p=0;scaner();lrparser();}。