编译原理报告for循环语句的翻译程序
编译原理报告for循环语句的翻译程序

学号:0120810680326课程设计题目f or循环语句的翻译程序学院计算机学院专业软件工程班级0803姓名徐泽前指导教师何九周2011 年 6 月日目录1设计目的 (4)2设计环境与工具 (4)3设计任务要求与说明 (4)4设计时间 (4)5设计地点 (4)6系统描述 (4)7文法及属性文法的描述 (5)7.1文法描述 (5)7.1.1 FOR语句相关的产生式: (5)7.1.2 布尔表达式: (5)7.1.3 赋值表达式: (5)7.2属性文法的描述 (5)8 语法分析方法描述及语法分析表设计 (7)8.1语法分析方法描述 (7)8.2系统中使用的action和goto表(见附录1) (9)9 给出中间代码形式的描述及中间代码序列的结构设计 (9)10简要的分析与概要设计 (10)11 详细的算法描述 (11)11.1词法分析的数据结构设计与详细的流程图 (11)11.2词法分析流程图 (11)11.3语法制导翻译的数据结构与详细的设计图 (12)11.3.1数据结构的设计 (12)11.3.2算法描述 (13)11.3.3程序流程图 (13)12给出软件的测试方法和测试结果 (14)12.1 FOR循环语句的测试 (14)12.2词法分析出错处理 (15)12.3语法分析出错处理 (16)13收获与体会 (16)14 参考文献 (17)课程设计任务书学生姓名:徐泽前专业班级:软件0803班指导教师:何九周工作单位:计算机学院题目: for循环语句的翻译程序初始条件:程序设计语言:主要使用C语言的开发工具,或者采用LEX、YACC等工具,也可利用其他熟悉的开发工具。
算法:可以根据《编译原理》课程所讲授的算法进行设计。
要求完成的主要任务:(包括课程设计工作量及其技术要求,说明书撰写等具体要求)1.明确课程设计的目的和重要性,认真领会课程设计的题目,读懂课程设计指导书的要求,学会设计的基本方法与步骤,学会如何运用前修知识与收集、归纳相关资料解决具体问题的方法。
编译原理实验报告总结

学年第学期《编译原理》实验报告学院(系):计算机科学与工程学院班级:11303070A学号:***********姓名:无名氏指导教师:保密式时间:2016 年7 月目录1.实验目的 (1)2.实验内容及要求 (1)3.实验方案设计 (1)3.1 编译系统原理介绍 (1)3.1.1 编译程序介绍 (2)3.1.2 对所写编译程序的源语言的描述 (2)3.2 词法分析程序的设计 (3)3.3 语法分析程序设计 (4)3.4 语义分析和中间代码生成程序的设计 (4)4. 结果及测试分析 (4)4.1软件运行环境及限制 (4)4.2测试数据说明 (5)4.3运行结果及功能说明 (5)5.总结及心得体会 (7)1.实验目的根据Sample语言或者自定义的某种语言,设计该语言的编译前端。
包括词法分析,语法分析、语义分析及中间代码生成部分。
2.实验内容及要求(1)词法分析器输入源程序,输出对应的token表,符号表和词法错误信息。
按规则拼单词,并转换成二元形式;滤掉空白符,跳过注释、换行符及一些无用的符号;进行行列计数,用于指出出错的行列号,并复制出错部分;列表打印源程序;发现并定位词法错误;(2)语法分析器输入token串,通过语法分析,寻找其中的语法错误。
要求能实现Sample 语言或自定义语言中几种最常见的、基本的语法单位的分析:算术表达式、布尔表达式、赋值语句、if语句、for语句、while语句、do while语句等。
(3)语义分析和中间代码生成输入token串,进行语义分析,修改符号表,寻找其中的语义错误,并生成中间代码。
要求能实现Sample语言或自定义语言中几种最常见的、基本的语法单位的分析:算术表达式、布尔表达式、赋值语句、if语句、for语句、while 语句、do while语句等。
实验要求:功能相对完善,有输入、输出描述,有测试数据,并介绍不足。
3.实验方案设计3.1 编译系统原理介绍编译器逐行扫描高级语言程序源程序,编译的过程如下:(1).词法分析识别关键字、字面量、标识符(变量名、数据名)、运算符、注释行(给人看的,一般不处理)、特殊符号(续行、语句结束、数组)等六类符号,分别归类等待处理。
编译原理语义分析实验报告

实验3 语义分析实验报告一、实验目的二、通过上机实习, 加深对语法制导翻译原理的理解, 掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。
三、实验要求四、采用递归下降语法制导翻译法, 对算术表达式、赋值语句进行语义分析并生成四元式序列。
五、算法思想1.设置语义过程。
(1)emit(char *result,char *ag1,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.函数lrparser 在原来语法分析的基础上插入相应的语义动作: 将输入串翻译成四元式序列。
在实验中我们只对表达式、赋值语句进行翻译。
源程序代码:#include<stdio.h>#include<string.h>#include<iostream.h>#include<stdlib.h>struct{char result[12];char ag1[12];char op[12];char ag2[12];}quad;char prog[80],token[12];char ch;int syn,p,m=0,n,sum=0,kk; //p是缓冲区prog的指针, m是token的指针char *rwtab[6]={"begin","if","then","while","do","end"};void scaner();char *factor(void);char *term(void);char *expression(void);int yucu();void emit(char *result,char *ag1,char *op,char *ag2);char *newtemp();int statement();int k=0;void emit(char *result,char *ag1,char *op,char *ag2){strcpy(quad.result,result);strcpy(quad.ag1,ag1);strcpy(quad.op,op);strcpy(quad.ag2,ag2);cout<<quad.result<<"="<<quad.ag1<<quad.op<<quad.ag2<<endl;}char *newtemp(){char *p;char m[12];p=(char *)malloc(12);k++;itoa(k,m,10);strcpy(p+1,m);p[0]='t';return (p);}void scaner(){for(n=0;n<8;n++) token[n]=NULL;ch=prog[p++];while(ch==' '){ch=prog[p];p++;}if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){m=0;while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}else if((ch>='0'&&ch<='9')){{sum=0;while((ch>='0'&&ch<='9')){sum=sum*10+ch-'0';ch=prog[p++];}}p--;syn=11;if(sum>32767)syn=-1;}else switch(ch){case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>'){syn=21;token[m++]=ch;}else if(ch=='='){syn=22;token[m++]=ch;}else{syn=23;p--;}break;case'>':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=24;token[m++]=ch;}else{syn=20;p--;}break;case':':m=0;token[m++]=ch;ch=prog[p++];if(ch=='='){syn=18;token[m++]=ch;}else{syn=17;p--;}break;case'*':syn=13;token[0]=ch;break; case'/':syn=14;token[0]=ch;break; case'+':syn=15;token[0]=ch;break; case'-':syn=16;token[0]=ch;break; case'=':syn=25;token[0]=ch;break; case';':syn=26;token[0]=ch;break; case'(':syn=27;token[0]=ch;break; case')':syn=28;token[0]=ch;break; case'#':syn=0;token[0]=ch;break; default: syn=-1;break;}}int lrparser(){//cout<<"调用lrparser"<<endl;int schain=0;kk=0;if(syn==1){scaner();schain=yucu();if(syn==6){scaner();if(syn==0 && (kk==0))cout<<"success!"<<endl;}else{if(kk!=1)cout<<"缺end!"<<endl;kk=1;}}else{cout<<"缺begin!"<<endl;kk=1;}return(schain);}int yucu(){// cout<<"调用yucu"<<endl;int schain=0;schain=statement();while(syn==26){scaner();schain=statement();}return(schain);}int statement(){//cout<<"调用statement"<<endl;char *eplace,*tt;eplace=(char *)malloc(12);tt=(char *)malloc(12);int schain=0;switch(syn){case 10:strcpy(tt,token);scaner();if(syn==18){scaner();strcpy(eplace,expression());emit(tt,eplace,"","");schain=0;}else{cout<<"缺少赋值符!"<<endl;kk=1;}return(schain);break;}return(schain);}char *expression(void){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分析产生表达式计算的第一项eplacewhile((syn==15)||(syn==16)){if(syn==15)strcpy(tt,"+");else strcpy(tt,"-");scaner();strcpy(ep2,term()); //调用term分析产生表达式计算的第二项ep2strcpy(tp,newtemp()); //调用newtemp产生临时变量tp存储计算结果emit(tp,eplace,tt,ep2); //生成四元式送入四元式表strcpy(eplace,tp);}return(eplace);}char *term(void){// cout<<"调用term"<<endl;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==13)||(syn==14)){if(syn==13)strcpy(tt,"*");else strcpy(tt,"/");scaner();strcpy(ep2,factor()); //调用factor分析产生表达式计算的第二项ep2strcpy(tp,newtemp()); //调用newtemp产生临时变量tp存储计算结果emit(tp,eplace,tt,ep2); //生成四元式送入四元式表strcpy(eplace,tp);}return(eplace);}char *factor(void){char *fplace;fplace=(char *)malloc(12);strcpy(fplace,"");if(syn==10){strcpy(fplace,token); //将标识符token的值赋给fplacescaner();}else if(syn==11){itoa(sum,fplace,10);scaner();}else if(syn==27){scaner();fplace=expression(); //调用expression分析返回表达式的值if(syn==28)scaner();else{cout<<"缺)错误!"<<endl;kk=1;}}else{cout<<"缺(错误!"<<endl;kk=1;}return(fplace);}void main(){p=0;cout<<"**********语义分析程序**********"<<endl;cout<<"Please input string:"<<endl;do{cin.get(ch);prog[p++]=ch;}while(ch!='#');p=0;scaner();lrparser();}七、结果验证1、给定源程序begin a:=2+3*4; x:=(a+b)/c end#输出结果2、源程序begin a:=9; x:=2*3-1; b:=(a+x)/2 end#输出结果八、收获(体会)与建议通过此次实验, 让我了解到如何设计、编制并调试语义分析程序, 加深了对语法制导翻译原理的理解, 掌握了将语法分析所识别的语法成分变换为中间代码的语义翻译方法。
编译原理for结构的语法树

编译原理for结构的语法树
编译原理中,for结构是一种常见的语法结构,用于循环执行一些语句。
在语法树中,for结构通常由三个部分组成:循环变量的初始化语句、循环条件判断语句和循环体语句。
循环变量的初始化语句一般用于给循环变量赋初始值。
在语法树中,循环变量的初始化语句通常是一条简单的赋值语句,例如:i = 0。
循环条件判断语句用于判断循环要不要继续执行。
在语法树中,
循环条件判断语句通常是一条关系运算符语句或者逻辑运算符语句,
例如:i < n。
循环体语句用于执行循环中需要重复执行的操作。
在语法树中,
循环体语句可以是一条语句、多条语句的块结构或者一个函数调用语句,例如:print(i)。
在编译器中,编译器会根据语法树中的for结构生成一种特殊的
代码。
这种代码通常包含一个循环头和一个循环尾。
循环头中包括了
循环变量的初始化语句和循环条件判断语句,而循环尾中包括了循环
变量的更新语句和跳转语句。
在编译器中,编译器会根据循环体语句
生成一些中间语言代码,最终将这些代码和循环头和循环尾的代码合
并生成最终的代码。
在实际编程中,for结构是一种非常常用的语法结构。
它可以用于循环遍历数组、枚举类型以及一些需要反复执行的操作。
在编写for
结构代码的时候,需要注意一些细节问题,例如循环变量的初始化、循环条件的判断以及循环体语句的执行。
只有掌握了这些细节问题,才能编写出高效且正确的for结构代码。
for循环的缩写

for循环的缩写For循环是编程中常用的一种循环结构,用于重复执行特定的代码块。
它的缩写来源于英文单词"for",意为"对于"或"用于"。
在许多编程语言中,for循环通常由三个部分组成:循环变量的初始化、循环条件的判断和循环变量的更新。
我们来看一下for循环的基本语法结构。
通常,for循环的语法如下所示:for (初始化; 条件; 更新) {// 循环体代码}在这个语法结构中,初始化部分用于初始化循环变量,条件部分用于判断是否继续执行循环体,更新部分用于更新循环变量的值。
循环体代码是需要重复执行的代码块,可以包含任意多条语句。
接下来,我们来看一些使用for循环的实际应用场景。
首先是遍历数组或列表。
通过for循环可以方便地遍历数组或列表中的每个元素,进行相应的操作。
例如,我们可以使用for循环计算数组中所有元素的和,或者找到数组中的最大值。
除了遍历数组或列表,for循环还可以用于打印特定的图形。
例如,我们可以使用for循环打印出一些简单的图形,比如三角形、矩形或菱形。
通过控制循环变量的值,我们可以控制图形的大小和形状。
for循环还可以用于处理字符串。
我们可以通过for循环遍历字符串的每个字符,并对每个字符进行相应的处理。
例如,我们可以使用for循环统计字符串中某个字符出现的次数,或者将字符串中的某个字符替换为另一个字符。
for循环还可以用于生成一系列的数字。
通过控制循环变量的起始值、终止值和步长,我们可以生成一系列的数字。
这在一些需要生成一定范围内的数字序列的场景中非常有用,比如生成1到100的所有偶数。
除了上述应用场景,for循环还可以用于实现一些其他的功能,比如计时器、动画效果等。
通过控制循环变量和循环体内的代码,我们可以实现各种复杂的功能。
总结一下,for循环是一种简洁高效的循环结构,在编程中应用广泛。
它可以用于遍历数组或列表、打印图形、处理字符串、生成数字序列等多种场景。
编译原理实验报告6-逆波兰式的翻译和计算

编译原理实验报告6-逆波兰式的翻译和计算实验6 逆波兰式的翻译和计算一、实验目的通过实验加深对语法指导翻译原理的理解,掌握算符优先分析的方法,将语法分析所识别的表达式变换成中间代码的翻译方法。
二、实验内容设计一个表示能把普通表达式(中缀式)翻译成后缀式,并计算出结果的程序。
三、实验要求1、给出文法如下:G[E]E->T|E+T;T->F|T*F;F->i(E);对应的转化为逆波兰式的语义动作如下:E-> E(1)op E(2) {E.CODE:=E(1).CODE||E(2).CODE||op}E->(E(1)) { E.CODE := E(1).CODE}E->id { E.CODE := id} 2、利用实验5中的算符优先分析算法,结合上面给出的语义动作实现逆波兰式的构造;3、利用栈,计算生成的逆波兰式,步骤如下:1)中缀表达式,从文本文件读入,每一行存放一个表达式,为了降低难度,表达式采用常数表达式;2)利用结合语法制导翻译的算符优先分析,构造逆波兰式;3)利用栈计算出后缀式的结果,并输出;四、实验环境PC微机DOS操作系统或Windows 操作系统Turbo C 程序集成环境或Visual C++ 程序集成环境#include<math.h>using namespace std;#define max 100char ex[max];int n;char GetBC(FILE* fp) {//读取文件的字符直至ch不是空白c har ch;d o {ch = fgetc(fp);} while (ch == ' ' || ch == '\t' || ch == '\n');r eturn ch;}void acquire(FILE* fp){c har str[max];c har stack[max];c har ch;i nt sum, i, j, t, top = 0;i = 0;/*读取一行表达式*/G etBC(fp);i f (feof(fp))return;e lse {fseek(fp, -1L, 1);printf("\n(%d)", n);n++;}d o{i++;str[i] = GetBC(fp);} while (str[i] != ';' && i != max); s um = i;t = 1;i = 1;c h = str[i];i++;w hile (ch != ';'){switch (ch){case '(':top++; stack[top] = ch;break;case ')':while (stack[top] != '(') {ex[t] = stack[top];top--;t++;}top--;break;case '+':case '-':while (top != 0 && stack[top] != '(') {ex[t] = stack[top];top--;t++;}top++;stack[top] = ch;break;case '*':case '/':while (stack[top] == '*' || stack[top] == '/'){ex[t] = stack[top];top--;t++;}top++;stack[top] = ch;break;case ' ':break;default:while (ch >= '0'&&ch <= '9'){ ex[t] = ch;t++;/*ex[ ]中存放逆波兰式 */ch = str[i];i++;/*str[ ]中存放中缀表达式*/ }i--;ex[t] = ',';t++;break;}ch = str[i];i++;}/*当中缀表达式扫描完毕,检查ω栈是否为空,若不空则一一退栈*/w hile (top != 0) {ex[t] = stack[top];t++;top--;}e x[t] = ';';f or (j = 1; j < sum; j++)printf("%c", str[j]);p rintf("\n输出:");f or (j = 1; j < t; j++)printf("%c", ex[j]);}void getValue() {f loat stack[max], d;c har ch;i nt t = 1, top = 0;c h = ex[t];t++;w hile (ch != ';'){switch (ch){case '+':stack[top - 1] = stack[top - 1] + stack[top];top--;break;case '-':stack[top - 1] = stack[top - 1] - stack[top];top--;break;case '*':stack[top - 1] = stack[top - 1] * stack[top];top--;break;case '/':if (stack[top] != 0)stack[top - 1] = stack[top - 1] / stack[top];else{printf("除零错误\n");break;/*异常退出*/}top--;break;/*将数字字符转化为对应的数值*/ default:d = 0;while (ch >= '0'&&ch <= '9') {d = 10 * d + ch - '0';ch = ex[t];t++;}top++;stack[top] = d;}ch = ex[t];t++;}p rintf("\t%g\n", stack[top]);}void main() {F ILE* fp;e rrno_t err;i f ((err = fopen_s(&fp,"C:\\Users\\Administrator\\Desktop\\e xpression.txt", "r")) != NULL){ //以只读方式打开文件,失败则退出程序printf("file can not open!");exit(0);}n = 1;p rintf("逆波兰式的翻译和计算结果如下:\n");w hile (1) {acquire(fp);if (feof(fp)) break;getValue(); }f close(fp);f p = NULL;}实验结果:问题:这次实验较之之前不同,在设计算法与数据结构上花的时间较少,因为之前在数据结构课程里做过使用堆栈完成表达式的计算,也学过中缀式和后缀式,所以代码编得较快,但是其中的算法其实是较复杂的,调试时显得更复杂而编程时我用的是VS,在调试开始时,断点是不能增加的,这样影响了调试的进度,其实之前做实验就注意到了,只是没有特别在意,但这个实验的算法较复杂,断点设得较多,这让我想到使用JAVA,也许使用java开发会更容易,调试的问题也可以解决,主要是使用现在对于C++的熟练程度远不如Java,如果能充分使用类和对象的特点,各种算法的实现将更加有条理,更易读易修改。
编译原理课程设计-For语句的翻译程序设计(简单优 先法、输出三地址码)

学号:0121410870922课程设计课程编译原理题目For语句的翻译程序设计(简单优先法、输出三地址码)学院计算机科学与技术学院专业计算机科学与技术班级计算机1404姓名王承禹指导教师林泓2016年12月27日;目录1 系统描述 (4)1.1设计目的 (4)1.2设计内容描述 (4)2 文法及属性文法的描述 (4)3 语法分析方法描述及语法分析表设计 (6)3.1语法分析方法描述 (6)3.2分析法操作步骤 (6)3.3优先关系矩阵 (8)4 中间代码形式的描述及中间代码序列的结构设计 (9)4.1中间代码形式 (9)5 编译系统的概要设计 (10)5.1数据结构 (10)5.2模块设计 (11)5.2.1词法分析模块 (11)5.2.2语法、语义分析模块 (12)5.2.3主控模块 (18)6 详细的算法描述 (19)6.1词法分析算法 (19)26.2语法分析算法 (19)6.3语义分析算法 (20)7 软件的测试方法和测试结果 (21)8 本设计的评价、特点、 (22)9 收获与体会 (23)10 核心代码 (25)成绩评定表 (45)3For语句的翻译程序设计(简单优先法、输出三地址码)1 系统描述1.1设计目的通过学习编译原理的相关内容,设计并编写FOR循环语句的翻译程序,使用简单优先法,按三地址码输出,能够实现词法分析,语法和语义的分析,加深对所学知识的理解,并且能够熟练运用到实际当中。
1.2设计内容描述FOR循环语句的基本格式如下:FOR i=E step E until E do Stmt根据所给题目要求,设计出符合FOR循环语句的文法及属性文法的描述,语法分析方法以及三地址码的输出方式,罗列出词法分析和语法分析的流程,根据语法规则设计输入输出方法,简单优先法中的优先关系表格。
设计好并且进行编译,设计若干输入输出用例(包括正确的输入和错误的输入,用来检查程序的完整性)。
2 文法及属性文法的描述根据For语句的特点,制定的产生式规则及由产生式对应的语义动作如下:4F1 -> for i = E1{emit(entry(i) , ' = ' , E1.place);F1.place = entry(i);/*保存控制变量在符号表中的位置*/F1.chain = nextstat;emit('goto'--);/*goto OVER*/F1.codebegin = nextstat;/*保存AGAIN的地址*/}F2 -> F1 step E2{F2.codebegin = F1.codebegin;F2.place = F1.place;emit(F1.place '=' E2.place '+' F1.place);backatch(F1.chain,nextstat);}F3 -> F2 until E3{F3.codebegin = F2.codebegin;q = nextstat;emit('if' F2.place, '<=' E3.place, 'goto' q+2);/*若i<=E3 转去执行循环体的第一个三地址码*/F3.chain = nextstat;emit('goto'--)/*转离循环*/}S -> F3 do Stmt{emit ('goto' F3.codebegin)/*goto AGAIN*/backpatch(Stmt.chain,F3.codebegin);Stmt.chain = F3.chain/*转离循环的转移目标留待外层S时再回填*/}53 语法分析方法描述及语法分析表设计3.1语法分析方法描述本次课内实践要求使用简单优先关系方法。
c语言 三种循环语句的等价转换

c语言三种循环语句的等价转换
C语言中有三种循环语句,分别是for循环、while循环和do-while循环。
这些循环语句可以相互转换,但需要注意一些细节。
首先是for循环的等价转换。
for循环可以转换为while循环,只需将循环的初始化、条件判断和更新表达式分别放在while循环
的前置、循环条件和循环体内即可。
例如,for(int i=0; i<10;
i++) 循环可以转换为 while(int i=0; i<10) { ...; i++; }。
其次是while循环的等价转换。
while循环可以转换为do-
while循环,需要在while循环结束后将循环条件再次写在do-
while循环的循环体下方。
例如,将 while(i<10) { ...; i++; }
转换为 do { ...; i++; } while(i<10);。
最后是do-while循环的等价转换。
do-while循环可以转换为while循环,需要将循环体和循环条件整体放入while循环内,并
删除do-while循环的部分。
例如,将 do { ...; i++; }
while(i<10); 转换为 while(i<10) { ...; i++; }。
需要注意的是,在进行循环语句的等价转换时,要确保转换后
的循环具有相同的语义和逻辑结构,以保证程序的正确性。
另外,在转换过程中要注意变量的作用域和循环控制条件的正确性,以免引入错误。
希望以上回答能够满足你的要求。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学号:0120810680326课程设计题目f or循环语句的翻译程序学院计算机学院专业软件工程班级0803姓名徐泽前指导教师何九周2011 年 6 月日目录1设计目的 (4)2设计环境与工具 (4)3设计任务要求与说明 (4)4设计时间 (4)5设计地点 (4)6系统描述 (4)7文法及属性文法的描述 (5)7.1文法描述 (5)7.1.1 FOR语句相关的产生式: (5)7.1.2 布尔表达式: (5)7.1.3 赋值表达式: (5)7.2属性文法的描述 (5)8 语法分析方法描述及语法分析表设计 (7)8.1语法分析方法描述 (7)8.2系统中使用的action和goto表(见附录1) (9)9 给出中间代码形式的描述及中间代码序列的结构设计 (9)10简要的分析与概要设计 (10)11 详细的算法描述 (11)11.1词法分析的数据结构设计与详细的流程图 (11)11.2词法分析流程图 (11)11.3语法制导翻译的数据结构与详细的设计图 (12)11.3.1数据结构的设计 (12)11.3.2算法描述 (13)11.3.3程序流程图 (13)12给出软件的测试方法和测试结果 (14)12.1 FOR循环语句的测试 (14)12.2词法分析出错处理 (15)12.3语法分析出错处理 (16)13收获与体会 (16)14 参考文献 (17)课程设计任务书学生姓名:徐泽前专业班级:软件0803班指导教师:何九周工作单位:计算机学院题目: for循环语句的翻译程序初始条件:程序设计语言:主要使用C语言的开发工具,或者采用LEX、YACC等工具,也可利用其他熟悉的开发工具。
算法:可以根据《编译原理》课程所讲授的算法进行设计。
要求完成的主要任务:(包括课程设计工作量及其技术要求,说明书撰写等具体要求)1.明确课程设计的目的和重要性,认真领会课程设计的题目,读懂课程设计指导书的要求,学会设计的基本方法与步骤,学会如何运用前修知识与收集、归纳相关资料解决具体问题的方法。
严格要求自己,要独立思考,按时、独立完成课程设计任务。
2.主要功能包括:利用算符优先分析方法和思想对某些语句进行语法分析与语义分析,生成相应的中间代码。
正确运用语法规则,并能应用所学的方法解决存在的问题。
语法分析方法及中间代码形式的描述、文法和属性文法的设计。
2.进行总体设计,详细设计:包括算法的设计和数据结构设计。
系统实施、调试,合理使用出错处理程序。
3.设计报告:要求层次清楚、整洁规范、不得相互抄袭。
正文字数不少于0.3万字。
包含内容:①课程设计的题目。
②目录。
③正文:包括引言、需求分析、总体设计及开发工具的选择,设计原则(给出语法分析方法及中间代码形式的描述、文法和属性文法的设计),数据结构与模块说明(功能与流程图)、详细的算法设计、软件调试、软件的测试方法和结果、有关技术的讨论、收获与体会等。
④结束语。
⑤参考文献。
⑥附录:软件清单(或者附盘)。
时间安排:消化资料、系统调查、形式描述1天系统分析、总体设计、实施计划3天撰写课程设计报告书1天指导教师签名: 2010年 6月 11日系主任(或责任教师)签名: 2010年 6月 11日1设计目的课程设计是对学生的一种全面综合训练,是与课堂听讲、自学和练习相辅相成的必不可少的一个教学环节。
通常,设计题中的问题比平时的练习题要复杂,也更接近实际。
编译原理这门课程安排的课程设计的目的是旨在要求学生进一步巩固课堂上所学的理论知识,深化理解和灵活掌握教学内容,选择合适的数据逻辑结构表示问题,然后编制算法和程序完成设计要求,从而进一步培养学生独立思考问题、分析问题、解决实际问题的动手能力。
2设计环境与工具(1)D OS环境下使用Turbo C;(2)W indows环境下使用Visual C++ ;(3)其它熟悉语言。
3设计任务要求与说明明确课程设计的目的和重要性,认真领会课程设计的题目,读懂课程设计指导书的要求,学会设计的基本方法与步骤,学会如何运用前修知识与收集、归纳相关资料解决具体问题的方法。
严格要求自己,要独立思考,按时、独立完成课程设计任务。
深入理解所学的《编译原理》相关知识,按照软件工程的设计方法进行简要的分析与概要设计,进行总体设计,详细设计、系统实施、调试。
运用程序设计语言实现算法,编写相关程序。
学会正确运用语法规则,并能应用优先关系和结合性解决二义性和冲突问题,有效而正确的利用各种分析方法和思想,合理使用出错处理程序,上机调试通过。
最后撰写课程设计报告。
通过编程实践逐步提高分析问题,解决问题的能力。
4设计时间第17周一周5设计地点鉴主10楼软件实验室6系统描述本系统完成FOR循环语句的翻译程序设计,FOR循环语句的格式为:for(A;B;C)Sx,其中A,B,C均为表达式,分别表示初始化,循环控制条件(这里为布尔表达式)以及使控制条件发生变化,Sx为循环体,可为一个或多个赋值语句。
本系统首先要进行词法分析,即从左到右逐个字符地对源程序进行扫描,产生一个个的单词序列,输出到一个中间文件上,作为语法分析的输入而继续编译过程。
该程序的语法分析能对输入的语法进行分析,判断输入语句是否满足for循环语句的文法。
通过LR分析方法对语句进行分析,看是否能通过给定的输入串归约到文法的开始符号。
一个LR分析器主要由总控程序,分析栈(状态栈和符号栈),输入队列和分析表组成。
在语法分析的同时进行语义分析,最后输出四元式的代码。
7文法及属性文法的描述7.1文法描述本系统中所使用FOR循环语句的文法包括FOR语句本身,赋值表达式和布尔表达式。
具体文法产生式如下:7.1.1 FOR语句相关的产生式:1) S->for(W)Sx 2) W->A;W13) W1->B;W2 4) W2->A5) Sx->Ax 6) Sx->{Am}7)Am->AmAx 8) Am->Ax7.1.2 布尔表达式:9)B->B||L 10) B->L11) L->L&&M 12) L->M13) M->!M 14) M->K15) K->(B) 16) K->false17) K->true 18) K->id19) K->idScid 20) Sc-> !=21) Sc-> == 22) Sc-> <=23) Sc-> >= 24) Sc-> <25) Sc-> >7.1.3 赋值表达式:26) Ax->A; 27) A->id=E28) E->E+T 29) E->E-T30) E->T 31) T->T*F32) T->T/F 33) T->F34) F->id 35) F->(E)36) F->num7.2属性文法的描述在本程序中用了三个变量来传递各种属性,TrueOrchain表示判断条件为真时的链号或者为句子的chain,FalseOrend表达判断条件为假时的链号,codeBegin表达代码的开始地址。
neststat指向下一四元式的地址,emit即为对四元式代码的打印,还需要下面三个函数:1.chainMerge( p1 , p2),把p1和p2为链首的两条链合并为一条。
返回合并后的链首值。
即将p2的链尾第4区段改为p1,合并后的链首为p2,除非p2是空链。
2.backpatch(p , t),把p所链接的每个四元式的第4区段都填为t。
其中使用语义值codeBegin与非终结符E相连,表示表达式E的第1个四元式语句的序列。
3.objectCode.insert(objcode),把中间代码存到objectCode中并把nextatat加1。
具体的需要传递属性的产生式的属性文法如下表所示:产生式属性文法S->for(W)Sx emit(1);//生成最后一个jumpbackpatch(nextstat,LastGotoAddress);//回填最后一个jump; backpatch(W.FalseOrEnd ,nextstat);//B为假则跳到最后四元式W1->B;W2 backpatch(B.TrueOrChain,W2.TrueOrChain); backpatch(W2.FalseOrEnd , B.codeBegin );W2->A emit(4);//输出跳转W2.TrueOrChain = nextstat; W2.FalseOrEnd = nextstat-1;Sx->{Am} 去掉{}B->B1||L backpatch(B1.FalseOrEnd, L.codeBegin );//回填B.codeBegin =B1.codeBegin ;B.TrueOrChain=chainMerge(B1.TrueOrChain,L.TrueOrChain);B.FalseOrEnd = L.FalseOrEnd ; LastGotoAddress=nextstat;//记录最后jump回填地址B->L LastGotoAddress=nextstat;//记录最后jump回填地址L->L1&&M backpatch(L1.TrueOrChain , M.codeBegin );//回填L.codeBegin =L 1.codeBegin ;L.TrueOrChain =M.TrueOrChain ;L.FalseOrEnd=chainMerge(L 1.FalseOrEnd,M.FalseOrEnd );M->!M 1 M.TrueOrChain =M 1.FalseOrEnd;M. FalseOrEnd =M 1。
TrueOrChainM.codeBegin =M 1.codeBegin ;K->idScid K.TrueOrChain =nextstat;K.codeBegin =nextstat;K.FalseOrEnd = nextstat+1;emit(J+Sc,id,id, );//输出跳转语句emit(jump,-,-, );A->id=Eemit(E,- ,- ,id);//输出赋值语句 E->EoperT(oper 为+-*/) emit(oper , E , T , temp);//输出表达式8 语法分析方法描述及语法分析表设计8.1语法分析方法描述本程序采用SLR (1)分析方法,简单的LR(1),即只在动作不唯一的地方向前查看一个符号,在动作唯一时不向前查看输入符号。