中间代码生成实验报告doc

合集下载

中间代码生成实验报告

中间代码生成实验报告

一、实验目的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)测试中间代码生成器编写测试用例,验证中间代码生成器的正确性。

中间代码生成实验报告

中间代码生成实验报告

中间代码生成实验报告《中间代码生成实验报告》摘要:本实验旨在通过编写中间代码生成程序,实现将高级语言源代码转换为中间代码的功能。

通过实验,我们掌握了中间代码的生成过程和相关算法,并对编译器的工作原理有了更深入的理解。

本实验采用了C语言作为源语言,通过词法分析、语法分析和语义分析,生成了对应的中间代码。

一、实验目的1. 理解编译器的工作原理,掌握中间代码生成的基本概念和方法;2. 掌握中间代码的表示方法和生成算法;3. 通过实践,提高编程能力和对编译原理的理解。

二、实验环境1. 操作系统:Windows 10;2. 编程语言:C语言;3. 开发工具:Visual Studio 2019。

三、实验内容1. 设计并实现中间代码生成程序,将给定的C语言源代码转换为中间代码;2. 实现词法分析、语法分析和语义分析,生成对应的中间代码;3. 测试程序,验证中间代码的正确性和有效性。

四、实验步骤1. 设计中间代码的表示方法,包括四元式、三地址码等;2. 实现词法分析器,将源代码转换为词法单元序列;3. 实现语法分析器,将词法单元序列转换为语法树;4. 实现语义分析器,对语法树进行语义检查并生成中间代码;5. 测试程序,验证中间代码的正确性和有效性。

五、实验结果经过测试,中间代码生成程序能够正确地将C语言源代码转换为中间代码,并且生成的中间代码能够正确地表达源代码的语义和逻辑结构。

通过实验,我们成功地掌握了中间代码的生成过程和相关算法,加深了对编译器工作原理的理解。

六、实验总结通过本次实验,我们深入了解了编译器的工作原理和中间代码生成的基本概念和方法。

通过实践,我们提高了编程能力和对编译原理的理解,为进一步深入学习编译原理和设计编译器打下了良好的基础。

希望通过不断的实践和学习,能够更加熟练地掌握编译原理的知识,为今后的学习和工作打下坚实的基础。

编译原理实验整体(4)语义及中间代码

编译原理实验整体(4)语义及中间代码

编译原理目标代码生成实验报告班级:11203105学号:1120310528姓名:陈向军一、实验目的:通过上机实习,将前面生成的中间代码转化成汇编代码二、实验要求:将前面生成的中间代码转化成汇编代码三、算法思想:与语法制导翻译相结合,将生成的中间代码转化成汇编代码四、语法制导翻译S' -> S ;S -> void main ( ) { decls stmts } ;S -> fun S ;fun -> fun fun ;fun -> funtype function id ( fundecls ) { decls stmts } ;fundecls -> fundecls , fundecl ;fundecls -> fundecl ;fundecl -> type id ;decls -> decls decl ;decls -> decl ;decl -> type ids @ ;type -> float ;type -> int ;funtype -> float ;funtype -> int ;ids -> ids , N6 id ;ids -> id ;ids -> id [ num ] = { nums } ;nums -> nums , num ;nums -> num ;nums -> xiao ;stmts -> stmts stmt ;stmts -> stmt ;stmt -> return expr @ ;stmt -> asgn @ ;stmt -> iter ;stmt -> { stmts } ;stmt -> continue ;stmt -> break ;expr -> E ;E -> E + T ;E -> E - T ;E -> T ;T -> T * F ;T -> T / F ;T -> T % F ;T -> F ;F -> ( E ) ;F -> num ;F -> xiao ;F -> id ;F -> id [ expr ] ;asgn -> left = expr ;asgn -> left = funid ( funcs ) ;funid -> id ;funcs -> funcs , func ;funcs -> func ;func -> id ;func -> num ;left -> id ;left -> id [ expr ] ;iter -> for ( asgn @ M1 rel @ N4 inc ) N2 stmt ; iter -> while M1 ( rel ) M2 stmt ;M1 -> $ ;M2 -> $ ;N1 -> $ ;N2 -> $ ;N3 -> $ ;N4 -> $ ;N5 -> $ ;N6 -> $ ;rel -> expr op expr ;rel -> ! rel ;rel -> rel o N3 rel ;op -> < ;op -> > ;op -> <= ;op -> >= ;op -> == ;o -> && ;o -> || ;inc -> left ++ ;slct -> if ( rel ) M1 stmt N1 else M2 stmt ;stmt -> printf ( str ) @ ;stmt -> printf ( str , N5 ids ) @ ;stmt -> scanf ( str , & id ) @ ;补充说明:$表示空,@表示语义说明,详见代码。

编译原理中间代码生成实验报告

编译原理中间代码生成实验报告

竭诚为您提供优质文档/双击可除编译原理中间代码生成实验报告篇一:编译原理-分析中间代码生成程序实验报告课程名称编译原理实验学期至学年第学期学生所在系部年级专业班级学生姓名学号任课教师实验成绩计算机学院制开课实验室:年月日篇二:编译原理实验中间代码生成实验四中间代码生成一.实验目的:掌握中间代码的四种形式(逆波兰式、语法树、三元式、四元式)。

二.实验内容: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个测试用例,观察结果。

编译语言-中间代码生成

编译语言-中间代码生成

实验四中间代码生成一、实验内容设计一个程序,该程序能够将形如x = y op z 的简单赋值语句翻译为对应的四元式序列,其中op 可为+、-、*、/等二元运算符。

(可参考实验指导书P163 至P164)。

要求用JA V A语言编程。

例如:若输入赋值语句 a = b + c,则输出如下四元式序列。

二、程序代码InToPost.JAVApackage zlf;import java.io.IOException;public class InToPost {private Stack theStack;private String input;private String output = "";public InToPost(String in) {input = in;int stackSize = input.length();theStack = new Stack(stackSize);}public String doTrans() {for (int j = 0; j < input.length(); j++) {char ch = input.charAt(j);switch (ch) {case'+':case'-':gotOper(ch, 1);break;case'*':case'/':gotOper(ch, 2);break;case'(':theStack.push(ch);break;case')':gotParen(ch);break;default:output = output + ch;break;}}while (!theStack.isEmpty()) {output = output + theStack.pop();}// System.out.println(output);return output;}public void gotOper(char opThis, int prec1) { while (!theStack.isEmpty()) {char opTop = theStack.pop();if (opTop == '(') {theStack.push(opTop);break;}else {int prec2;if (opTop == '+' || opTop == '-')prec2 = 1;elseprec2 = 2;if (prec2 < prec1) {theStack.push(opTop);break;}elseoutput = output + opTop;}}theStack.push(opThis);}public void gotParen(char ch){while (!theStack.isEmpty()) {char chx = theStack.pop();if (chx == '(')break;elseoutput = output + chx;}}class Stack {private int maxSize;private char[] stackArray;private int top;public Stack(int max) {maxSize = max;stackArray = new char[maxSize];top = -1;}public void push(char j) {stackArray[++top] = j;}public char pop() {return stackArray[top--];}public char peek() {return stackArray[top];}public boolean isEmpty() {return (top == -1);}}}package zlf;import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.util.Stack;public class extends JFrame{ private static Stack<String> number = new Stack<String>();private int n = 1;private JButton jbt = new JButton("生成");private JTextArea jta = new JTextArea();private JTextField jtf = new JTextField("A=B+C*D+E",20);private boolean hasError = false;public QuaternaryTypeOfAlgorithm(){JPanel p1 = new JPanel();p1.add(jtf);p1.add(jbt);add(p1,BorderLayout.NORTH);add(new JScrollPane(jta),BorderLayout.CENTER);jbt.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){String equation = jtf.getText().trim();create(equation);number.clear();hasError = false;repaint();}});}public void create(String input){String output;InToPost theTrans = new InToPost(input);output = theTrans.doTrans();try{for(int i = 0 ; i < output.length(); i++){String t = output.substring(i, i+1);if(t.equals("+")){String n1 = number.pop();String n2 = number.pop();String n3 = "T"+n;n++;number.push(n3);jta.append(n-1+": (+,"+n2+","+n1+","+n3+")"+'\n');}else if(t.equals("-")){String n1 = number.pop();String n3 = "T"+n;n++;number.push(n3);jta.append(n-1+": (-,"+n1+","+" "+","+n3+")"+'\n');}else if(t.equals("*")){String n1 = number.pop();String n2 = number.pop();String n3 = "T"+n;n++;number.push(n3);jta.append(n-1+": (*,"+n2+","+n1+","+n3+")"+'\n');}else if(t.equals("/")){String n1 = number.pop();String n2 = number.pop();String n3 = "T"+n;n++;number.push(n3);jta.append(n-1+": (/,"+n2+","+n1+","+n3+")"+'\n');}else if(t.matches("[a-zA-Z0-9=]")){number.push(t);//System.out.println("number:"+t);}}String last2 = number.pop();number.pop();String last1 = number.pop();n++;jta.append(n-1+":(=,"+last2+", ,"+last1+")"+'\n'+'\n'+'\n');}catch(Exception e){hasError = true;}if(hasError||!number.empty()){JOptionPane.showMessageDialog(null, "你输入的算式表达式有错!请重新输入");n umber.clear();}}public static void main(String[] args){QuaternaryTypeOfAlgorithm q = new QuaternaryTypeOfAlgorithm();q.setSize(400,200);q.setTitle("生成四元式序列");q.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);q.setVisible(true);q.setLocationRelativeTo(null);}}三、实验结果。

编译原理实验三:中间代码生成

编译原理实验三:中间代码生成

编译原理——语义分析成员:杨霞 030802107王日日 030802139方艳丽 030802102实验三:语义分析:生成中间代码一、实验目的通过语法制导或翻译模式生成中间代码。

二、实验内容在自底向上语法分析基础上设计语义规则(语法制导翻译),将源程序翻译为四元式输出.三、实验环境Windows microsoft visual c++ 6.0四.实验原理三地址码的几种常见指令:1.X=Y OP Z 的赋值指令,其中OP 是一个双目运算符或逻辑运算符。

2.X= Y 的复制指令。

3.无条件转移指令 GOTO L 把下一步要执行的带有标号L的三地址指令4.IF X GOTO L 或 IF FALSE X GOTO L的条件转移指令5.IF X RELOP Y GOTO L的条件转移指令。

三地址码四元式实验环境:windows microsoft visual c++语法制导定义:控制流语句的语法制导定义:实验代码分析:struct midcode//四元式结构;{int label;//存放标号;char op;//存放操作符;char arg1;//存放操作数1;char arg2;//存放操作数2;char result;//存放目的操作数(转移标号)}m_midcode[100];如何实现语句的跳转:主要利用了语义规则与规约过程的结合;例如:Label为四元式产生的新标号;Mnew 为四元式中最新的标号;case 9:tab1=t-1;while(tab1--){if(m_midcode[tab1].op=='>'&& (int)(m_midcode[tab1].result)==0){m_midcode[tab1].result=(char)m_midcode[tab1+2].label;/E.true=newlabelm_midcode[tab1+1].result=(char)(m_midcode[tab1+2].label+1);/E.false=newlabeltab2=tab1;for(;tab2<t;tab2++)if(m_midcode[tab2].op=='g'&&(int)m_midcode[tab2].result==0)m_midcode[tab2].result=(char)(mnew-1);//S1.next=s2.next=S.nextbreak ;}实验结果:心得体会:四元式序列是编译原理最后一个实验,最后的实验也要建立在之前两个实验的基础上。

哈工大威海编译原理实验三语义分析与中间代码生成(DOC X页)

哈工大威海编译原理实验三语义分析与中间代码生成(DOC X页)

哈工大威海编译原理实验三语义分析与中间代码生成(DOCX页)哈尔滨工业大学(威海)计算机学院编译原理实验报告姓名院系计算机学院学号 090410任课教师指导教师实验地点宋健二楼机房实验时间实验三语义分析及中间代码生成实验名称同组人无预习报告(对实验主要内容的认识) 得分(1) 通过本次试验,我应该加深对于编译原理制导方案的理解,并且加深对于语法变换的所起到的作用;(2) 对于试验中要用到得中间代码的格式规范,也应该进一步的分析和掌握(3) 能够很好的使用到前面开发出来的词法分析器和语法分析器,将它们与语义分析器结合起来,跟好的更系统的掌握编译原理这门专业技能 (4) 关于符号表以及token串表的维护,现在终于使其有所作用实验内容(问题,思路,程序,结果) 得分(1)开发环境:vs2010(2)输入:在运行打开的软件下(win32格式),输入相应的代码(即要进行词法分析的字符串)(比如:int a;)(3)输出:在输入字符串后,按回车键后,既可以得到相应的词法分析的结果(比如:int a 的输入对应的输出如下:int a;首先对于词法分析打印出:Int --- key //关键字A ---str //字符串; ---bor //边界符号对于语法分析:Accept //编译语句分析成功对于输入字符串的语义分析和中间代码的生成如下中间代码:)(4)在相应的运行程序的文件夹中生成一个txt文件,用来存储生成的Token 链表(5)系统功能:(2) 开发平台(操作系统、设计语言):1、操作系统:windows 72、设计语言:c++3、编译器:vs2010(3) 设计方案;1) 主数据流图开始词法分析Token表的生成及修改语法分析修改token表语义分析语句是否为变量声明对语句按照文法的action表进行归约加一个四元式结点向下进行语义分析生成中间代码结束2) 主要数据结构:符号表、TOKEN串表等。

实验 6 简单中间代码生成

实验 6  简单中间代码生成

实验 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.确定临时变量生成方案,构造其生成程序。

中间代码生成具体实验过程含代码

中间代码生成具体实验过程含代码

实验三中间代码生成学号:;姓名:马小军实验目的1.了解并掌握中间代码的生成过程和作用2.了解并掌握四元式3.体会属性文法在中间代码生成过程中的作用。

实验环境Windows7操作系统vs2010编程环境实验内容从文件中读入表达式,输出其四元式的结果序列本程序只能生成赋值语句及算数表达式中间代码的四元式不能生成逻辑表达式及其他复杂语句中间代码的四元式实验原理三、以逆波兰式为例的实验设计思想及算法(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。

(2)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符数字,则分析到该数字串的结束并将该数字存入数组。

(3)如果不是数字,该字符则是运算符,此时需比较优先关系。

做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。

如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。

倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。

(4)重复上述操作(2)-(3)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为四元式。

下面给出算法流程图实验步骤打开并运行软件根据提示输入要分析的源程序(文件目录下有写好的文件源文件1.txt输入即可)运行输出结果例如将以下源文件放入test.txt运行结果a:=b*c+b*d思考同样的思路对算法进行适当改动就可以生成其它形式的中间代码【其他部分】设计原理和算法思想参考《程序设计语言编译原理》第三版国防工业出版社作者陈火旺等附录代码#include<stdlib.h>#include<fstream>#include<iostream>#include<stdio.h>using namespace std;#define MAX 100int m=0,sum=0;//sum用®?于®¨²计?算?运?算?符¤?的Ì?个?数ºy//m用®?于®¨²标À¨º记?输º?入¨?表À¨ª达ä?式º?中D字Á?符¤?的Ì?个?数ºychar JG='A';char str[MAX];//用®?于®¨²存ä?输º?入¨?表À¨ª达ä?式º?int token=0;//左Á¨®括¤¡§号?的Ì?标À¨º志?/***********用®?于®¨²更¨¹改?计?算?后¨®数ºy组Á¨¦中D的Ì?值¦Ì**************/void change(int e){int f=e+2;char ch=str[f];if(ch>='A'&&ch<='Z'){for(int l=0;l<m+10;l++){if(str[l]==ch)str[l]=JG;}}if(str[e]>='A'&&str[e]<='Z'){for(int i=0;i<m;i++){if(str[i]==str[e])str[i]=JG;}}}void chengchuchuli(int i,int m){i++;for( ;i<=m-1;i++)//处ä|理¤¨ª乘?除y运?算?{if(str[i]=='*'||str[i]=='/'){cout<<"("<<str[i]<<" "<<str[i-1]<<" "<<str[i+1]<<" "<<JG<<")"<<endl;change(i-1);str[i-1]=str[i]=str[i+1]=JG;sum--;JG=(char)(int)JG++;}}}void jiajianchuli(int j,int m){j++;for( ;j<=m-1;j++)//处ä|理¤¨ª加¨®减?运?算?{if(str[j]=='+'||str[j]=='-'){cout<<"("<<str[j]<<" "<<str[j-1]<<" "<<str[j+1]<<" "<<JG<<")"<<endl;change(j-1);str[j-1]=str[j]=str[j+1]=JG;sum--;JG=(char)(int)JG++;}}}/*扫¦¡§描¨¨一°?遍À¨¦从䨮文?件t中D读¨¢入¨?表À¨ª达ä?式º?*/void scan(FILE *fin){int p[MAX];char ch='a';int c=-1,q=0;while(ch!=EOF){ch=getc(fin);while(ch==' '||ch=='\n'||ch=='\t') ch=getc(fin);//消?除y空?格?和¨ª换?行D 符¤?str[m++]=ch;if(ch=='='||ch=='+'||ch=='-'||ch=='*'||ch=='/') sum++;else if(ch=='('){p[++c]=m-1;}else if(ch==')'){q=m-1;chengchuchuli(p[c],q);//从䨮左Á¨®括¤¡§号?处ä|理¤¨ª到Ì?又®?括¤¡§号?jiajianchuli(p[c],q);JG=(char)(int)JG--;str[p[c]]=str[m-1]=JG;c--;JG=(char)(int)JG++;}}}void sanyuanshi(){for(int i=0;i<=m-1;i++)//处ä|理¤¨ª乘?除y运?算?{if(str[i]=='*'||str[i]=='/'){cout<<"("<<str[i]<<" "<<str[i-1]<<" "<<str[i+1]<<" "<<JG<<")"<<endl;change(i-1);str[i-1]=str[i]=str[i+1]=JG;sum--;JG=(char)(int)JG++;}}for(int j=0;j<=m-1;j++)//处ä|理¤¨ª加¨®减?运?算?{if(str[j]=='+'||str[j]=='-'){cout<<"("<<str[j]<<" "<<str[j-1]<<" "<<str[j+1]<<" "<<JG<<")"<<endl;change(j-1);str[j-1]=str[j]=str[j+1]=JG;sum--;JG=(char)(int)JG++;}}for(int k=0;k<=m-1;k++)//处ä|理¤¨ª赋3值¦Ì运?算?{if(str[k]=='='){JG=(char)(int)--JG;cout<<"("<<str[k]<<" "<<str[k+1]<<" "<<" "<<" "<<str[k-1]<<")"<<endl;sum--;change(k+1);str[k-1]=JG;}}}void main(){char in[MAX]; //用®?于®¨²接¨®收º?输º?入¨?输º?出?文?件t名?FILE *fin; //用®?于®¨²指?向¨°输º?入¨?输º?出?文?件t的Ì?指?针?cout<<"请?输º?入¨?源¡ä文?件t名?(ꡧ包㨹括¤¡§后¨®缀Áo名?)ê?"<<endl;// scanf("%s",in);cin>>in;;if ((fin=fopen(in,"r"))==NULL) //判D断?输º?入¨?文?件t名?是º?否¤?正y确¨¡¤{cout<<"打䨰开a词䨺法¤¡§分¤?析?输º?入¨?文?件t出?错䨪!"<<endl;}cout<<"*********三¨y元a式º?如¨?下?:êo*********"<<endl;scan(fin);//调Ì¡Â用®?函¡¥数ºy从䨮文?件t中D读¨¢入¨?表À¨ª达ä?式º?sanyuanshi();if(sum==0) printf("成¨¦功|!ê?");else printf("有®D错䨪误¨®!ê?");//关?闭À?文?件tfclose(fin);system("pause");}。

(精品)编译方法实验报告(中间代码生成器的设计)

(精品)编译方法实验报告(中间代码生成器的设计)

编译方法实验报告
2011年10月
一、实验目的
熟悉算术表达式的语法分析与中间代码生成原理。

二、实验内容
(1)设计语法制导翻译生成表达式的四元式的算法;
(2)编写代码并上机调试运行通过。

输入——算术表达式;
输出——语法分析结果;
相应的四元式序列。

(3)设计LL(1)分析法或LR(0)分析法的属性翻译文法,并根据这些属性翻译文法,使用扩展的语法分析器实现语法制导翻译。

三、实验原理及基本步骤
●算术表达式文法:
G(E): E →E ω0 T | T
T →T ω1 F | F
F → 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 —语义栈;。

编译课设报告--pl0编译器的中间代码生成 2

编译课设报告--pl0编译器的中间代码生成 2

课程设计报告( —年度第一学期)名称:编译技术课程设计题目:PL/0语言编译器的中间代码生成院系:班级:学号:学生姓名:指导教师:设计周数:一周成绩:日期:年月日1 课程设计的目的和要求1.1 课程设计的目的本次设计的时间为1周,目的是通过使用高级语言实现部分算法加强对编译技术和理论的理解。

设计的题目要求具有一定的规模,应涵盖本课程内容和实际应用相关的主要技术,同时使大家将理论与实际应用结合起来,受到软件设计等开发过程的全面训练,从而提高软件开发的能力。

1.2 课程设计的要求1、要求用递归子程序法/或预测分析法实现对表达式、各种说明语句、控制语句进行语法分析。

2、若语法正确,则用语法制导翻译法进行语义翻译:对说明语句,要求将说明的各符号记录到相应符号表中;对可执行语句,应产生出四元式中间代码并填写到三地址码表中;3、若语法错误,要求指出出错性质和出错位置(行号)。

出错处理应设计成一个出错处理子程序。

2 系统描述PL/0的编译程序和目标程序的解释执行程序都是用JA V A语言书写的,因此PL/0语言可在配备JA V A语言的任何机器上实现。

本次课设开发平台即为JA V A。

用递归子程序法实现了对表达式、各种说明语句、控制语句进行语法的分析。

其中,对各个变量符号保存到了符号表中。

对可执行语句,转化成四元式中间代码进行输出。

本程序中,通过出错处理子程序,也进行了语法的错误的记录,并且输出了出错的行号和出错原因。

该程序的输入是打开test文件,通过文件输入流读入,输出有生成的中间代码、符号表内容、错误分析三部分内容,分别用java界面控件显示出来。

2.1 PL/0语言的描述PL/0语言的编译程序是一个编译解释执行系统。

PL/0的目标程序为假想栈式计算机的汇编语言,与具体计算机无关。

其编译过程采用一趟扫描方式,以语法分析类为核心,词法分析和代码生成类都作为一个独立的类,当语法分析需要读单词时就调用词法分析程序,而当语法分析正确需要生成相应的目标代码时,则调用代码生成程序。

中间代码生成实验报告

中间代码生成实验报告

中间代码生成实验报告中间代码生成实验报告一、引言在计算机编程领域中,中间代码生成是编译器的一个重要阶段。

它将源代码转化为一种中间表示形式,以便于后续的优化和目标代码生成。

本实验旨在通过实现一个简单的中间代码生成器,深入理解编译器的工作原理和中间代码的作用。

二、实验背景中间代码是一种介于源代码和目标代码之间的表示形式。

它通常是一种抽象的、与机器无关的形式,具有较高的可读性和可维护性。

中间代码生成是编译器的一个重要阶段,它将源代码转化为中间代码,为后续的优化和目标代码生成提供基础。

三、实验目的本实验的主要目的是通过实现一个简单的中间代码生成器,加深对编译器工作原理的理解,并掌握中间代码的生成过程。

具体目标包括:1. 学习使用编程语言实现中间代码生成算法;2. 理解中间代码的数据结构和语义;3. 掌握将源代码转化为中间代码的过程;4. 分析和优化生成的中间代码。

四、实验设计与实现本实验采用C++语言实现一个简单的中间代码生成器。

具体步骤如下:1. 词法分析:使用词法分析器对输入的源代码进行扫描,将其划分为一个个的词法单元。

2. 语法分析:使用语法分析器对词法单元进行解析,构建语法树。

3. 语义分析:对语法树进行语义分析,检查语法的正确性,并生成中间代码。

4. 中间代码生成:根据语义分析的结果,生成对应的中间代码。

5. 中间代码优化:对生成的中间代码进行优化,提高执行效率和代码质量。

6. 目标代码生成:将优化后的中间代码转化为目标代码。

五、实验结果与分析经过实验,我们成功实现了一个简单的中间代码生成器,并生成了相应的中间代码。

通过对生成的中间代码进行分析,我们发现其中存在一些冗余和不必要的指令,可以进一步进行优化。

例如,可以通过常量折叠、死代码删除等技术,减少中间代码的长度和执行时间。

六、实验总结通过本次实验,我们深入理解了中间代码生成的过程和作用,并通过实践掌握了中间代码生成器的实现方法。

在实验过程中,我们遇到了一些困难和挑战,但通过不断的学习和尝试,最终取得了满意的结果。

实验五+中间代码生成器

实验五+中间代码生成器

实验5 中间代码生成器一、实验目的掌握语法制导定义和翻译的原理和技术,在语法分析器的基础上,加上语义分析,构造一个中间代码生成器。

二、实验内容在实验四用Yacc生成的语法分析器基础上加入语义动作,编写一个中间代码生成程序。

1.文法(见教材附录A.1,p394)program→ blockblock→{ decls stmts }decls →decls decl | εdecl →type id ;type →type [num] //数组可以不做| basic //四种基本数据类型int | float | char | bool stmts→stmts stmt | εstmt→id=expr;| if(bool)stmt| if( bool)stmt else stmt| while(bool)stmt| do stmt while(bool ) ;| break ;//break可以不做| blockbool →bool || join| joinjoin →join&& equality | equalityequality →equality == rel | equality != rel | relrel →expr < expr| expr <= expr| expr > expr| expr >= expr| exprexpr→ expr + term| expr - term| termterm→ term * unary| term / unary| unaryunary →!unary| - unary| factorfactor→ ( e xpr ) | id| num2.中间代码的形式见教材p221~222,若有必要,可以适当扩展(加以说明)。

三、实验过程3.1符号表的定义和相关函数struct SymbolElemstruct SymbolListSymbolList CreateSymbolList( SymbolList PrevList, int StartAddr )/*创建并返回一个新的符号表(SymbolList就是书上的Env),PrevList是其的上一层符号表*/void DestroySymbolList( SymbolList List )struct SymbolElem * LookUpSymbolList( SymbolList List, char * IdName )/*在符号表List中查找是否存在标识符IdName,如果存在,则返回该结点指针,否则返回空*/struct SymbolElem * LookUpAllSymbolList( SymbolList List, char * IdName )/*从符号表List开始并不断地往上一层符号表中查找是否存在标识符IdName,如果存在,则返回该结点指针,否则返回空*/struct SymbolElem * AddToSymbolList( SymbolList List, char * IdName,int IdType, int Width )/*创建一个新的符号结点,并添加到符号表中,而后返回该结点指针*/3.2常数表的定义和相关函数union ConstVal/*存放一个常数*/struct ConstElem/*常量表*/struct ConstList/*创建并返回常量表*/void CreateConstList( int StartAddr )void DestroyConstList( void )/*在常量表ConstList中查找是否存在常量,如果存在,则返回该结点指针,否则返回空*/struct ConstElem * LookUpConstList( int ConstType, union ConstVal ConstValue, int Width )/*创建一个新的常数结点,并添加到常数表中,而后返回该结点指针*/struct ConstElem * AddToConstList( char * Str, int ConstType, union ConstVal ConstValue, int Width )3.3四元式的定义和函数/*四元式数据结构*/struct Quadruple/*四元式表*/struct QuadTablevoid CreateQuadTable(int StartAddr)void DestroyQuadTable( void )/*当Arg1是变量或临时变量时,Arg1Name是该变量的名称,用于演示时使用,其余参数类同*/int Gen( int Op, int Arg1, int Arg2, int Arg3, char *Arg1Name, char *Arg2Name, char *Arg3Name )/*把四元式所对应的三地址代码写入到文件中*/void WriteQuadTableToFile( const char * FileName )四、实验结果源程序片断运行状态图运行结果本次实验很难,做了很久都没做出来。

实验三语义分析及中间代码生成

实验三语义分析及中间代码生成

实验三语义分析及中间代码生成一、实验目的通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法范畴变换为某种中间代码的语义翻译方法。

二、实验内容实现简单的高级语言源程序的语义处理过程。

三试验要求(一)程序设计要求(1)目标机:8086及其兼容处理器(2)中间代码:三地址码或者四元式(3)设计结果:语法分析树(节点具有属性)、三地址码表、符号表、TOKEN串表(4)语义分析内容要求:1)变量说明语句2)赋值语句3)控制语句(任选一种)(5)其它要求:1)将词法分析(扫描器)作为子程序,供语法语义程序调用;2)使用语法制导的语义翻译方法;3)编程语言自定;4)最好提供源程序输入界面;5)目标代码生成暂不做;6)编译后,可查看TOKEN串、语法分析树、符号表、三地址码表;7)主要数据结构:产生式表、符号表、语法分析树、三地址码表。

四、实验设计(1)系统功能(包括各个子功能模块的功能说明);可对一段包含加减乘除括号的赋值语句进行语法分析,其必须以$为终结符,语句间以;隔离,判断其是否符合语法规则,依次输出判断过程中所用到的产生式,并输出最终结论,若有错误可以报错并提示错误所在行数及原因(2)开发平台(操作系统、设计语言);Windows 7,Microsoft Visual C++ 6.0(Dos),C++。

(3) 数据结构struct token//词法 token结构体{int code;//编码int num;//递增编号token *next;};token *token_head,*token_tail;//token队列struct str//词法 string结构体{int num;//编号string word;//字符串内容str *next;};str *string_head,*string_tail;//string队列struct ivan//语法产生式结构体{char left;//产生式的左部string right;//产生式的右部int len;//产生式右部的长度};ivan css[20];//语法 20个产生式struct pank//语法 action表结构体{char sr;//移进或归约int state;//转到的状态编号};pank action[46][18];//action表int go_to[46][11];//语法 go_to表struct ike//语法分析栈结构体,双链{ike *pre;int num;//状态int word;//符号编码ike *next;};ike *stack_head,*stack_tail;//分析栈首尾指针struct L//语义四元式的数据结构{int k;string op;//操作符string op1;//操作数string op2;//操作数string result;//结果L *next;//语义四元式向后指针L *Ltrue;//回填true链向前指针L *Lfalse;//回填false链向前指针};L *L_four_head,*L_four_tail,*L_true_head,*L_false_head;//四元式链,true链,false链struct symb//语义输入时符号表{string word;//变量名称};(4)五、实验结果六、实验总结通过本次实验,我了解了当我编写的代码在经过编译过程中所进行的处理,分为词法分析,语法分析,语义分析和中间代码生成,生成的中间代码经过代码生成器变形成了我们常提到的目标程序.语义分析和中间代码生成会有静态检查:包括类型检查、控制流检查、唯一性检查和关联名字检查等等一判断源程序是否符合语言规定的语法和语义要求。

实验-中间代码生成

实验-中间代码生成

四、程序实现(续) : 2.代码设计 :
void Syntax::E() { T(); while (Token.code==9||Token.code==10) { sExam.Read(&Token); //read(w) T(); output(exp_operator[--top]); } }
NEXT(w)
F •R5
output(*)
F •R6
output(/)
NEXT(w)
E •R7 ) y
n
err2
出口
出口
Ri 返回地址
四、程序实现 : 1.数据结构 :
SemRecord ID[10]; int m=0; double Cons[10]; int n=0; TokenType pos[20]; int num=0; //符号表 //标识符个数 //常数表 //常数个数 //逆波兰式区 //元素个数
Syntax s(ID,&m,Cons,&n,pos,&num); //语法分析类对象x { private: TokenType *p_pos; int *p_num; TokenType Token; Scan sExam; //语法分析类,递归子程序分析 //逆波兰式区指针 //单词Token //扫描器对象
例如,对于符号串 a*(b+c)的分析(翻译)过程,可得出: 导出序列: a{a}*(b{b}+c{c}{+}){*} ※ 分解导出序列:
去掉动作符号: a*(b+c) ………. 源表达式; 去掉文法符号: abc+* ………. 逆波兰式;
算法设计:
主 程 序
Z 开始 初始化 NEXT(w) 入口 T •R1 + y

《编译系统设计实践》实验项目三:语法制导翻译与中间代码生成

《编译系统设计实践》实验项目三:语法制导翻译与中间代码生成

《编译系统设计实践》实验项目三:语法制导翻译与中间代码生成一、实验目的通过语法制导或翻译模式生成中间代码。

二、实验内容理解并应用课本的语法制导定义。

在自顶向下语法分析基础上设计语义规则(语法制导翻译),将源程序翻译为四元式输出,若有错误将错误信息输出。

三、设计思路1.分析过程主函数main 创建一个语法分析器和词法分析器,将词法分析器传入语法分析器中,调用语法分析器的program函数,program负责对输入流进行语法分析做出抽象语法树,然后生成中间代码。

2.程序结构目录四、测试报告1.测试一输入:int i;int j;float v;float x;float[100] a;while(true){do i=i+1;while(a[i]<v);do j=j-1;while(a[j]>v);if(i>=j) break;x=a[i];a[i]=a[j];a[j]=x;}输出:2.测试二:错误待翻译代码输入:i=i+1;int i;输出:3.测试3 :给出语法错误的代码输入:int [100]a;输出:五、实验分工在本次实验中,小组集体进行讨论分析,商定实现方法和完成目标。

小组讨论分析后由黄志杰、潘增滢同学负责编码调试,苏杰阳、陈明煜负责测试和检查审阅代码,指出并修改问题,刘晓君进行测试并撰写实验报告,最后小组同学再一起总结反思提出修改意见。

六、实验总结语法制导翻译的主要难点在于判断关键字,所以我们为判断关键字编写了独立的功能,但对于转化为三地址输出不是很了解,所以上网查阅资料借鉴了网上的代码,最后使用了函数的递归调用实现了,虽然最后的实现成果并不是十分完整,不够精确,但是对语法指导翻译有了一定的了解,也对编译原理有了更深刻的认识。

中间代码生成实验报告

中间代码生成实验报告

一、实验目的通过在实验二的基础上,增加中间代码生成部分,使程序能够对实验二中的识别出的赋值语句,if语句和while语句进行语义分析,生成四元式中间代码。

二、实验方法实验程序由c语言完成,在Turboc 2.0环境中调试通过。

语义分析程序的基本做法是对文法中的每个产生式分别编写一个语义分析子程序,当程序语法部分进行推倒或规约时,就分别调用各自的语义分析程序。

当语法分析结束时,语义分析也就结束了。

在本实验程序中,当语法分析部分识别出语法正确的句子时,就进入content函数(当语法分析识别出不正确的句子时,不进入content函数,也就是不进行语义分析),然后根据句子的类型进行分类,进入不同的语义处理部分。

对于赋值语句,关键是产生正确的处理算术表达式E的四元式。

程序中的ec函数的功能就是产生算术表达式的四元式,在ec函数中使用了两个栈idshed,opshed,分别是算术表达式的数据栈和符号栈。

每次提取一个数字和一个算符,然后将算符与与栈顶算符进行优先级比较,优先级高则将单前数字和算符进栈,低或者相等的话则将当前栈顶元素进行合并,产生四元式。

直至整个算术表达式结束。

其中还有一些细节问题,具体的做法可以参看程序。

对于实验给定的if语句的文法格式,条件判断式C只中可能是>或者<=两种关系,不可能是布尔表达式,这样程序就简单的多了。

通过ec函数可以产生条件判断式C中的E的四元式,然后只要加上转向四元式就可以了。

本实验程序中只给出真出口的转向四元式,没有给出假出口的转向四元式,这在实际中是不可以的,但在本实验中,实际上是对每条独立的语句进行语法分析,给出假出口转向四元式实际上意义不大,而且假出口转向语句的转移目标必须要到整个语句分析结束以后才可以知道,这样就要建立栈,然后回填,这样会使程序复杂很多,所以没有加上假出口转向四元式。

对于while语句,具体的做法和if语句差不多,所不同的是当while语句结束时,要多出一条无条件转向四元式,重新转到条件判断式C的第一条四元式。

编译原理综合性实验报告-分析中间代码生成程序

编译原理综合性实验报告-分析中间代码生成程序
<VarDefList>-> <VarDef>[;<VarDefList>]
<VarDef>-><idList>:T
<idList>->id[,<idList>]
程序的主要任务是:
(1).扫描整个变量声明部分,并进行语义错误检查。
分析PL/0编译程序的总体结构、代码生成的方法和过程;具体写出一条语句的中间代码生成过程。
二、设备与环境
PC兼容机、Windows操作系统、Turbo Pascal软件等。
三、实验内容
1.分析PL/0程序的Block子程序,理清PL/0程序结构和语句格式。画出Block子程序的流程图,写出至少两条PL/0程序语句的语法格式。
2.分析PL/0程序的Block子程序和Gen子程序,了解代码生成的方法和过程。使用概要算法来描述语句的代码生成过程。
3.自己编写一个简单的PL/0程序,能够正确通过编译,得到中间代码。列出自己编写的源程序和编译后得到的中间代码。
4.从中选择一个语句或表达式,写出代码生成的过程。要求从自己的源程序中选择一条语句,结合这条语句写出语义分析和代码生成过程。在描述这个过程中,要说清楚每个功能有哪个子程序的哪条语句来完成,说清楚语句和参数的含义和功能。
四、实验结果及分析
(一)Block子程序分析
1.常量声明的分析:
常量声明部分的语法结构定义为如下形式:
<ConstDecPart> -> const <ConstDefList>;
<ConstDefList> -> <ConstDef>[;<ConstDefList>]

实验四 中间代码生成

实验四 中间代码生成

实验四中间代码生成一、实验要求:熟悉中间代码生成原理二:实验内容:中缀表达式:(a+2)*(b/c)+(d*e)后缀表达式:a 2 + b c / * d e * +定义:int a,b;char c;float d,e;三、实验代码:#include<process.h>#include<stdio.h>#include<string.h>typedef struct{char name[10];char type;//数据类型}sem,*ptsem;typedef struct{ptsem* base;int utop;}stack ;//语义信息栈int i=1;int j=0;int n=0;stack list;char st[10],str1[10],*p;ptsem yylist=new sem[10];void initlist()//初始化{list.base=new ptsem[100];list.utop=0;}void pop( ptsem &pt){pt=list.base[list.utop--];return;}void push(ptsem pt){list.base[++list.utop]=pt;return;}void gencode(ptsem top,ptsem subtop,char w){//生成四元式中间代码ptsem pt=new sem;if(top->type==subtop->type){}else if(top->type=='i'&subtop->type=='c')//栈顶操作数不为实型 {printf("(int,%s,t%d);\n",subtop->name,i);char c=i+48;//产生临时变量数值,如t1,t2等subtop->name[0]='t';subtop->name[1]=c;subtop->name[2]='\0';//产生临时变量subtop->type='i';//转换栈顶操作数类型为实型i++;}else if(top->type=='c'&subtop->type=='i')//栈顶操作数是实型 {printf("(int,%s,t%d);\n",top->name,i);char c=i+48;top->name[0]='t';top->name[1]=c;top->name[2]='\0';top->type='i';//转换第2个栈顶操作数类型为实型i++;}else if(top->type=='i'&subtop->type=='r'){printf("(FLORT,%s,t%d);\n",top->name,i);char c=i+48;top->name[0]='t';top->name[1]=c;top->name[2]='\0';top->type='r';//转换第2个栈顶操作数类型为实型i++;}else if(top->type=='r'&subtop->type=='i'){printf("(FLORT,%s,t%d);\n",subtop->name,i);char c=i+48;subtop->name[0]='t';subtop->name[1]=c;subtop->name[2]='\0';subtop->type='r';//转换第2个栈顶操作数类型为实型i++;}else if(top->type=='c'&subtop->type=='r'){printf("(FLORT,%s,t%d);\n",top->name,i);char c=i+48;top->name[0]='t';top->name[1]=c;top->name[2]='\0';top->type='r';//转换第2个栈顶操作数类型为实型i++;}else if(top->type=='r'&subtop->type=='c'){printf("(FLORT,%s,t%d);\n",subtop->name,i);char c=i+48;subtop->name[0]='t';subtop->name[1]=c;subtop->name[2]='\0';subtop->type='r';//转换第2个栈顶操作数类型为实型i++;}printf("(%c,%s,%s,t%d);\n",w,subtop->name,top->name,i);//w表示运算符,subtop->name表示第1个操作数,top->name表示第2个操作数,i表示第i个临时变量char c=i+48;pt->type=top->type;pt->name[0]='t';pt->name[1]=c;pt->name[2]='\0';i++;push(pt);return;}void identify()//判断变量及其数据类型{while(*p>='a'&&*p<='z')st[j++]=*p++;st[j]='\0';j=0;int flag=0;if(!strcmp(st,"float")||!strcmp(st,"int")||!strcmp(st,"char"))flag=1;if(flag==1){strcpy(str1,st);return;}sem pp;if(!strcmp(str1,"float")){strcpy(,st);pp.type='r';if(!strcmp(str1,"int")){strcpy(,st);pp.type='i';}if(!strcmp(str1,"char")){strcpy(,st);pp.type='c';}yylist[n++]=pp;}void conid()//常量操作{ptsem pt=new sem;int flag=0,k=0;do{pt->name[k++]=*p;if(*p++=='.')flag=1;}while(*p>='0'&&*p<='9'||*p=='.');pt->type=flag?'r':'i';if(*p>'9'&&*p<'0'){printf("the const data you inputed is wrong");exit(0);}pt->name[k]='\0';push(pt);}void varid()//变量操作{ptsem pt=new sem;int flag=0,k=0;do{pt->name[k++]=*p++;}while(*p>='a'&&*p<='z'||*p>='A'&&*p<='Z');pt->name[k]='\0';for(int i=0;i<n;i++)if(!strcmp(pt->name,yylist[i].name)){flag=1;pt->type=yylist[i].type;push(pt);} if(flag==0)printf(" \" %s\" is not defined!",pt->name);exit(0);}}void main(){initlist();printf("\n");char str[100];gets(str);//输入变量定义p=str;while(*p!='\0'){if(!(*p>='a'&&*p<='z'||*p>='A'&&*p<='Z'||*p==';'||*p==' '||*p==',')){printf("this define is wrong!");exit(0);}//ifswitch(*p){case',':p++;break;case ' ':p++;break;case';': p++;break;default: identify();}//switch}//whilechar strpds[100];gets(strpds);//输入后缀式算术表达式p=strpds;char ch=*p,a;ptsem top,subtop;while(*p!='\0') {if(ch>='0'&&ch<='9')a='0';else if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')a='1';else if(ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch=='^')a='2';else if(ch==';')break;else if(ch==' ')a='4';else a='3';switch(a){case'0':conid();ch=*p;break;//常数case'1':varid();ch=*p;break;//变量case'2':pop(top);pop(subtop);gencode(top,subtop,ch);ch=*++p;break;//运算符 case'3':printf("%c is a illegal letter!\n",ch);exit(0);case'4':ch=*++p;//空格}}if(*p!='\0')printf("this setense is illegal!"); }四、实验结果:。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

中间代码生成实验报告篇一:编译方法实验报告(中间代码生成器)编译方法实验报告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语句进行语义分析,生成四元式中间代码。

二、实验方法实验程序由c语言完成,在Turboc 2.0环境中调试通过。

语义分析程序的基本做法是对文法中的每个产生式分别编写一个语义分析子程序,当程序语法部分进行推倒或规约时,就分别调用各自的语义分析程序。

当语法分析结束时,语义分析也就结束了。

在本实验程序中,当语法分析部分识别出语法正确的句子时,就进入content函数(当语法分析识别出不正确的句子时,不进入content函数,也就是不进行语义分析),然后根据句子的类型进行分类,进入不同的语义处理部分。

对于赋值语句,关键是产生正确的处理算术表达式E的四元式。

程序中的ec函数的功能就是产生算术表达式的四元式,在ec函数中使用了两个栈idshed,opshed,分别是算术表达式的数据栈和符号栈。

每次提取一个数字和一个算符,然后将算符与与栈顶算符进行优先级比较,优先级高则将单前数字和算符进栈,低或者相等的话则将当前栈顶元素进行合并,产生四元式。

直至整个算术表达式结束。

其中还有一些细节问题,具体的做法可以参看程序。

对于实验给定的if语句的文法格式,条件判断式C只中可能是>或者通过ec函数可以产生条件判断式C中的E的四元式,然后只要加上转向四元式就可以了。

本实验程序中只给出真出口的转向四元式,没有给出假出口的转向四元式,这在实际中是不可以的,但在本实验中,实际上是对每条独立的语句进行语法分析,给出假出口转向四元式实际上意义不大,而且假出口转向语句的转移目标必须要到整个语句分析结束以后才可以知道,这样就要建立栈,然后回填,这样会使程序复杂很多,所以没有加上假出口转向四元式。

对于while语句,具体的做法和if语句差不多,所不同的是当while语句结束时,要多出一条无条件转向四元式,重新转到条件判断式C的第一条四元式。

当要产生无条件转向四元式时,它的转向目标C的第一条四元式已经产生了,所以具体的做起来是不太困难的。

只要记下当前while中的C的第一条四元式的位置,填上就可以了。

整个程序的结束是当读入“ . ”时,程序就中止。

程序中还有很多细节问题,具体的可以后面的附录:程序的完整代码。

三、测试程序ff:=6+6*6-;if sl>89+56*67then f:=7*7+4;ff:=6+6*6-6%4+8;if sl+78*76>89*56+67then while a-7>98+45*45 do f:=7*7+4;.四、运行结果首先对测试程序进行语法分析,识别出正确的句子,当识别出正确的句子时,就对当前句子进行语义分析,而语法不正确的句子不进行语义分析。

ff:=6+6*6-Error(4):Except ID or NUM ; Error(2):Syntax errorif sl>89+56*67thenf:=7*7+4; success!!!(1)[ *, 56, 67, T1 ](2)[ +, 89, T1, T2 ](3)[j>, sl, T2, (4) ](4)[ *, 7, 7, T3 ](5)[ +, T3, 4, T4 ](6)[ :=, T4, -, f ]ff:=6+6*6-6%4+8; success!!!(7)[ *, 6, 6, T5 ](8)[ +, 6, T5, T6 ](9)[ %, 6, 4, T7 ](10)[ -, T6, T7, T8 ](11)[ +, T8, 8, T9 ](12)[ :=, T9, -, ff ]if sl+78*76>89*56+67thenwhile a-7>98+45*45dof:=7*7+4; success!!!(13)[ *, 78, 76, T10 ](14)[ +, sl,T10, T11 ](15)[ *, 89, 56, T12 ](16)[ +,T12, 67, T13 ](17)[j>, T11, T13, (18) ](18)[ -, a, 7, T14 ](19)[ *, 45, 45, T15 ](20)[ +, 98,T15, T16 ](21)[j>, T14, T16, (22) ](22)[ *, 7, 7, T17 ](23)[ +,T17, 4, T18 ](24)[ :=, T18, -, f ](25)[j, _, _,(18)].Error(2):Syntax error五、实验小结终于完成了编译原理的三次实验,这几次实验使我们更彻底地巩固了编译原理。

相关文档
最新文档