实验 6 简单中间代码生成
- 格式:doc
- 大小:170.50 KB
- 文档页数:10
一、实验目的1. 理解编译原理中中间代码生成的基本概念和作用。
2. 掌握中间代码生成的常用算法和策略。
3. 提高对编译器构造的理解和实际操作能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:Java3. 开发工具:Eclipse三、实验内容1. 中间代码生成的基本概念2. 中间代码的表示方法3. 中间代码生成算法4. 实现一个简单的中间代码生成器四、实验步骤1. 了解中间代码生成的基本概念中间代码生成是编译过程中的一个重要环节,它将源程序转换成一种中间表示形式,便于后续的优化和目标代码生成。
中间代码生成的目的是提高编译器的灵活性和可维护性。
2. 研究中间代码的表示方法中间代码通常采用三地址代码(Three-Address Code,TAC)表示。
TAC是一种低级表示,由三个操作数和一个操作符组成,例如:(t1, t2, t3) = op,其中t1、t2、t3为临时变量,op为操作符。
3. 学习中间代码生成算法中间代码生成算法主要包括以下几种:(1)栈式中间代码生成算法(2)归约栈中间代码生成算法(3)递归下降中间代码生成算法4. 实现一个简单的中间代码生成器本实验采用递归下降中间代码生成算法,以一个简单的算术表达式为例,实现中间代码生成器。
(1)定义语法规则设表达式E由以下语法规则表示:E → E + T | E - T | TT → T F | T / F | FF → (E) | i(2)设计递归下降分析器根据语法规则,设计递归下降分析器,实现以下功能:①识别表达式E②识别项T③识别因子F(3)生成中间代码在递归下降分析器中,针对不同语法规则,生成相应的中间代码。
例如:当遇到表达式E时,生成以下中间代码:(t1, t2, t3) = op1(t1, t2) // op1表示加法或减法(t4, t5, t6) = op2(t4, t5) // op2表示乘法或除法(t7, t8, t9) = op3(t7, t8) // op3表示赋值(4)测试中间代码生成器编写测试用例,验证中间代码生成器的正确性。
中间代码生成实验报告篇一:编译方法实验报告(中间代码生成器)编译方法实验报告XX年10月一、实验目的熟悉算术表达式的语法分析与中间代码生成原理。
实验内容二、(1)设计语法制导翻译生成表达式的四元式的算法;(2)编写代码并上机调试运行通过。
输入——算术表达式;输出——语法分析结果;相应的四元式序列。
(3)设计LL(1)分析法或LR(0)分析法的属性翻译文法,并根据这些属性翻译文法,使用扩展的语法分析器实现语法制导翻译。
三、实验原理及基本步骤●算术表达式文法:G(E):E ? E ω0 T | TT ? T ω1 F | FF ? i | (E)●文法变换:G’(E) E ? T {ω0 T(本文来自:小草范文网:中间代码生成实验报告)}T ? F {ω1 F}F ? i | (E)●属性翻译文法:E ? T {ω0 “push(SYN, w)” T “QUAT”}T ? F {ω1 “push(SYN, w)” F “QUAT”}F ? i “push(SEM, entry(w))” | (E)其中:push(SYN, w) —当前单词w入算符栈SYN;push(SEM, entry(w)) —当前w在符号表中的入口值压入语义栈SEM;QUAT —生成四元式函数i.T = newtemp;ii.QT[j] =( SYN[k], SEM[s-1], SEM[s], T); j++;iii.pop( SYN, _ ); pop( SEM, _ ); pop( SEM, _ );push( SEM, T );●递归下降子程序:数据结构:SYN —算符栈;SEM —语义栈;四、数据结构设计使用递归的结构进行四元式的设计,同时,运用堆栈结构将四元式的输出序列打印出来while ( exp[i]=='+' || exp[i]=='-'){syn[++i_syn]=exp[i];//push(SYN,w)i++; //read(w)T();quat();}while ( exp[i]=='*' || exp[i]=='/'){syn[++i_syn]=exp[i];//push(SYN,w)i++; //read(w)F();quat();}void quat(){strcpy(qt[j],"(, , , )");//QT[j]:=(SYN[k],SEM[s-1],SEM[s],temp);qt[j][1]=syn[i_syn];qt[j][3]=sem[i_sem-1];qt[j][5]=sem[i_sem];qt[j][7]=temp;j++;i_syn--;//pop(SYN);i_sem--;//pop(SEM);i_sem--;//pop(SEM);sem[++i_sem]=temp; //push(SEM,temp); temp++;}五、关键代码分析(带注释)及运行结果#include#include "string.h"#include "stdio.h"using namespace std;char syn[10]; //文法符号栈int i_syn;char sem[10]; //运算对象栈int i_sem;char exp[50]; //算术表达式区int i;char qt[30][15];//四元式区int j=0;char temp='q'; //临时变量,取值为r--z int E();int T();int F();void quat();//生成四元式函数int main(int argc, char* argv[]){printf("please input your expression:"); scanf("%s",exp); //输入四元式i=0; //read(w)E();if (exp[i]=='\0')for (i=0;i printf("%s\n",qt[i]);elseprintf("err");return 0;}int E(){T();while ( exp[i]=='+' || exp[i]=='-'){syn[++i_syn]=exp[i];//push(SYN,w)i++; //read(w)T();quat();}return 1;}int T(){F();while ( exp[i]=='*' || exp[i]=='/'){syn[++i_syn]=exp[i];//push(SYN,w)i++; //read(w)F();quat();}return 1;}int F(){if ( exp[i]=='('){i++; //read(w)E();if ( exp[i]!=')'){printf("err");return 0;}}else if ((exp[i]>='a' && exp[i]='0' && exp[i] sem[++i_sem]=exp[i]; } //push(SEM,w)else{printf("err");return 0;}i++; //read(w)return 1;}void quat(){strcpy(qt[j],"( , , , )");//QT[j]:=(SYN[k],SEM[s-1] ,SEM[s],temp);qt[j][1]=syn[i_syn];qt[j][3]=sem[i_sem-1];qt[j][5]=sem[i_sem];qt[j][7]=temp;j++;i_syn--; //pop(SYN);i_sem--; //pop(SEM);i_sem--; //pop(SEM);sem[++i_sem]=temp;//push(SEM,temp);temp++;}篇二:中间代码生成实验报告一、实验目的通过在实验二的基础上,增加中间代码生成部分,使程序能够对实验二中的识别出的赋值语句,if语句和while语句进行语义分析,生成四元式中间代码。
武夷学院实验报告课程名称:编译原理项目名称:编写中间代码生成程序二、实验过程记录1:(一)实验目的:在分析理解PL/0编译程序的基础上,对其词法分析程序、语法分析程序和语义处理程序进行部分修改扩充。
(二)实验内容:对PL/0语言作如下功能扩充:(1)扩充条件语句的功能使其为:if <条件> then <语句>[else <语句>](2)增加repeat语句,格式为:repeat <语句> {; <语句>} until <条件>(三)实验过程语句语法描述图:1注:实验过程记录要包含实验目的、实验原理、实验步骤,页码不够可自行添加。
EBNF表示:<程序>::= <分程序>.<分程序>::= [<常量说明部分>][<变量说明部分>][<过程说明部分>]<语句> <常量说明部分>::= const<常量定义>{,<常量定义>};<常量定义>::= <标识符>=<无符号整数><无符号整数>::= <数字>{<数字>}<标识符>::= <字母>{<字母>|<数字>}<变量说明部分>::= var<标识符>{, <标识符>};<过程说明部分>::= <过程首部><分程序>{;<过程说明部分>}<过程首部>::= procedure<标识符>;<语句> ::= <赋值语句>|<条件语句>|<当循环语句>|<过程调用语句><复合语句>|<读语句>|<写语句>|<空><赋值语句>::= <标识符> := <表达式><表达式> ::= [+|-]<项>{<加法运算符><项>}<项>::= <因子>{<乘法运算符><因子>}<因子>::= <标识符>|<无符号整数>| ‘ ( ’ <表达式> ‘ ) ’<加法运算符>::= +|-<乘法运算符>::= *|/<条件>::= <表达式><关系运算符><表达式>|odd<表达式>程序描述图:三、实验结果与讨论:2实验结果:实验小结:通过在PL/0的编译程序的实验中,认识了许多关于中间代码生成的知识,掌握了中间代码中的作用所谓“中间代码”是一种结构简单、含义明确的记号系统,这种记号系统复杂性介于源程序语言和机器语言之间,容易将它翻译成目标代码,产生中间代码的过程叫中间代码生成。
一、实验目的通过在实验二的基础上,增加中间代码生成部分,使程序能够对实验二中的识别出的赋值语句,if语句和while语句进行语义分析,生成四元式中间代码。
二、实验方法实验程序由c语言完成,在Turboc 2.0环境中调试通过。
语义分析程序的基本做法是对文法中的每个产生式分别编写一个语义分析子程序,当程序语法部分进行推倒或规约时,就分别调用各自的语义分析程序。
当语法分析结束时,语义分析也就结束了。
在本实验程序中,当语法分析部分识别出语法正确的句子时,就进入content函数(当语法分析识别出不正确的句子时,不进入content函数,也就是不进行语义分析),然后根据句子的类型进行分类,进入不同的语义处理部分。
对于赋值语句,关键是产生正确的处理算术表达式E的四元式。
程序中的ec函数的功能就是产生算术表达式的四元式,在ec函数中使用了两个栈idshed,opshed,分别是算术表达式的数据栈和符号栈。
每次提取一个数字和一个算符,然后将算符与与栈顶算符进行优先级比较,优先级高则将单前数字和算符进栈,低或者相等的话则将当前栈顶元素进行合并,产生四元式。
直至整个算术表达式结束。
其中还有一些细节问题,具体的做法可以参看程序。
对于实验给定的if语句的文法格式,条件判断式C只中可能是>或者<=两种关系,不可能是布尔表达式,这样程序就简单的多了。
通过ec函数可以产生条件判断式C中的E的四元式,然后只要加上转向四元式就可以了。
本实验程序中只给出真出口的转向四元式,没有给出假出口的转向四元式,这在实际中是不可以的,但在本实验中,实际上是对每条独立的语句进行语法分析,给出假出口转向四元式实际上意义不大,而且假出口转向语句的转移目标必须要到整个语句分析结束以后才可以知道,这样就要建立栈,然后回填,这样会使程序复杂很多,所以没有加上假出口转向四元式。
对于while语句,具体的做法和if语句差不多,所不同的是当while语句结束时,要多出一条无条件转向四元式,重新转到条件判断式C的第一条四元式。
中间代码生成实验报告《中间代码生成实验报告》摘要:本实验旨在通过编写中间代码生成程序,实现将高级语言源代码转换为中间代码的功能。
通过实验,我们掌握了中间代码的生成过程和相关算法,并对编译器的工作原理有了更深入的理解。
本实验采用了C语言作为源语言,通过词法分析、语法分析和语义分析,生成了对应的中间代码。
一、实验目的1. 理解编译器的工作原理,掌握中间代码生成的基本概念和方法;2. 掌握中间代码的表示方法和生成算法;3. 通过实践,提高编程能力和对编译原理的理解。
二、实验环境1. 操作系统:Windows 10;2. 编程语言:C语言;3. 开发工具:Visual Studio 2019。
三、实验内容1. 设计并实现中间代码生成程序,将给定的C语言源代码转换为中间代码;2. 实现词法分析、语法分析和语义分析,生成对应的中间代码;3. 测试程序,验证中间代码的正确性和有效性。
四、实验步骤1. 设计中间代码的表示方法,包括四元式、三地址码等;2. 实现词法分析器,将源代码转换为词法单元序列;3. 实现语法分析器,将词法单元序列转换为语法树;4. 实现语义分析器,对语法树进行语义检查并生成中间代码;5. 测试程序,验证中间代码的正确性和有效性。
五、实验结果经过测试,中间代码生成程序能够正确地将C语言源代码转换为中间代码,并且生成的中间代码能够正确地表达源代码的语义和逻辑结构。
通过实验,我们成功地掌握了中间代码的生成过程和相关算法,加深了对编译器工作原理的理解。
六、实验总结通过本次实验,我们深入了解了编译器的工作原理和中间代码生成的基本概念和方法。
通过实践,我们提高了编程能力和对编译原理的理解,为进一步深入学习编译原理和设计编译器打下了良好的基础。
希望通过不断的实践和学习,能够更加熟练地掌握编译原理的知识,为今后的学习和工作打下坚实的基础。
竭诚为您提供优质文档/双击可除编译原理中间代码生成实验报告篇一:编译原理-分析中间代码生成程序实验报告课程名称编译原理实验学期至学年第学期学生所在系部年级专业班级学生姓名学号任课教师实验成绩计算机学院制开课实验室:年月日篇二:编译原理实验中间代码生成实验四中间代码生成一.实验目的:掌握中间代码的四种形式(逆波兰式、语法树、三元式、四元式)。
二.实验内容:1、逆波兰式定义:将运算对象写在前面,而把运算符号写在后面。
用这种表示法表示的表达式也称做后缀式。
2、抽象(语法)树:运算对象作为叶子结点,运算符作为内部结点。
3、三元式:形式序号:(op,arg1,arg2)4、四元式:形式(op,arg1,arg2,result)三、以逆波兰式为例的实验设计思想及算法(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。
(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。
(4)如果不是数字,该字符则是运算符,此时需比较优先关系。
做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。
如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。
倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。
(5)重复上述操作(1)-(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。
四、程序代码://这是一个由中缀式生成后缀式的程序#include#include#include#include#definemaxbuffer64voidmain(){chardisplay_out(charout_ch[maxbuffer],charch[32]);//intcaculate_array(charout_ch[32]);staticinti=0;staticintj=0;charch[maxbuffer],s[maxbuffer],out[maxbuffer];cout cin>>ch;for(i=0;i {out[i]=ch[i];}cout while(out[j]!=#)cout j++;}cout display_out(s,out);//caculate_array;}chardisplay_out(charout_ch[32],charch[]) {inttop=-1;inti=0,data[maxbuffer],n;intj=0;charsta[20];while(ch[i]!=#){if(isalnum(ch[i])){while(isalnum(ch[i])){out_ch[j]=ch[i];j++;i++;}out_ch[j]=;j++;else{switch(ch[i]){case+:case-:if(sta[top]==(||top==-1) {top++;sta[top]=ch[i];i++;}else{//j--;out_ch[j]=sta[top];j++;top--;//i++;}break;//break;case*:case/:if(sta[top]==*/) {out_ch[j]=sta[top];j++;//i++;top--;}else{top++;sta[top]=ch[i];i++;}break;//break;case(:top++;sta[top]=ch[i];i++;break;case):if(sta[top]==() {top--;i++;}if(top==-1){//cout }else{//while(sta[top]!=?(?){ out_ch[j]=sta[top];top--;j++;//}break;}break;/*case?#?:out_ch[j]=?#?; j++;break;*/default:cout ch[i]=#;j=0;break;}}}while(top!=-1){out_ch[j]=sta[top];j++;top--;}out_ch[j]=#;n=0;co(:编译原理中间代码生成实验报告)utwhile(out_ch[n]!=#){cout n++;}cout j=0;returnout_ch[maxbuffer];}五、实验结果:要求:自己给出3个测试用例,观察结果。
实验 6 简单中间代码生成1、实验目的:综合运用所学知识,集成词法分析、符号表管理等程序的成果,在语法分析和文法属性计算的基础上,完成中间代码的生成工作。
让学生全面了解一个编译器工作的全过程,真正全面掌握编译的思想和方法。
2、实验的基本原理对于一个给定文法,通过改写文法,使其满足LR(1)文法的要求,根据语义确定文法符号的属性,确定语义规则或翻译方案;根据文法特点构造LR(1)分析表,进而构造语法分析和属性计算程序。
分析程序在分析表的驱动下,完成对给定的句子进行语法分析和属性计算工作,最后生成三地址中间代码序列。
3、实验内容及要求a.实验所用文法如下。
statmt → id = expexp → exp addop term | termaddop →+ | -term→ term mulop factor | factormulop → * | /factor → ( exp ) | id | num其中id和num为实验二中定义的标识符和常数,因此这里还需要一个小的词法分析器来得到id和num。
b.构造文法LR(1)项目集,构造ACTION和GOTO矩阵,确认文法满足LR(1)文法要求。
c.按一般高级语言赋值语句的计算要求定义文法的属性和语义规则,属性计算的结果是将给定赋值语句翻译成三地址代码序列,并输出此序列。
d.从数据文件中读出赋值语句,并对其进行语法分析,对合法语句,输出其翻译结果。
e.实验数据文件中应该有多个语句,可能有正确的也应该有错误的语句;语句中的表达式有形式简单的也应该有复杂的。
每个表达式写在一行,以$结束。
4、实验步骤准备好用于实验的赋值语句序列,并存储在文件中。
a.编写单词分析子程序,能从源程序中分离出单词(包括标识符和常数);词法分析器以子程序形式出现,当需要进行词法分析时进行调用;b.构造分析表,确认上述文法为LR(1)文法,定义属性和语义规则。
c.确定临时变量生成方案,构造其生成程序。
d.编写自下而上分析程序,这个程序应该能够识别正确和错误的语句;同时进行语义计算。
e.逐个读入语句,给出正误评判,并输出正确语句翻译结果。
问题求解1.拓广方法由于文法的开始符号只在方法中出现一次,并不在产生式右部出现,所以方法可以不用扩展。
1)statmt → id = exp2)exp → exp addop term3)exp → term4)addop → +5)addop → -6)term→ term mulop factor7)term→ factor8)mulop → *9)mulop → /10)factor → ( exp )11)factor → id12)factor → num2.构造LR(1)项目集I0:statmt →·id = exp , $I1: goto( I0 , id )statmt →id·= exp , $I2: goto( I1 , = )statmt →id =·exp , $exp →·exp addop term , $|+|-exp →·term , $|+|-term→·term mulop factor , $|+|-|*|/term→·factor , $|+|-|*|/factor →·( exp ) , $|+|-|*|/factor →·id , $|+|-|*|/factor →·num , $|+|-|*|/I3: goto( I2 , exp )statmt →id = exp·, $exp →exp ·addop term , $|+|-addop →·+ ,(|id|numaddop →·- ,(|id|numI4: goto( I2 , term )exp → term· , $|+|-term→ term· mulop factor , $|+|-|*|/mulop →·* ,(|id|nummulop →·/ ,(|id|numI5: goto( I2 , factor )term→factor· , $|+|-|*|/I6: goto( I2 ,( )factor → (·exp) , $|+|-|*|/exp →·exp addop term , )|+|-exp →·term , )|+|-term→·term mulop factor , )|+|-|*|/term→·factor , )|+|-|*|/factor →·( exp ) , )|+|-|*|/factor →·id , )|+|-|*|/factor →·num , )|+|-|*|/I7: goto( I2 , id )factor →id· , $|+|-|*|/I8: goto( I2 , num )factor →num· , $|+|-|*|/I9; goto( I3 , addop )exp → exp addop· term , $|+|-term→·term mulop factor , $|+|-|*|/term→·factor , $|+|-|*|/factor →·( exp ) , $|+|-|*|/factor →·id , $|+|-|*|/factor →·num , $|+|-|*|/I10: goto(I3 , + )addop → +· ,(|id|numI11: goto(I3 , - )addop → -· ,(|id|numI12: goto(I4 , mulop )term→ term mulop· factor , $|+|-|*|/ factor →·( exp ) , $|+|-|*|/factor →·id , $|+|-|*|/factor →·num , $|+|-|*|/I13: goto( I4 , * )mulop → *· ,(|id|numI14: goto( I4 , / )mulop → /· ,(|id|numI15: goto( I6 , exp )factor → (exp·) , $|+|-|*|/exp → exp· addop term , )|+|-addop →·+ ,(|id|numaddop →·- ,(|id|numI16: goto( I6 , term )exp → term· , )|+|-term→ term· mulop factor , )|+|-|*|/ mulop →·* ,(|id|nummulop →·/ ,(|id|numI17: goto( I6 , factor )term→ factor· , )|+|-|*|/I18: goto( I6 , ( )factor → (·exp) , )|+|-|*|/exp →·exp addop term , )|+|-exp →·term , )|+|-term→·term mulop factor , )|+|-|*|/term→·factor , )|+|-|*|/factor →·( exp ) , )|+|-|*|/factor →·id , )|+|-|*|/fac tor →·num , )|+|-|*|/I19: goto( I6 , id )factor → id· , )|+|-|*|/I20: goto( I6 , num )factor → num· , )|+|-|*|/I21: goto( I9 , term )exp → exp addop term· , $|+|-term→term ·mulop factor , $|+|-|*|/mulop →·* ,(|id|nummulop →·/ ,(|id|numgoto( I9 , factor ) == I5goto( I9 , ( ) == I6goto( I9, id ) == I7goto( I9, num ) == I8I22: goto( I12 , factor )term→ term mulop factor· , $|+|-|*|/ goto( I12 , ( ) == I6goto( I12, id ) == I7goto( I12, num ) == I8I23: goto( I15 , addop )exp → exp addop· term , )|+|-term→·term mulop factor , )|+|-|*|/term→·factor , )|+|-|*|/factor →·( exp ) , )|+|-|*|/factor →·id , )|+|-|*|/factor →·num , )|+|-|*|/I24: goto( I15 , ) )factor → ( exp ) · , $|+|-|*|/goto( I15 , + ) == I10goto( I15 , - ) == I11I25: goto( I16 , mulop )term→ term mulop· factor , )|+|-|*|/ factor →·( exp ) , )|+|-|*|/factor →·id , )|+|-|*|/factor →·num , )|+|-|*|/goto( I16 , * ) == I13goto( I16 , / ) == I14I26: goto( I18 , exp )factor → (e xp·) , )|+|-|*|/exp →exp· addop term , )|+|-addop →·+ ,(|id|numaddop →·- ,(|id|numgoto( I18 , term ) == I16goto( I18 , factor ) == I17goto( I18 , ( ) == I18goto( I18 , id ) == I19goto( I18 , num ) == I20goto( I21 , mulop ) ==I12goto( I21 , * ) ==I13goto( I21 , / ) ==I14I27: goto( I23 , term )exp → exp addop term· , )|+|-term→ term· mulop factor , )|+|-|*|/ mulop →·* ,(|id|nummulop →·/ ,(|id|numgoto( I23 , factor ) == I17goto( I23 , ( ) == I18goto( I23 , id ) == I19goto( I23 , num ) == I20I28: goto( I25 , factor )term→ term mulop factor· , )|+|-|*|/goto( I25 , ( ) == I18goto( I25 , id ) == I19goto( I25 , num ) == I20I29: goto( I26 , ) )factor → ( exp )· , )|+|-|*|/goto( I26 , addop ) == I23goto( I26 , + ) == I10goto( I26 , - ) == I11goto( I27 , mulop ) == I25goto( I27 , * ) == I13goto( I27 , / ) == I143.,画出自动机5.判断是否是LR(1)文法由于按照LR(1)分析表的构造方法所构造出的分析表中,每一项至多只有一个动作,所以该文法是LR(1)的,可以用LR(1)方法分析。