中间代码生成实验报告材料

合集下载

天津理工大学编译原理实验3:语义分析与中间代码生成

天津理工大学编译原理实验3:语义分析与中间代码生成

实验报告学院(系)名称:计算机与通信工程学院
【实验过程记录(源程序、测试用例、测试结果及心得体会等)】
根据语法分析修改的程序流程图
开始
从输入串获取字符与符号栈比较关系>|=
归约>将符号移进符号栈
是否成功
Error 出错处理Y
结束
输出结果
N
从标识符中查找数值
压入语义栈
根据四元式修改语义栈
程序运行结果:
部分源代码:
心得体会:
这次实验做得还是不够理想,虽然做出了语法制导翻译的全过程,但是还有部分地方不够完美。

例如四元式的使用及输出,不过总体来说,也算是深入的掌握了语法制导翻译的全过程,获益匪浅。

中间代码生成实验报告

中间代码生成实验报告

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

lab14语义分析报告报告材料与中间代码生成

lab14语义分析报告报告材料与中间代码生成

实验报告封面课程名称:编译原理课程代码:SS2027任课老师:彭小娟实验指导老师: 彭小娟实验报告名称:实验十四:语义分析与中间代码生成1学生姓名:学号:教学班:递交日期:签收人:我申明,本报告内的实验已按要求完成,报告完全是由我个人完成,并没有抄袭行为。

我已经保留了这份实验报告的副本。

申明人(签名):实验报告评语与评分:评阅老师签名:彭小娟一、实验名称:语义分析与中间代码生成1二、实验日期: 年 月 日三、实验目的:1. 理解相关概念:中间代码、三地址码,各种语句的目标代码结构2. 掌握三地址码(三元式、四元式、DAG 图),3. 理解赋值语句三地址代码的翻译模式四、实验用的仪器和材料:(操作系统:CPU :内存:硬盘:软件:)硬件:PC 人手一台软件:office五、实验的步骤和方法:1. 给出下面中缀式的逆波兰表示(后缀式),后缀式的中缀式表示/*)(*)/(*++-+-+-++e d c ab d c b a e d c b anot A or not (C or not D)2. 请将表达式-(a+b)*(c+d)-(a+b+c)分别表示成三元式、四元式序列。

3. 按7.3节所说的方法,写出下面赋值句)A+=的自下而上语法制导B-(*:DC翻译过程。

给出所产生的三地址代码。

六、数据记录和计算:七、实验结果或结论:(总结)八、备注或说明:可写上实验成功或失败的原因,实验后的心得体会、建议等。

九、引用参考文献:即在本实验中所引用的之資料。

中间代码生成实验报告doc

中间代码生成实验报告doc

中间代码生成实验报告篇一:编译方法实验报告(中间代码生成器)编译方法实验报告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/C++,开发工具为 Visual Studio 2019,操作系统为 Windows 10。

三、实验内容(一)词法分析器的设计与实现词法分析是编译过程的第一个阶段,其任务是从输入的源程序中识别出一个个具有独立意义的单词符号。

在本次实验中,我们使用有限自动机的理论来设计词法分析器。

首先,我们定义了单词的种类,包括关键字、标识符、常量、运算符和分隔符等。

然后,根据这些定义,构建了相应的状态转换图,并将其转换为程序代码。

在实现过程中,我们使用了字符扫描和状态转移的方法,逐步读取输入的字符,判断其所属的单词类型,并将其输出。

(二)语法分析器的设计与实现语法分析是编译过程的核心环节之一,其任务是在词法分析的基础上,根据给定的语法规则,判断输入的单词序列是否构成一个合法的句子。

在本次实验中,我们采用了自顶向下的递归下降分析法来实现语法分析器。

首先,我们根据给定的语法规则,编写了相应的递归函数。

每个函数对应一种语法结构,通过对输入单词的判断和递归调用,来确定语法的正确性。

在实现过程中,我们遇到了一些语法歧义的问题,通过仔细分析语法规则和调整函数的实现逻辑,最终解决了这些问题。

(三)语义分析与中间代码生成语义分析的任务是对语法分析所产生的语法树进行语义检查,并生成中间代码。

在本次实验中,我们使用了四元式作为中间代码的表示形式。

在语义分析过程中,我们检查了变量的定义和使用是否合法,类型是否匹配等问题。

同时,根据语法树的结构,生成相应的四元式中间代码。

(四)代码优化代码优化的目的是提高生成代码的质量和效率。

在本次实验中,我们实现了一些基本的代码优化算法,如常量折叠、公共子表达式消除等。

通过对中间代码进行分析和转换,减少了代码的冗余和计算量,提高了代码的执行效率。

中间代码生成

中间代码生成

中间代码生成计算机科学与工程学院课程设计报告题目全称:常用边缘算法的实现学生学号: 2506203010 姓名:王嘉指导老师:职称:指导老师评语:签字:课程设计成绩:设计过程表现设计报告质量总分编译器中间代码生成的研究与实现作者:王嘉学号:2506203010 指导老师:吴洪摘要:在编译器的翻译流水线中,中间代码生成是处于核心地位的关键步骤。

它的实现基于语法分析器的框架,并为目标机器代码的实现提供依据。

虽然在理论上没有中间代码生成器的编译器也可以工作,但这将会带来编译器的高复杂度,低稳定性和难移植性。

现代编译理论不仅要求中间代码的生成,还要求基于中间代码的优化。

本文研究并实现了一个轻量级类C语言的中间代码生成器,并就中间代码生成的原理进行了细致的阐述。

关键字:中间代码生成、语法制导翻译、翻译模式、语法树、三地址码一、目的及意义在编译器的分析综合模型中,前端将源程序翻译成一种中间表示,后端根据这个中间表示生成目标代码。

目标语言的细节要尽可能限制在后端。

尽管源程序可以直接翻译成目标语言,但使用与机器无关的中间形式具有以下优点:1.重置目标比较容易:不同机器上的编译器可以在已有前端的基础上附近一个适合这台新机器的后端来生成。

2.可以在中间表示上应用与机器无关的代码优化器。

本文介绍如何使用语法制导方法,基于一种轻量级的类C语言FineC的词法分析器和语法分析器,一遍地将源程序翻译成中间形式的编程语言结构,如声明、赋值及控制流语句。

为简单起见,我们假定源程序已经经过一遍扫描,生成了相应的词法记号流和符号表、词素表结构。

基于FineC语法标准的语法分析器框架也已经能够正常工作。

我们的任务就是补充这个框架,使其在语法分析的过程中生成相应的中间代码,并将必要的变量和函数声明存放在一个符号表链中。

二、目标语言词法和语法标准:这里定义一个编程语言称作FineC(“fine”指代轻量、精妙)。

它是一种适合编译器设计方案的语言。

编译方法实验报告(中间代码生成器)

编译方法实验报告(中间代码生成器)

编译方法实验报告2011年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 <iostream>#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--zint 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<j;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]<='p')||(exp[i]>='0' && exp[i]<='9')){ 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++;}六、总结与分析我们知道, 定义一种语言除了要求定义语法外, 还要求定义语义, 即对语言的各种语法单位赋予具体的意义。

中间代码生成实验报告

中间代码生成实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

一、实验目的通过在实验二的基础上,增加中间代码生成部分,使程序能够对实验二中的识别出的赋值语句,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*67 then f:=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+67 then while a-7>98+45*45 do f:=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五、实验小结终于完成了编译原理的三次实验,这几次实验使我们更彻底地巩固了编译原理。

从詷法分析到语法分析直到这次的中间代码都是看似简单的基础知识,却花了不少时间对课本多次反复研究、请教学习,进行深层次地探讨才找出编程时出现的种种问题。

还有很多程序方面很细节的问题,很容易被突略,却往往又是关键。

总地来说,虽然实验做得很辛苦,但真的可以从实验当中学习到很多,认识到很多。

并对编译理解也透彻了许多,比较清晰地掌握了编译程序的原理和方法。

附录:#include<string.h>#include<stdio.h>#include<stdlib.h>#define reser 20char *charstring="abcdefghijklmnopqrstuvwxyz";char *numstring="0123456789";char *strstring="abcdefghijklmnopqrstuvwxyz0123456789";char reserve[reser][10];char idshed[40][10],opshed[40][10];char token[15],id[15],sym[15];char line[80],tempp[240];char ch,ch1,temp,tem;char tx[10];char tn[4],signt1[20],signt2[20],ju[20];int cc,ii,k,num,kind,t,e4=0,e3=0,judge=1,row1=0;int startc,idsh=0,opsh=0,tt=1,nn=1,signwh,over=0,adds=0,whs=0,pp=0;int li=0;char filename[15];FILE *fp;void getch(){if(li==0) {if (cc==ii){cc=1; ii=0;if (row1==1) fseek(fp,-1,1); /*读行首字符将指针退回一格,若是整个文本的开头,则不需要*/line[0]=fgetc(fp);row1=1;while(((temp=fgetc(fp))!='\n') && (temp!=EOF)){ line[cc]=temp;cc++;tempp[pp]=temp;pp++;}line[cc]=' '; /*将缓冲带后加上一个空字符,以便行和行之间号区分*/cc++;tempp[pp]=' ';pp++;while(((temp=fgetc(fp))=='\n') && (temp!=EOF)); /* 跳过空行*/ line[cc]='\0';}tem=line[ii];ii++;ch=tem;}else{ch=tempp[pp];pp++;}}void getnbc(){getch();while (ch==' ')getch();if (ch=='{'){do{getch();}while( ch=='}');getnbc();}}void retract(){ii--;}void ret(){pp--;}int jchar(char ch){ /* 判断ch是不是字母*/ if(strchr(charstring,ch)==0)return 0;else return 1;}int jnum(char ch){ /* 判断ch是不是数字*/ if(strchr(numstring,ch)==0)return 0;else return 1;}int jstr(char ch){ /* 判断ch是不是字母或数字*/ if(strchr(strstring,ch)==0)return 0;else return 1;}void advance(){getnbc();kind=0;if (jchar(ch)==1){k=0;do {if(k<15){ token[k]=ch; k++;}getch(); }while(jstr(ch)==1);if (li==0)retract();else ret();token[k]='\0'; /*截去token中的无用字符*/ strcpy(id,token);for(t =0;t<=20;t++){if(strcmp(reserve[t],id)==0)break;}if ( t<=20 ) kind=t ;else kind=21;strcpy(sym,id);}elseif (jnum(ch)==1){k=0;do{if ( k<15 ) {token[k]=ch; k++;}getch();}while( jstr(ch)==1);if (li==0)retract();else ret();kind=22;token[k]='\0';strcpy(sym,token);}else{if(ch=='.') kind=26;k=0;do{sym[k]=' '; k++;}while(k!=15);sym[0]=ch;sym[1]='\0';}}void error(int n){judge=0; /*出错退出,将judge=0*/switch(n){case 0:{printf(" Error(0):Expect ':' \n"); break;}case 1:{printf(" Error(1):Expect '=' \n"); break;}case 2:{printf(" Error(2):Syntax error \n");break;}case 3:{printf(" Error(3):Except Operater \n");break;}case 4:{printf(" Error(4):Except ID or NUM \n");break;}case 5:{printf(" Error(5):Except ';' \n");break;}case 6:{printf(" Error(6):Except '<' or '>'\n");break;}case 7:{printf(" Error(7):Except '=' \n" );break;}case 8:{printf(" Error(8):Except 'then' \n");break;}case 9:{printf(" Error(9):Except Condition Expression\n ");break;} case 10:{printf(" Error(10):Except 'do' ");break;}default:; }}void e(){advance();if((strcmp(sym,"+")==0)||(strcmp(sym,"-")==0)||(strcmp(sym,"*")==0)||(strcmp(s ym,"%")==0)){ printf("%s",sym);advance();if((kind==21) || (kind==22)){ /* kind为21,22分别表示的是标志符和数字*/ printf("%s",sym);e();}else { e4=1 ;error(4);} } /*出错退出,e4=1*/}void c(){advance();if((kind==21) || (kind==22)){printf("%s",sym);e();if(e4==1); /*e4的作用是判断程序从e()中是不是出错退出*/ else {if(strcmp(sym,">")==0){printf("%s",sym);advance();if((kind==21) || (kind==22)) {printf("%s",sym);e();}else{error(4);}}else {if(strcmp(sym,"<")==0){printf("%s",sym);advance();if(strcmp(sym,"=")==0){printf("%s",sym);advance();if((kind==21) || (kind==22)){printf("%s",sym);e();}else{error(4);}} else{error(7);}} else{error(6);}}}}else{e3=1; error(9);} /*出错退出,e3=1*/}void statement(){if(judge==1) /*judge的作用为判断程序是不是出错退出,若是,则无需advance()*/advance();switch (kind){case 21:{ /* id */printf("%s",sym);advance();if(strcmp(sym,":")==0){ printf("%s",sym);advance();if(strcmp(sym,"=")==0){printf("%s",sym);advance();if((kind==21) || (kind==22)){printf("%s",sym);e();if(e4==1) ;else{if(strcmp(sym,";")==0){printf("%s",sym);judge=1;printf(" success!!!\n");startc=1;}else error(5); }e4=0; /*将e4重新置为0,以免对下面程序有影响*/ }else error(4);} else{ error(1);}} else { error(0);}break;}case 8:{ printf("%s ",sym); /* if */c();if(e4==1);else{ if(e3==1); /*e3的作用是判断程序从c()中是不是出错退出*/ else{if(strcmp(sym,"then")==0){printf(" %s ",sym);statement();}else{error(8);}}e3=0; /*将e3重新置为0,以免对下面程序有影响*/}e4=0;break;}case 19:{ /* while */printf("%s ",sym);c();if(e4==1);else{ if(e3==1);else{if(strcmp(sym,"do")==0){printf(" %s ",sym);statement();}else{error(10);}}e3=0;}e4=0;break;}default: { printf("%s ",sym);error(2);judge=1;break;} }}void pushid(){strcpy(idshed[idsh],sym);idsh++;}void pushop(){strcpy(opshed[opsh],sym);opsh++;}void gen(char op[10],char a[10],char b[10]){printf("(%d) [ %2s,%3s,%3s, T%d ]\n",nn,op,a,b,tt);tt++;nn++;itoa(tt-1,tn,10);strcpy(tx,"T");strcat(tx,tn);}void ec(){advance();pushop();advance();pushid();if((strcmp(opshed[opsh-1],"*")==0)||(strcmp(opshed[opsh-1],"%")==0)){gen(opshed[opsh-1],idshed[idsh-2],idshed[idsh-1]);opsh--;idsh=idsh-1;strcpy(idshed[idsh-1],tx);} else{if((strcmp(opshed[opsh-1],"+")==0)||(strcmp(opshed[opsh-1],"-")==0)){ adds=1;if((strcmp(opshed[opsh-2],"+")==0)||(strcmp(opshed[opsh-2],"-")==0)){gen(opshed[opsh-2],idshed[idsh-3],idshed[idsh-2]);strcpy(idshed[idsh-2],tx);}} }advance();if((strcmp(sym,"+")==0)||(strcmp(sym,"-")==0)||(strcmp(sym,"*")==0)||(strcmp(sym,"%")==0)){if (li==0)retract();else ret();ec(); }}void content(){int reu;reu=nn;switch(kind){ case 21:{advance();advance();advance();pushid();advance();if((strcmp(sym,"+")==0)||(strcmp(sym,"-")==0)||(strcmp(sym,"*")==0)||(strcm p(sym,"%")==0)){if (li==0)retract();else ret();ec();if (adds==1)gen(opshed[opsh-1],idshed[idsh-2],idshed[idsh-1]);adds=0;printf("(%d) [ :=, %s, -, %s ]\n",nn,tx,idshed[0]);nn++;opsh=0;}else{printf("(%d) [ :=, %s, -, %s ]\n",nn,idshed[1],idshed[0]);nn++;}break;}case 8:{idsh=0;opsh=0;advance();pushid();advance();if((strcmp(sym,"+")==0)||(strcmp(sym,"-")==0)||(strcmp(sym,"*")==0)||(strcm p(sym,"%")==0)){if (li==0)retract();else ret();ec();if(adds==1)gen(opshed[opsh-1],idshed[idsh-2],idshed[idsh-1]);adds=0;strcpy(signt1,tx);idsh=0;opsh=0;}else{strcpy(signt1,idshed[0]);}if(strcmp(sym,">")==0)strcpy(ju,"j>");else{strcpy(ju,"j<=");advance();}idsh=0;opsh=0;advance();advance();if((strcmp(sym,"+")==0)||(strcmp(sym,"-")==0)||(strcmp(sym,"*")==0)||(strcm p(sym,"%")==0)){if (li==0)retract();else ret();ec();if (adds==1)gen(opshed[opsh-1],idshed[idsh-2],idshed[idsh-1]);adds=0;strcpy(signt2,tx);idsh=0;opsh=0;}else{strcpy(signt2,idshed[0]);}printf("(%d) [%s, %s, %s, (%d) ]\n",nn,ju,signt1,signt2,nn+1);nn++;advance();idsh=0;opsh=0;if(kind==21) pushid();content();break;}case 19:{idsh=0;opsh=0;advance();pushid();advance();if((strcmp(sym,"+")==0)||(strcmp(sym,"-")==0)||(strcmp(sym,"*")==0)||(strcm p(sym,"%")==0)){if (li==0)retract();else ret();ec();if(adds==1)gen(opshed[opsh-1],idshed[idsh-2],idshed[idsh-1]);adds=0;strcpy(signt1,tx);idsh=0;opsh=0;}else{strcpy(signt1,idshed[0]);}if(strcmp(sym,">")==0)strcpy(ju,"j>");else{strcpy(ju,"j<=");advance();}idsh=0;opsh=0;advance();pushid();advance();if((strcmp(sym,"+")==0)||(strcmp(sym,"-")==0)||(strcmp(sym,"*")==0)||(strcm p(sym,"%")==0)){if (li==0)retract();else ret();ec();if (adds==1)gen(opshed[opsh-1],idshed[idsh-2],idshed[idsh-1]);adds=0;strcpy(signt2,tx);idsh=0;opsh=0;}else{strcpy(signt2,idshed[0]);printf("(%d) [%s, %s, %s, (%d) ]\n",nn,ju,signt1,signt2,nn+1);nn++;advance();idsh=0;opsh=0;if(kind==21) pushid();content();printf("(%d) [j, _, _, (%d)]\n",nn,reu);nn++;break; }default:{break; }}}main(){strcpy(reserve[8],"if");strcpy(reserve[19],"while");strcpy(reserve[4],"do");strcpy(reserve[16],"then");printf("Please Input Source Program Filename:");scanf("%s",filename);fp=fopen(filename,"r");cc=0;ii=0;ch='\0';while (kind!=26) /*kind==26为读到了'.',程序结束*/{startc=0;pp=0;statement();li=1;if(startc==1){pp=0;advance();pushid();content(); }} }。

相关文档
最新文档