编译原理 语义分析

编译原理实验报告

姓名:闫梦丽班级:软件工程学号:日期: 语 义 分 析 器

0901 0908010101 2012年4月

1.题目要求:

1.1实验目的

通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。 1.2实验原理

采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。

2.算法分析

2.1主程序示意图

置初值调用scaner调用lrparser输出四元组

结束

图1

2.2设置语义过程

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); }

2.3函数lrparser在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。在实验中我们只对表达式、赋值语句进行翻译。

3、实验步骤 #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("\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"); elsefor(j=0;j

//输出

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("short of 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,"+"); //操作符

tt= ‘+’或者‘—’

else strcpy(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,"*"); else strcpy(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); scaner(); //读下一个单词符号 }

else if(syn==11) { itoa(sum,fplace,10); scaner(); //读下一个单词符号

} else if(syn==27) { scaner(); //读下一个单词符号 fplace=expression(); //调用expression分析返回表达式的值 if(syn==28) scaner(); //读下一个单

词符号

else { printf("error on ')' !\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

ch=prog[p++];

while(ch==' ')ch=prog[p++];

if(((ch='a'))||((ch='A')))

{ while(((ch='a'))||((ch='A'))||((ch>='0')&&(ch

p--; syn=10;

token[m++]='\0'; for(n=0;n

if(strcmp(token,rwtab[n])==0)

{ syn=n+1; break; } }

else if((ch>='0')&&(ch='0')&&(ch

else switch(ch) { case '') { 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++; }

4、实验结果

实验的输入和输出:

输入是语法分析提供的正确的单词串,输出为三地址指令形式的四元式序列。 例如:对于语句串

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

编译原理实验报告

姓名:闫梦丽班级:软件工程学号:日期: 语 义 分 析 器

0901 0908010101 2012年4月

1.题目要求:

1.1实验目的

通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。 1.2实验原理

采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。

2.算法分析

2.1主程序示意图

置初值调用scaner调用lrparser输出四元组

结束

图1

2.2设置语义过程

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); }

2.3函数lrparser在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。在实验中我们只对表达式、赋值语句进行翻译。

3、实验步骤 #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("\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"); elsefor(j=0;j

//输出

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("short of 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,"+"); //操作符

tt= ‘+’或者‘—’

else strcpy(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,"*"); else strcpy(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); scaner(); //读下一个单词符号 }

else if(syn==11) { itoa(sum,fplace,10); scaner(); //读下一个单词符号

} else if(syn==27) { scaner(); //读下一个单词符号 fplace=expression(); //调用expression分析返回表达式的值 if(syn==28) scaner(); //读下一个单

词符号

else { printf("error on ')' !\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

ch=prog[p++];

while(ch==' ')ch=prog[p++];

if(((ch='a'))||((ch='A')))

{ while(((ch='a'))||((ch='A'))||((ch>='0')&&(ch

p--; syn=10;

token[m++]='\0'; for(n=0;n

if(strcmp(token,rwtab[n])==0)

{ syn=n+1; break; } }

else if((ch>='0')&&(ch='0')&&(ch

else switch(ch) { case '') { 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++; }

4、实验结果

实验的输入和输出:

输入是语法分析提供的正确的单词串,输出为三地址指令形式的四元式序列。 例如:对于语句串

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


相关内容

  • 编译原理--教学大纲
  • <计算机编译原理>课程大纲 一.适用对象 本课程适用于计算机科学与技术以及相关专业的网络教育.成人教育学生. 二.课程性质 本课程是计算机科学与技术专业学生的专业基础课. 编译原理课程是计算机专业的一门主干课程.课程介绍程序设计语言编译程序构造的一般原理.基本设计方法.主要实现技术和一些 ...

  • 编译原理试题1
  • 课程测试试题(A卷) 一.填空 (30分) 1.将编译过程的各阶段划分为前端或后端和将编译程序分遍的主要参考因素都是( )和( )的特征. 2.( )是一种语法分析程序的自动构造工具,用它可以直接构造各种语言的语法分析器:而( )是一种词法分析程序的自动构造工具,用它可以直接构造各种语言的词法分析器 ...

  • 编译原理名词解释
  • .名词解释: 1)前缀 答:前缀--是指符号串任意首部. 2)可归前缀 答:可归前缀--是指规范句型的一个前缀,这种前缀包含句柄且不含句柄之后的任何符号. 3)活前缀 答:活前缀--规范句型的一个前缀,这种前缀不含句柄之后的任何符号. 或给定文法规范句型的可归前缀的任意首部. 4)简单短语 答:简单 ...

  • 编译原理论文
  • 编译原理心得体会 编译原理是计算机专业的一门重要专业课,旨在介绍编译程序构造的一般原理和基本方法,在计算机本科教学中占有十分重要的地位. 该课程理论性与实践性都很强,我们在学习 是普遍感到内容非常抽象,不易理解,内容多且繁琐,难以完整.全面地掌握编译原理的有关知识,更不用说灵活运用编译原理知识从事相 ...

  • 合肥工业大学编译原理课程设计
  • 关于<编译原理>课程设计的有关说明 <编译原理>是计算机专业的一门重要的专业课程,其中包含大量软件设计思想.大家通过课程设计,实现一些重要的算法,或设计一个完整的编译程序模型,能够进一步加深理解和掌握所学知识,对提高自己的软件设计水平具有十分重要的意义.大家在进行课程设计时, ...

  • 编译原理试题3
  • 课程测试试题(B卷) 一.判断(15分) 1.编译程序是一种语言翻译程序,它将源语言程序翻译成功能等价的目标语言程序. 2.所谓规则或产生式是指形如α→β或α::=β的(α,β)有序对,其中α是字母表V的正闭包元素,而β是字母表V的闭包元素. 3.设文法G =(VN,VT,P,S),若P中的每一个规 ...

  • 张瑞编译原理实验报告
  • 黑龙江大学 "编译原理课程设计"读书报告 学院 年级 专业 学号 姓名 报告日期 成绩 软件学院 2012级 软件工程 20122515 张瑞 2014年6月28日 黑龙江大学计算机科学技术学院 黑龙江大学软件学院 概述 "编译原理"课程是计算机专业中一门重要 ...

  • 编译原理(选择.填空.简答)题
  • 一.是非题(下列各题,你认为正确的,请在题干的括号内打"√",错的打"×".每题1分, 共5分) 1.算符优先关系表不一定存在对应的优先函数. √ 2.数组元素的地址计算与数组的存储方式有关.√ 3.仅考虑一个基本块,不能确定一个赋值是否真是无用的.√ 4.每 ...

  • 北邮研究生 高级计算机系统结构
  • 计算机系统结构的发展历程 课程:高级计算机系统结构 姓名: 学号: 班级: 2015年12月 一. 计算机系统结构 随着当今社会和科技的飞速发展,自四十年代计算机问世以来,计算机科学更是发展迅速,应用领域不断扩展计算机的普及和广泛应用,现代社会正朝着高度信息化,自动化方向发展.计算机逐渐成为社会必不 ...