目录1.绪论概述“编译原理”是一门研究设计和构造编译程序原理课程,是计算机各专业的一门重要的专业课。
编译原理这门课程蕴含着计算机学科中解决问题的思路和解决问题的方法,对应用软件和系统软件的设计与开发有一定的启发和指导作用。
“编译原理”是一门实践性很强的课程,要掌握这门课程中的思想,就必须要把所学到的知识应用于实践当中。
而课程设计是将理论与实践相互联系的一种重要方式。
设计目的课程设计是对学生的一种全面综合素质训练,是与课堂听讲、自学和练习相辅相成的必不可少的一个教学环节。
通常,设计题中的问题比平时的练习题要复杂很多,但也更接近实际。
编译原理这门课程安排的课程设计的目的是旨在要求学生进一步巩固课堂上所学的理论知识,深化理解和灵活掌握教学内容,选择合适的数据逻辑结构解决问题,然后编制算法和程序完成设计要求,从而进一步培养学生独立思考问题、分析问题、解决实际问题的能力。
设计题目及要求基于这个学期所学习的内容以及自己所掌握到的知识,本次我所要设计的题目是赋值语句的四元式生成。
要求:(1)设计语法制导生成赋值语句的四元式的算法;(2)编写代码并上机调试运行通过;(3)输入一赋值语句;(4)输出相应的表达式的四元式;2.背景知识语法制导翻译方法语法制导翻译的方法就是为每个产生式配上一个翻译子程序(称语义动作或语义子程序),并在语法分析的同时执行这些子程序。
语义动作是为产生式赋予具体意义的手段,它一方面指出了一个产生式所产生的符号串的意义,另一方面又按照这种意义规定了生成某种中间代码应做哪些基本动作。
在语法分析的过程中,当一个产生式获得匹配(对于自顶向下分析)或用于规约(对于自底向上分析)时,此产生式相应的语义子程序就进入工作,完成既定的翻译任务。
语法制导翻译分为自底向上语法制导翻译和自顶向下语法制导翻译。
属性文法属性文法是编译技术中用来说明程序语言语义的工具,也是当前实际应用中比较流行的一种语义描述方法。
属性是指与文法符号的类型和值等有关的一些信息,在编译中用属性描述处理对象的特征。
属性文法是一种适用于定义语义的特殊文法,即在语言的文法中增加了属性的文法,它将文法符号的语义以“属性”的形式附加到各个文法的符号上,再根据产生式所包含的含义,给出每个文法符号属性的求值规则,从而形成一种带有语义属性的上下文无关文法,即属性文法。
属性文法也是一种翻译文法,属性有助于更详细的指定文法中的代码生成动作。
几种常见的中间语言(1)抽象语法树(2)逆波兰表示法(3)三地址代码在编译程序中,三地址代码语言的具体实现通常有三种表示方法:四元式、三元式和间接三元式。
四元式的简介四元式是具有四个域的记录(即结构体)结构,这四个域为:(op,arg1,arg2,result)其中,op为运算符,arg1、arg2及result为指针,他们可指向有关名字在符号表中的登记项或一临时变量(也可空缺)。
常用的三地址语句与相应的四元式对应如下:X=y op z 对应(op,y,z,x)X=-y 对应(uminus,y,_,x)X=y 对应(=,y,_,x)Par x1 对应(par,x1,_,_)Call p 对应(call,_,_,p)Goto L 对应(j,_,_,L)If x rop y goto L 对应(jrop,x,y,L)注意规则:如果op是一个算术或逻辑运算符,则result总是一个新引进的临时变量,它用来存放运算结果。
四元式出现的顺序与表达式计值的顺序是一致的,四元式之间的联系是通过临时变量实现的。
四元式由于其表示更接近程序设计的习惯而成为一种普遍采用的中间代码形式。
3.设计过程设计思路(1)定义部分:定义常量、变量、数据结构。
(2)初始化:设立算符优先分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等(3)控制部分:从键盘输入一个表达式符号串;(4)利用算符优先分析算法进行表达式处理:根据算符优先分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。
实现本设计主要通过C语言来实现。
C语言的语法结构类型很多,从实习的角度可分为以下六类:⑴明语句。
如各种数据类型说明(整型、实型、布尔型、字符型、复型、双精度型、枚举、子界、数组、集合、文件、记录、指针等),各种数据空间特性说明(如公用语句,共名语句,等价语句等),初值语句。
实习重点是内存空间的分配方法。
⑵序结构语句。
典型代表是各类表达式(如算术表达式、布尔表达式、字符表达式、位表达)及相应的赋值语句。
实习重点是算术表达式的翻译方法。
⑶制结构语句。
常见的有转移语句、条件语句和各种分叉语句。
实习重点是拉链返填的方法。
⑷子程序结构。
指子程序、函数、过程这类结构的定义和调用。
实习重点是哑实结合的方法。
⑸环结构。
如计数循环、条件循环等。
实习重点是循环化简的方法。
⑹式语句。
主要指输入输出语句的格式加工。
4.上机调试运行在VC++中c语言环境下调试运行代码调试界面及结果执行及结果输入一语句:a=((b+c)*2-3)/d对应的输出应该为:(1)(+,b,c,A)(2)(*,2,A,B)(3)(-,3,B,C)(4)(/,C,d,D)(5)(=,C,_,a)图如下所示:5.注意事项(1)表达式中允许使用运算符(+-*/)、分割符(括号)、字符i,结束符#;(2)如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);(3)测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。
同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照6.总结实践是检验真理的唯一标准,当然也是检验学习成果的标准。
在经过一段时间的学习之后,我们需要了解自己的所学应该如何应用在实践中,因为任何知识都源于实践,归于实践,所以要将所学的知识在实践中来检验。
在做设计写论文期间,我遇到了好多问题,比如:程序总是出现错误,执行不了等等。
但是在周围同学的帮助下,这些问题都得到了解决。
由于对知识的不了解,许多地方不是很懂,需要通过其他同学和老师的指点才能明白。
感谢周围同学的大力帮助还有老师的谆谆教导,才使我完成此次的结课论文。
通过这次的设计,我得到了许多宝贵的经验。
经验如下:思想上,学会了用坚持不懈的精神去解决问题,很多事情看起来很简单,但实际做起来会发现有许多很困难。
中间有许多你想不到的东西。
学习上,使自已在大学所以的知识在这次得到实践,学到一些书本上无法学到的经验,对编译原理有了进一步的认识。
同时,也明白了知识是需要实践的,很多你能说出来的东西,但是在实际应用的时候,并不是那么顺利。
所以以后,我们要注重理论与实践的结合。
这次设计考察了我们这一学期的知识,熟练的话可以很容易的做出来,不熟练的需要翻书擦能得到解决,在这次四元式的设计中,充分应用了老师上课所讲的知识,是我对此有了更深的了解。
并且通过此次设计,对之前掌握不太好的现在也能熟练运用了。
参考文献【1】《编译原理教程》(第四版)主编:胡元义【M】西安电子科技大学出版社【2】《编译原理》作者:胡伦俊、徐兰芳、骆婷【M】电子工业出版社附录#include<>#include<>#define MAX 100void SET_Mul_Div(int i,int m);void SET_Add_Sub(int j,int m);void print();int m=0;int count=0;char tempvar='A';int temp;char string[MAX]; //用于存放表达式int main(){int p[MAX];char ch;int c=-1,q=0;printf("请输入赋值语句:\n");while((ch = getchar())!='\n'){string[m++]=ch;if(ch=='='||ch=='+'||ch=='-'||ch=='*'||ch=='/')count++;elseif(ch=='('){ p[++c]=m-1; }else if(ch==')'){q=m-1;SET_Mul_Div(p[c],q); //从左括号处理到又括号SET_Add_Sub(p[c],q);temp=(int)tempvar-1;tempvar=(char)temp;string[p[c]]=string[m-1]=tempvar;c--;temp=(int)tempvar+1; tempvar=(char)temp;} } /*****调用生成四元式的函数********/ print(); /*********判断是否成功**********/if(count==0)printf("Successful!\n");elseprintf("Wrong!");printf("\n");system("pause"); }void SET_Mul_Div(int i,int m) //处理乘除运算{for(i++;i<=m-1;i++){if(string[i]=='*'||string[i]=='/'){printf("(%c %c %c %c)\n",string[i],string[i-1],string[i+1 ], tempvar);string[i-1]=string[i]=string[i+1]=tempvar;count--;temp=(int)tempvar+1;tempvar=(char)temp; } } }void SET_Add_Sub(int j,int m) //处理加减运算{ j++;for(;j<=m-1;j++){if(string[j]=='+'||string[j]=='-'){printf("(%c %c %c %c)\n",string[j],string[j-1],string[j+1],t empvar);string[j-1]=string[j]=string[j+1]=tempvar;count--;temp=(int)tempvar+1;tempvar=(char)temp; } } } /*打印*/void print(){ int i;for(i=0;i<=m-1;i++)//处理乘除运算{ if(string[i]=='*'||string[i]=='/'){printf("(%c %c %c %c)\n",string[i],string[i-1],string[i+1],t empvar);string[i-1]=string[i]=string[i+1]=tempvar;count--;temp=(int)tempvar+1;tempvar=(char)temp; }}int j;for(j=0;j<=m-1;j++)//处理加减运算{if(string[j]=='+'||string[j]=='-'){printf("(%c %c %c %c)\n",string[j],string[j-1],string[j+1],t empvar); string[j-1]=string[j]=string[j+1]=tempvar; count--;temp=(int)tempvar+1;tempvar=(char)temp; } }int k;for(k=0;k<=m-1;k++) //处理赋值运算{ if(string[k]=='='){ temp=(int)tempvar--;tempvar=(char)temp;printf("(%c %c %c) \n",string[k],string[k+1], string[k-1],tempvar);count--;string[k-1]=tempvar; } } }。