scau编译原理综合性实验
一、题目要求
题目:
选择部分C语言的语法成分,设计其词法分析程序、语法语义分析程序。
要求:
设计并实现一个一遍扫描的词法语法语义分析程序,将部分C语言的语法成分(包含赋值语句、if语句、while循环语句)翻译成三地址代码,要求有一定的出错提示和错误恢复功能。
二、源码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>#define BUFFSIZE 5000
char prog[BUFFSIZE],token[8];
char ch,ch1;
int syn,p,q,m,n,sum,i=1,k=0,kk,flag=0;
char *rwtab[32]={"main","break","case","char","define","continue","default","do","double","else","what","extern","float","for","goto","if","int","long","stack","return","short","fopen","sizeof","static","struct","switch","typedef","enum","unsigned","void","fclose","while"};int main() /*主函数*/
{void scaner();int lrparser();FILE *fp;if((fp=fopen("test.txt","r"))==NULL){ printf("无法打开文件!\n");exit(1);}p=0;while(!feof(fp)){ prog[p++]=fgetc(fp);if(p>=5000){ printf("缓冲区容量不够!\n");exit(1);}}/*把文件test中的内容存入数组prog中*/fclose(fp);printf("%s\n",prog);p=0;
printf("输出词法分析结果:\n");do{scaner();switch(syn){case 34:printf("(%d,%d),",syn,sum);break;case -1:printf("error,");break;default:printf("(%d,%s),",syn,token);}}while(syn!=0);p=0;printf("\n语法语义的分析开始:\n");scaner();lrparser();system("pause");return 0;
}void scaner()
{for(n=0;n<8;n++) token[n]=NULL;m=0;sum=0;ch=prog[p];while(ch==' '||ch=='\n'){ p++;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;m++;p++;ch=prog[p];}token[m++]='\0';syn=33;for(n=0;n<32;n++)if(strcmp(token,rwtab[n])==0){ syn=n+1;break;}}/*判断输入字符是否为标识符或者关键字的情况*/elseif(ch>='0'&&ch<='9'){ while(ch>='0'&&ch<='9'){ sum=sum*10+ch-'0';p++;ch=prog[p];}syn=34;}/*判断输入字符是否为整型常数的情况*/elseswitch(ch){case '<':token[m]=ch;p++;ch=prog[p];if(ch=='>'){ syn=42;m++;token[m]=ch;p++;}/*出现<>的情况*/else if(ch=='='){ syn=43;m++;token[m]=ch;p++;}/*出现<=的情况*/else{ syn=41;}break;case '>':token[m]=ch;p++;ch=prog[p];if(ch=='='){ syn=45;m++;token[m]=ch;p++;}/*出现>=的情况*/else{syn=44;}break;case ':':token[m]=ch;p++;ch=prog[p];if(ch=='='){ syn=40;m++;token[m]=ch;p++;}/*出现:=的情况*/else{syn=39;}break;case '/':token[m]=ch;p++;ch=prog[p];if(ch=='*'){ syn=51;q=0;m++;token[m]=ch;p++;q=p+1;while(prog[p]!='*'||prog[q]!='/'){p++;q++;}}/*出现注释'/*'的情况*/else{syn=38;}break;case '*':token[m]=ch;p++;ch=prog[p];if(ch=='/'){ syn=52;m++;token[m]=ch;p++;}else{syn=37;}break;case '+':syn=35;token[0]=ch;p++;break;case '-':syn=36;token[0]=ch;p++;break;case '=':syn=46;token[0]=ch;p++;break;case ';':syn=47;token[0]=ch;p++;break;case '(':syn=48;token[0]=ch;p++;break;case ')':syn=49;token[0]=ch;p++;break;case '%':syn=50;token[0]=ch;p++;break;case '{':syn=53;token[0]=ch;p++;break;case '}':syn=54;token[0]=ch;p++;break;case ',':syn=55;token[0]=ch;p++;break;case '#':syn=0;token[0]=ch;p++;break;default:syn=-1;}}void emit(char *result,char *ag1,char *op,char *ag2)
{printf("(%d) %s=%s%s%s\n",i,result,ag1,op,ag2);i++;return;
}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);
}int lrparser()
{ int yucu();int schain=0;kk=0;if(syn!=1){printf("缺main错误!!\n");flag++;}scaner();if(syn!=48){printf("main后缺(括号!!\n");flag++;}else scaner();if(syn!=49){printf("main后缺)括号!!\n");flag++;}else scaner();if(syn!=53){printf("main后缺{括号!!\n");flag++;}else scaner();schain=yucu();if(syn==54){ scaner();if(syn==0&&kk==0&&flag==0)/*kk是用来记录其他错误的标识*/printf("语法与语义分析结束。分析结果为:success\n");elseprintf("程序存在着%d个错误\n",flag);}else{if(kk!=1)printf("缺}错误!!");kk=1;}return(schain);
}int yucu()
{int statement();int schain=0;schain=statement();while(syn==47){ scaner();schain=statement();}return(schain);
}int statement()
{char *expression();char tt[8],eplace[8];int schain=0;switch(syn){ case 33:strcpy(tt,token);scaner();if(syn==46){ scaner();strcpy(eplace,expression());emit(tt,eplace," "," ");schain=0;}else{printf("赋值号=错误!!");kk=1;}return(schain);break;}
}char *expression(void)
{ char *term();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==35||(syn==36)){ strcpy(tt,token);scaner();strcpy(ep2,term());strcpy(tp,newtemp());emit(tp,eplace,tt,ep2);strcpy(eplace,tp);}return(eplace);
}char *term(void)
{char *factor();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==37||(syn==38)){ 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==33){strcpy(fplace,token);scaner();}else if(syn==34){itoa(sum,fplace,10);scaner();}else if(syn==48){scaner();fplace=expression();if(syn==49)scaner();else{printf("缺‘)’错误!!\n");kk=1;flag++;}}else{printf("表达式错误!!\n");kk=1;flag++;}return(fplace);
}