《编译原理》课程实验报告
实验名称:语义分析
姓名:
学号:
地点: 四教302
教师:
院系:
专业: 计算机科学与技术15-1
一. 实验目的
通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。
二. 实验内容
采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。
输入:begin a:=2+3*4;x:=(a+b)/c end #
输出:(1)t1=3*4 (2)t2=2+t1 (3)a=t2
(4)t3=a+b (5)t4=t3/c (6) x=t4
三.实验步骤
|
代码如下:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
char prog[100],token[8],ch;
char*rwtab[6]={"begin","if","then","while","do","end"};
int syn,p,m,n,sum,q;
int kk;
struct { char result1[8];
char ag11[8];
char op1[8];
char ag21[8];
} quad[20];
char *factor();
char *expression();
int yucu();
char *term();
int statement();
int lrparser();
char *newtemp();
scaner();
emit(char *result,char *ag1,char *op,char *ag2);
main()
{ int j;
q=p=kk=0;
printf("院系:计算机与通信工程学院\n");
printf("班级:计算机科学与技术15-01\n");
printf("姓名:汪笛\n");
printf("学号:541507010139\n");
printf("\nplease input a string (end with '#'): ");
do
{scanf("%c",&ch);
prog[p++]=ch;
}while(ch!='#');
p=0;
scaner();
lrparser();
if(q>19)printf(" to long sentense!\n");
else for (j=0;j<q;j++)printf(" %s = %s %s %s\n\n",quad[j].result1,quad[j].ag11,quad[j].op1,quad[j].ag21);
//getch();
}
int lrparser()
{ int schain=0;
kk=0;
if (syn==1)
{ scaner();
schain=yucu();/*调用语句串分析函数进行分析*/
if(syn==6)
{ scaner();
if((syn==0)&&(kk==0)) printf("Success!\n");
}
else { if(kk!=1)printf("short of 'end' !\n");
kk=1;
// getch();
exit(0);
}
}
else { printf("shortof 'begin' !\n");
kk=1;
// getch();
exit(0);
}
return (schain);
}
int yucu()
{ int schain=0;
schain=statement();/*调用语句分析函数进行分析*/
while(syn==26)
{ scaner();
schain=statement();/*调用语句分析函数进行分析*/
}
return (schain);
}
int statement()
{ char tt[8],eplace[8];
int schain=0;
if (syn==10)
{ strcpy(tt,token);
scaner();
if(syn==18)
{ scaner();
strcpy(eplace,expression());
emit(tt,eplace,"","");
schain=0;
}
else { printf("shortof sign ':=' !\n");
kk=1;
// getch();
exit(0);
}
return (schain);
}
}
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());/*调用term分析产生表达式计算的第一项eplace*/
while((syn==13)||(syn==14))
{ if(syn==13)strcpy(tt,"+");
elsestrcpy(tt,"-");
scaner();
strcpy(ep2,term());/*调用term分析产生表达式计算的第二项ep2*/
strcpy(tp,newtemp());/*调用newtemp产生临时变量tp存储计算结果*/
emit(tp,eplace,tt,ep2);/*生成四元式送入四元式表*/
strcpy(eplace,tp);
}
return (eplace);
}
char *term()/*仿照函数expression编写*/
{ 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)strcpy(tt,"*");
elsestrcpy(tt,"/");
scaner();
strcpy(ep2,factor());
strcpy(tp,newtemp());
emit(tp,eplace,tt,ep2);
strcpy(eplace,tp);
}
return (eplace);
}
char *factor()
{ char *fplace;
fplace=(char *)malloc(12);
strcpy(fplace,"");
if(syn==10)
{ strcpy(fplace,token);/*将标识符token的值赋给fplace*/
scaner();
}
else if(syn==11)
{ itoa(sum,fplace,10);
scaner();
}
else if(syn==27)
{ scaner();
fplace=expression();/*调用expression分析返回表达式的值*/
if(syn==28) scaner();
else { printf("erroron ')' !\n");
kk=1;
// getch();
exit(0);
}
}
else { printf("error on '(' !\n");
kk=1;
// getch();
exit(0);
}
return (fplace);
}
char *newtemp()
{ char *p;
char m[8];
p=(char *)malloc(8);
kk++;
itoa(kk,m,10);
strcpy(p+1,m);
p[0]='t';
return(p);
}
scaner()
{ sum=0;
for(m=0;m<8;m++)token[m++]=NULL;
m=0;
ch=prog[p++];
while(ch=='')ch=prog[p++];
if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))
{while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9')))
{token[m++]=ch;
ch=prog[p++];
}
p--;
syn=10;
token[m++]='\0';
for(n=0;n<6;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';
ch=prog[p++];
}
p--;
syn=11;
}
else switch(ch)
{ case '<':m=0;
ch=prog[p++];
if(ch=='>')
{ syn=21;
}
else if(ch=='=')
{ syn=22;
}
else
{ syn=20;
p--;
}
break;
case '>':m=0;
ch=prog[p++];
if(ch=='=')
{ syn=24;
}
else
{ syn=23;
p--;
}
break;
case ':':m=0;
ch=prog[p++];
if(ch=='=')
{ syn=18; }
else
{ syn=17;
p--;
}
break;
case '+': syn=13; break;
case '-': syn=14; break;
case '*': syn=15;break;
case '/': syn=16;break;
case '(': syn=27;break;
case ')': syn=28;break;
case '=': syn=25;break;
case ';': syn=26;break;
case '#': syn=0;break;
default: syn=-1;break;
}
}
emit(char *result,char *ag1,char *op,char *ag2)
{
strcpy(quad[q].result1,result);
strcpy(quad[q].ag11,ag1);
strcpy(quad[q].op1,op);
strcpy(quad[q].ag21,ag2);
q++;
}
输出结果为:
四.总结与回顾
本次实验做的是语法分析子程序,采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。实现的过程也是不断的在网上查找资料,并将合适的下载下来进行参考。实现的过程也是理解的过程,不断完善才可以不断加强理解。
实验报告成绩评定表
评定项目 | 内 容 | 满 分 | 评 分 | 总 分 |
实验态度 | 态度端正、遵守纪律、出勤情况 | 20 |
|
|
实验过程 | 按要求完成算法设计、代码书写、注释清晰、运行结果正确 | 40 |
| |
报告撰写 | 报告书写规范、内容条理清楚、表达准确规范、上交及时。 | 40 |
| |
评语:
指导老师签字: 年 月 日 |