编译器_编译原理课程设计报告书
编译原理课程设计报告
《编译原理》课程设计报告一、课程设计目的通过课程设计进一步理解高级语言在计算机中的执行过程,了解现代编译器的运作机制,加深对编译原理中重点算法和编译技术的理解,提高自己自学和理解的能力。
学会如何利用已有软件JFLex、Java_cup对词法分析器及语法分析器的构造。
二、设计概述本tiger语言编译器的编译过程涉及到编译五个阶段中的二个,即词法分析器、语法分析器。
其中语法分析后还完成了语法树的打印的构造以及类型检查。
词法分析器由JFLex编译正则式生成,词法分析器编译产生式生成,语法分析器由CUP生成。
结果通过GUI界面呈现在使用者面前。
编译程序需要在单词级别上来分析和翻译源程序,所以首先要识别出单词,而词法分析部分的任务是:从左至右扫描源程序的字符串,按照词法规则(正则文法规则)识别出一个个正确的单词,并转换成该单词相应的二元式(种别码、属性值)交给语法分析使用。
因此,词法分析是编译的基础。
执行词法分析的程序称为词法分析器。
语法分析是编译程序的核心部分,其主要任务是确定语法结构,检查语法错误,报告错误的性质和位置,并进行适当的纠错工作。
三、设计过程(一)设计构思程序主要完成三大功能模块:词法分析器、语法分析器、GUI人机交互界面。
词法分析器由JFLex编译正则式生成,其中必须为外界提供一个获取记号流的接口,实验中定为java_cup.runtime.Symbol next_token。
语法分析器是建立在词法分析器上的,故必须包含词法分析器以便获得记号流,next_token为语法分析器提供TOKEN,语法分析器的对外接口是:java_cup.runtime.Symbol debug_parse(),同时返回语法树的根节点。
GUI 界面是提供人机交互的,它能够依次显示词法分析阶段分析得到的所有TOKEN 的信息,语法阶段生成的语法树,另外对于词法和语法阶段出现的错误在“错误提示”文本框中一一列举出来,提供用户改进代码的信息。
编译原理课程设计C-语言编译器
编译原理课程设计报告课题名称: C-语言编译器设计提交文档学生姓名:李杰提交文档学生学号:0743041240同组成员名单:无指导教师姓名:金军N不指导教师评阅意见:..提交报告时间: 2010年 6 月 10日1.课程设计目标实验建立C-编译器。
只含有scanner和parser部分。
2.分析与设计(1)实现方法:编程语言为C语言。
编程方法:scanner部分根据DFA图用switch-case结构实现状态转换;parser部分用递归下降分析方法实现。
(2)扫描器:C-惯用的词法1、语言的关键字:else if int return void while2、专用符号:+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */3、其他标记是ID和NUM,通过下列正则表达式定义:ID = letter letter* NUM = digit digit* letter = a|..|z|A|..|Z digit = 0|..|94、空格由空白、换行符和制表符组成。
空格通常被忽略,除了它必须分开ID、NUM关键字。
5. 注释用通常的C语言符号/ * . . . * /围起来。
注释可以放在任何空白出现的位置(即注释不能放在标记内)上,且可以超过一行。
注释不能嵌套各单词的状态转换图(DFA图如下)词法结构见文件"globals.h"中。
(3)分析器:分析树结构见文件"globals.h"中。
C-的BNF语法如下:(4)代码设计说明:程序结构:语法分析函数parse通过调用词法分析函数getToken实现语法分析。
文件和函数的设计说明:文件main.c包含相应头文件,及main函数的实现;文件golbals.h 包含符号表和分析数的数据结构及在其它文件中使用的变量;文件util.h 和util.c实现与词法分析和语法分析输出相关的函数printToken和printTree,以及分析树节点初始化相关的函数newStmtNode,newExpNode(Expkind)和copyString;文件scan.h 和scan.c实现词法分析,主要函数为getToken;文件parse.h 和parse.c实现语法分析,函数为与文法规则对应的函数。
编译原理课程设计报告
课程设计报告( 2021--2022年度第一学期)名称:编译技术课程设计题目:算符优先分析法研究院系:班级:学号:学生姓名:指导教师:设计周数:一周成绩:日期:2021年12 月31日1 课程设计的目的和要求1.1 课程设计的目的本次设计的时间为1周,目的是通过使用高级语言实现部分算法加强对编译技术和理论的理解。
设计的题目要求具有一定的规模,应涵盖本课程内容和实际应用相关的主要技术。
1.2 课程设计的要求1. 文法使用产生式来定义;2. 分别给出每一个非终结符的FIRSTVT和LASTVT集。
3. 画出算符优先关系表;4. 判定给定的文法是否是算符优先文法;5. 给定符号串判定是否是文法中的句子,分析过程用分析表格的方式打印出来。
2 系统描述举例如下:本次实验使用Visual Studio 2019软件,利用只规定终结符之间的优先关系的自底向上移进-规约法实现对算符优先分析法的研究,输出非终结符的FIRSTVT和LASTVT集,算符优先关系表和对句子的分析表格,均在DOS窗口显示。
2.1 文法的描述G[S]: S->#E#;E->E+T|T;F-P!F|P;T->T*F|F;P->(E)|i2.2 属性文法的描述表2-1 条件语句及其语义规则3 概要设计3.1 概要设计(体现系统的设计思路和主要功能)主要步骤包括:用户自己输入文法,实质上是算数表达式的计算。
构建每个非终结符的FirstVT()和LastVT()集。
构建优先关系符号表。
构建词法分析的程序。
编写主函数,用户输入文法对语句利用算符优先文法进行判别。
算法的主体思想:用栈存储已经看到的输入符号,用优先关系指导移动归约语法分析器的动作,如果栈顶的终结符和下一个输入符之间的优先关系是<或=,则语法分析器移动,表示还没有发现句柄的右端,如果是>关系,就调用归约。
3.2 开发环境实验采用C++程序语言进行设计开发工具为Visual Studio 20194 详细设计4.1 系统的类图图4-1 文法类图4.2 主要算法的流程图图4-2 求非终结符的FIRSTVT 和LASTVT 集流程图求LASTVT 集的过程与此类似,但符号串的扫描顺序是从后开始若产生式右部第一个字符为非终结符 则直接将其加入first 集中else first[x].insert(str[0]);寻找该非终结符 的first 集 dfs(y);将该非终结符的first 集也加进去for (; it != first[y].end(); it++)first[x].insert(*it);if (isupper(str[0]))若产生式右部第一个字符为非终结符 string& left = VN_set[x].left;string&str = VN_set[x].right[i];产生产生式左部非终结符的FIRSTVT 集图4-3 构造算符优先关系表流程图图4-4 对输入串进行算符优先分析流程图4.3 数据分析与定义char relation[MAX][MAX]; //算符优先关系表vector<char> VT;vector<WF> VN_set; //类型为文法的数组VN_setmap<string, int> VN_dic; //map映射,一条产生式对应的第几条的序号set<char> first[MAX]; //FIRSTVT集set<char> last[MAX]; //LASTVT集4.4 系统界面设计用户输入文法个数和每条产生式的内容后,输出结果格式如下:分为:产生式、FIRSTVT集、;LASTVT集、算符优先关系表和分析过程图4-5 系统输出界面概况5 测试方法和测试结果5.1 测试用例1输入如程序5-1所示。
编译原理课程设计报告
实验要求✧基本内容1)增加单词:保留字ELSE,REPEAT,DOWHILE,RETURN运算符+=,-=,++,--2)修改单词:不等号# 改为<>3)增加条件语句的ELSE子句4)扩充赋值运算:+= 和-=5)扩充语句(Pascal的FOR语句):①FOR <变量>:=<表达式> TO <表达式> DO <语句>②FOR <变量>:=<表达式> DOWNTO <表达式> DO <语句>其中,语句①的循环变量的步长为2,语句②的循环变量的步长为-2。
✧选做内容1)增加运算:++ 和--。
2)增加类型:①字符类型;②实数类型。
3)扩充函数:①有返回值和返回语句;②有参数函数。
4)增加一维数组类型(可增加指令)。
5)其他典型语言设施。
设计方案1.概述:源、目标语言:编译程序编绎的源程序是PL0,程序产生的目标代码是一个假想栈式计算机的汇编语言.称为类PCODE指令代码 ,指令格式格式如下:F L A其中F代表功能码,L表示层次差,A表示位移量,不同指令其含义有所区别。
PL/0语言是Pascal语言的一个子集,这里分析的PL/0的编译程序包括了对PL/0语言源程序进行分析处理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类PCODE代码的功能。
PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。
词法分析和代码生成作为独立的子程序供语法分析程序调用。
语法分析的同时,提供了出错报告和出错恢复的功能。
在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE代码。
实现工具(平台),运行平台:编译器实现工具和运行平台程序用C++语言编写,在C++ Builder平台下运行。
2.结构设计说明:PL/0的编译过程采用一趟扫描方式,以语法分析为核心,词法分析程序和代码生成程序都作为一个独立的过程,当语法分析需要读入单词时就调用词法分析程序,而当语法分析正确需生成相应的目标代码时,则调用代码生成程序。
编译原理课程设计报告
2011-2012学年第二学期《编译原理》课程设计报告学院:计算机科学与工程学院班级:学生姓名:学号:成绩:指导教师:时间:2012年5 月目录一、课程设计的目的 ---------------------------------------------------------------- - 1 -二、课堂实验及课程设计的内容 -------------------------------------------------- - 1 -2.1、课堂实验内容-------------------------------------------------------------- - 1 -2.2、课程设计内容-------------------------------------------------------------- - 1 -三、visual studio 2008 简介------------------------------------------------------- - 2 -四、问题分析及相关原理介绍 ----------------------------------------------------- - 3 -4.1、实验部分问题分析及相关原理介绍 ---------------------------------- - 3 -4.1.1、词法分析功能介绍及分析------------------------------------- - 3 -4.1.2、语法分析功能介绍及分析------------------------------------- - 3 -4.1.3、语义分析功能介绍及分析------------------------------------- - 4 -4.2、课程设计部分问题分析及相关原理介绍 ---------------------------- - 5 -4.2.1、编译程序介绍 ----------------------------------------------------- - 5 -4.2.2、对所写编译程序的源语言的描述(C语言) -------------- - 6 -4.2.3、各部分的功能介绍及分析 -------------------------------------- - 7 -4.3、关键算法:单词的识别-------------------------------------------------- - 8 -4.3.1、算法思想介绍 ----------------------------------------------------- - 8 -4.3.2、算法功能及分析 -------------------------------------------------- - 8 -五、设计思路及关键问题的解决方法 ------------------------------------------ - 10 -5.1、编译系统------------------------------------------------------------------ - 10 -5.1.1、设计思路 --------------------------------------------------------- - 10 -5.2、词法分析器总控算法--------------------------------------------------- - 12 -5.2.1、设计思路 --------------------------------------------------------- - 12 -5.2.2、关键问题及其解决方法 --------------------------------------- - 13 -六、结果及测试分析-------------------------------------------------------------- - 14 -6.1、软件运行环境及限制--------------------------------------------------- - 14 -6.2、测试数据说明------------------------------------------------------------ - 14 -6.3、运行结果及功能说明--------------------------------------------------- - 16 -6.4、测试及分析说明--------------------------------------------------------- - 16 -七、总结及心得体会 --------------------------------------------------------------- - 17 -7.1、设计过程------------------------------------------------------------------ - 17 -7.2、困难与收获 ------------------------------------------------------------- - 17 -八、参考文献 ------------------------------------------------------------------------ - 18 -一、课程设计的目的通过设计、编写和调试词法分析程序(又称扫描器),了解扫描器的组成结构,不同种类单词的识别方法,加深了对词法分析作用的理解。
编译原理编译器课程设计
编译原理编译器课程设计一、课程目标知识目标:1. 理解编译原理的基本概念,掌握编译器各阶段的工作原理和实现方法;2. 学会使用一种编程语言(如C、Java等)编写简单的编译器程序;3. 掌握词法分析、语法分析、语义分析及目标代码生成的基本技术和策略;4. 了解优化技术在编译器中的应用,提高程序运行效率。
技能目标:1. 能够运用所学知识独立设计并实现一个简单的编译器;2. 培养学生运用编译原理知识解决实际问题的能力;3. 提高学生的编程实践能力和团队协作能力;4. 培养学生查阅资料、分析问题、总结归纳的能力。
情感态度价值观目标:1. 培养学生对编译原理和编译器开发工作的兴趣,激发学生的学习热情;2. 培养学生勇于探索、积极创新的精神,增强克服困难的信心和毅力;3. 培养学生具备良好的编程习惯,遵循职业道德,为我国软件产业的发展贡献自己的力量。
本课程旨在通过编译原理编译器课程设计,使学生掌握编译器的基本原理和技术,提高编程实践能力,培养团队协作精神,激发学生的学习兴趣和创新精神。
课程性质为理论与实践相结合,注重培养学生的实际操作能力。
针对学生的年级特点,课程内容将逐步深入,从基本概念到实际应用,引导学生由浅入深地掌握编译器相关知识。
在教学过程中,教师需关注学生的学习进度,及时调整教学策略,确保课程目标的实现。
通过本课程的学习,学生将具备独立设计和实现简单编译器的能力,为后续相关课程的学习打下坚实基础。
二、教学内容1. 编译原理概述:介绍编译器的基本概念、发展阶段和组成部分,使学生了解编译器在整个软件开发过程中的地位和作用。
教材章节:第一章2. 词法分析:讲解词法分析器的功能、设计方法,以及正则表达式和有限自动机等基本概念。
教材章节:第二章3. 语法分析:介绍语法分析器的作用、设计方法,以及上下文无关文法、LL(1)、LR(1)等分析方法。
教材章节:第三章4. 语义分析:讲解语义分析器的任务、属性文法、语法制导翻译等概念,以及类型检查和符号表管理方法。
扬大课程设计报告-C语言子集编译器
扬州大学编译原理课程设计题目C语言子集编译器班级学号姓名成绩扬州大学信息工程学院一、课程设计目的通过编译原理课程设计,加深对课堂中所讲授的内容的理解,设计一个具有词法分析、语法、语义分析、错误处理的综合程序。
进一步掌握编译程序常用实现的方法和技术,使学生初步具有研究、设计、编制和调试编译程序的能力。
二、课程设计题目实现一个简单的编译器三课程设计要求1.实现一个C语言子集或Pascal语言子集的编译器,工具任选。
2.要求实现的功能:翻译 +,-,*, / 四则运算表达式及布尔表达式,翻译包含if语句,while语句及do-while语句及相互间的嵌套。
四、课程设计语言及选用工具选用语言:Java工具 Eclipse五、课程设计方法1,本课程设计的数据结构设计过程中用到的栈:static Vector<String>DataStack = new Vector<String>(); 输入流栈static Vector<String>targetAnaStack = new Vector<String>(); 输入备份栈static Vector<String>AnalysStack = new Vector<String>(); 分析栈static Vector<String>KeyWordStack = new Vector<String>(); 保留字栈static Vector<String>JiexanStack = new Vector<String>(); 界限符栈static Vector<String>YunsuanfuStack = new Vector<String>(); 运算符栈中间代码的构造:包括标号,符号,第一操作数,第二操作数,和目的操作数class midCode {String sign;String op1;String op2;LoopLastLocation p1;}class LoopLastLocation { //每一个目的操作数都联系着一个对应的跳转标号String LastLocation;Int BiaoHao;}总体构成:跳转标号(操作符,第一操作数,第二操作数,目的操作数或者跳转标号)2,器主要分为四个部分:词法分析、语法分析、中间代码生成和目标代码生成。
编译原理课程设计报告 编译器
《编译技术》课程设计实验报告实验名称:编译器程序说明:下载请好评姓名:向难学号:200812110106班级:计算机系08本一班2010年11月12日目录一、课设要求 (3)二、总体设计思想 (4)三、详细算法设计 (4)四、流程框图 (5)五、函数相关说明 (9)1. 所有函数一览 (9)2. void emit(char *res,char *num1,char *op,char *num2) (9)3. char *newTemp() (10)4. int merge(int p1,int p2) (10)5. void backpatch(int p,int t) (11)6. void fuzhi() (11)7. void tiaojian(int *nChain) (12)8. void xunhuan() (13)六、程序运行结果 (15)七、编译器使用说明 (17)八、心得与体会 (17)九、源程序清单 (18)一、课设要求用C语言对下述文法和单词表定义的语言设计编制一个编译器。
(1)单词符号及种别表(2)语法结构定义<程序> ::= main()<语句块><语句块> ::= ‘{‘<语句串>’}’//程序用括号括起来<语句串>::=<语句>{;<语句>};<语句>::=<赋值语句>|<条件语句>|<循环语句><赋值语句>::=ID=<表达式> //赋值语句用”=”号<条件语句>::=if<条件><语句块> //条件怎么没有括号,囧(自己加1个)<循环语句>::=do <语句块>while <条件><条件>::=<表达式><关系运算符><表达式> //没有布尔运算,还算简单<表达式> ::= <项>{ +<项>|-<项>}<项> ::= <因子>{*<因子>|/<因子>}<因子> ::=ID|num|(<表达式>)num::=( +|-|ε) 数字*(.数字数字* | ε)( e ( +|-|ε) 数字数字*|ε)ID::=字母(字母|d数字)*字母::=a|b|c…|z|A|B|C…|Z数字::=0|1|2…|9<关系运算符> ::= <|<=|>|>=|==|!=二、总体设计思想采用递归下降(自上而下)的语法制导翻译法。
编译原理课程设计报告
课程设计报告设计题目:一个简单文法的编译器的设计与实现班级:计算机1206班组长学号:2012XXX组长姓名:XXX指导教师:XXX设计时间:2014年12月设计分工组长学号及姓名:2012XXX XXX分工:1)读取源文件进行词法分析2)进行LL(1)分析生成分析表3)设计顶层自动机将源程序分段4)生成可执行的汇编程序组员1学号及姓名:2012XXX XXX分工:1)设计第二层自动机处理程序片段2)生成中间语言四元式3)源程序错误处理组员2学号及姓名:2012XXX XXX分工:1)设计第三层自动机处理复合表达式2)设计带动作的LL(1) 文法3)源程序错误处理摘要编译原理课程具有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,在系统软件中也是占有十分重要的地位。
本次课程设计我们是在Visual C++的平台上应用了词法分析、语法分析、语义分析、中间语言生成以及目标语言生成的知识设计了一个简单的编译器前端。
其中设计了一个简单的有限自动机来扫描源程序即进行语法分析,并生成了关键字表、标志符表、界符表、常数表和Token串;设计了一个LL(1)文法和一个带动作的文法来实现语法分析,并生成了Select集和LL(1)分析表;采用了四元式序列的设计来生成中间语言;通过汇编语言设计来生成目标语言。
最后为了使该编译器更加完善,我们设计了简单的的错误检查机制,能够对源程序进行比较全面的错误检查同时也能够指出错误出现的大致位置,增强了该编译器的健壮性。
关键字:编译器,前端,有限自动机,LL(1)文法,汇编语言,错误处理目录摘要 (3)1、概述 (5)2、课程设计任务及要求 (5)2.1设计任务 (5)2.2设计要求 (6)3、算法与数据结构 (6)3.1词法分析器的算法 (6)3.2 语法分析器的算法 (12)3.2.1 LL(1)文法设计算法 (12)3.2.2递归下降子程序设计算法 (19)3.3中间语言生成器算法 (20)3.4处理复合表达式算法 (24)3.5目标语言生成器算法 (30)3.6数据结构 (39)4、程序设计与实现 (39)4.1编译程序设计与实现 (39)4.2程序实验结果 (39)4.2.1待测源程序 (39)4.2.2词法分析结果 (40)4.2.3语法分析结果 (41)4.2.4中间语言生成结果 (42)4.2.5目标语言生成结果 (43)4.2.6程序错误处理结果 (44)5、参考文献 (44)1、概述本次课程设计的编译程序主要包括了词法分析器、语法分析器、中间代码生成器和目标代码生成器四部分,编译程序的输出结果包括了词法分析后的关键字表、界符表、标识符表和Token串,语法分析后的Select集和LL(1)分析表;中间代码生成器产生的四元式序列。
编译原理课程设计报告
编译原理课程设计报告Tiger编译器的设计与实现张至先5080309910目录1. 介绍 (3)2. 词法分析 (5)3. 语法分析 (6)4. 语义分析 (11)5. 中间代码生成 (18)6. 汇编指令选择 (24)7. 寄存器分配 (28)8. 生成汇编代码 (33)9. 感想 (34)10. 附录A Tiger.flex (35)11. 附录B Grm.cup (39)12. 附录C queens.tig (44)13. 附录D parse.txt (45)14. 附录E lib.s (53)15. 附录F out.s (55)16. 附录G 参考文献 (61)1.介绍本课程设计旨在实现一个Tiger语言的编译器。
1.1Tiger语言规范详见《Tiger Language Reference Manual》。
1.2课程设计所用语言JAVA1.3课程设计参考“虎书”《Modern compiler implementation in JAVA,1st edtion》1.4实验环境(工具)Java 开发环境: Eclipse词法分析器: JFlex语法分析器:CUPMIPS模拟器:PCSPIM1.5设计模块编译器的设计涉及到很多方面,可分为多个模块,从前端(词法分析)到后端(目标代码生成)依次完成。
具体如下(按完成先后顺序):1.词法分析2.语法分析3.语义检查4.中间代码生成5.代码规范化6.汇编指令选择7.寄存器分配8.目标代码生成9.程序运行模块流程图如图1.1所示。
每个模块的实现方法将在接下分章节详述。
图1.1 Tiger编译器模块流程图1.6项目时间安排本学期第十周开始启动该项目,第十四周完成词法分析和语法分析(本项目的前两个模块),第十七周完成至寄存器分配之前,第十八周完成工程及课程设计文档,第十九周提交检查。
1.7项目完成情况基本上符合原计划,现已完成最终的目标代码生成,可以将较复杂的tiger程序编译MIPS 汇编文件,并在模拟器上正确运行。
《编译原理》设计方案报告
《编译原理》课程设计报告设计题目:pl0编译器设计一、PL0程序的文法及,指令及属性翻译简化c语言文法定义(LL(1)文法)C程序::=void main(){函数体}函数体::=变量定义部分语句列变量定义部分::=变量定义变量定义部分| ɛ变量定义::=int 变量表变量表::=标识符|标识符,变量表语句列::=语句语句列| ɛ语句::=条件语句| 循环语句| 读语句| 写语句| 复合语句| 表达式语句| 空语句条件语句::=if(表达式)语句循环语句::=while(表达式)语句读语句::=read(变量表);写语句::=write(表达式表);复合语句::={语句列};表达式语句::=表达式;空语句::=;表达式定义(算符优先文法)表达式::=变量=表达式| 变量+=表达式| 变量-=表达式| 变量*=表达式| 变量/=表达式| 变量%=表达式| 表达式1表达式1::=表达式1 || 表达式2 | 表达式2表达式2::=表达式2&&表达式3 | 表达式3表达式3::=表达式3==表达式4 | 表达式3!=表达式4 | 表达式3>=表达式4 | 表达式3>表达式4 | 表达式3<=表达式4 | 表达式3<表达式4 | 表达式4表达式4::=表达式4+表达式5 | 表达式4-表达式5 | 表达式5表达式5::=表达式5*表达式6 | 表达式5/表达式6 |表达式5/表达式6 |表达式6表达式6::=!表达式7表达式7::=(表达式) | 变量| 常量PL0文法定义《程序》::=《分程序》.《分程序》::=《常量定义》;《常后分程序》|《常后分程序》《常后分程序》::=《变量定义》;《变后分程序》|《变后分程序》《变后分程序》::=《过程定义》;《变后分程序》|《语句》《常量定义》::=const 《常量定义表》《常量定义表》::=id = number | id = number,《常量定义表》《变量定义》::= var 《变量表》《变量表》::=id | id,《变量表》《过程定义》::=procedure id ;《分程序》《语句》::=《赋值语句》|《条件语句》|《循环语句》|《读语句》|《写语名》|《复合语句》| 《过程调用语句》|ε《赋值语句》::=id := 《表达式》《读语句》::=read(《变量表》)《写语句》::=write(《表达式表》)《表达式表》::=《表达式》| 《表达式》,《表达式表》《条件语句》::=if 《条件表达式》then 《语句》《循环语句》::=while 《条件表达式》do 《语句》《复合语句》::=begin 《语句列》end《过程调用语句》::=call id《参量表》::=《有参表》|ε《有参表》::=《表达式》,《有参表》|《表达式》《表达式》::=+《表达式1》|-《表达式1》|《表达式1》《表达式1》::=《表达式1》+《表达式2》|《表达式1》-《表达式2》|《表达式2》《表达式2》::=《表达式2》*《表达式3》|《表达式2》/《表达式3》| 《表达式2》mod 《表达式3》|《表达式3》《表达式3》::=id | number | (《表达式》)《条件表达式》::=《条件表达式》or 《条件表达式1》|《条件表达式1》《条件表达式1》::=《条件表达式1》and 《条件表达式2》| 《条件表达式2》《条件表达式2》::=not 《条件表达式3》|《条件表达式3》《条件表达式3》::=(《条件表达式》)|《关系表达式》《关系表达式》::=《表达式》>《表达式》《关系表达式》::=《表达式》>=《表达式》《关系表达式》::=《表达式》<《表达式》《关系表达式》::=《表达式》<=《表达式》《关系表达式》::=《表达式》=《表达式》《关系表达式》::=《表达式》#《表达式》PL0栈式机指令指令格式:指令码(f) 所在层数差(l),操作数(a)PL0栈式机指令:LIT:将常数a取到栈顶LOD:将位于(当前层-l)层处的变量a取到栈顶STO:将栈顶处值存储到指定位置,l,a同上CALL 调用当前-l层处的过程aINT:为调用过程在栈中开辟数据区,a为单元个数JMP:无条件转移指令,a目标地址JPC:条件转移指令,栈顶值的布尔值为非真时转移到a处,否则执行下面语句OPR:关系运算或算术运算PL0属性翻译MCONST(const:常量定义开始), V AR(var:变量定义开始), PROCEDURE(procedure:过程定义开始),CALL(call:过程调用语句),BEGIN(begon:复合语句开始),END(end:复合语句结束),IF(if:条件语句开始),THEN(then:条件结束),WHILE(while:循环语句开始), DO(do:循环条件结束), READ(read:读语句),WRITE(write:输出语句), ODD(odd:判奇运算),//分隔符、运算符号DOT(点:.),COMMA(逗号:,), SEMICOLON(分号:;), LPAREN(左括号:(), RPAREN(右括号:)), ASSIGNOP(赋值::=), PLUSOP(加法运算符号:+), MINUSOP(减法运算符:-), MULTOP(乘法运算符:*), DIVOP(除法运算符:/),GT(大于:>),GE(大于等于:>=),LT(小于:<),LE(小于等于:<=),EQ(等于:=),NE(不等:#),ENDF(输入结束符),//分析过程中需要的非终结符号SERVERKEY(保留字), FACTOR(因子),ROP(关系运算), CONSTANT(常量部份定义), V ARIABLE(变量部份定义), IDENT(自定义标识符), NUMBER(常数)二、符号表的结构,组织,填写及查找1、符号表结构const char *pName; //符号名称int kind; //符号类别,由上面单词分类确定int val; //符号表中的位置值int level; //符号的层数int parent; //符号的作用域int size; //过程长度char strBuff[MAXLENSTR]; //符号堆2、符号表的组织符号表的组织方式有:线性表、散列表、树结构等,其必须维持源程序中的作用域信息。
编译器-编译原理课程设计报告书
广西大学编译原理课程设计专业:计算机科学与技术姓名:课程:编译原理指导教师:目录一.程序简介与分析---------------------------------------------------------1 二.程序适用范围-----------------------------------------------------------1 三.词法分析---------------------------------------------------------------1 四.语法分析---------------------------------------------------------------3 五.语义分析和中间代码生成------------------------------------------------9 六.代码生成--------------------------------------------------------------11 七.流程图----------------------------------------------------------------12 八.实现------------------------------------------------------------------13 九.程序运行结果----------------------------------------------------------13 十.总结------------------------------------------------------------------18 十一.附录(源程序)--------------------------------------------------------19简单的编译程序设计一.程序简介与分析本程序由四个部分组成:词法分析子程序,语法分析子程序,语义分析子程序,目标代码生成程序。
《编译原理》设计方案报告
《编译原理》设计方案报告一、项目概述二、课程目标本课程的主要目标是使学生能够掌握编译器的设计与实现原理,理解编译过程中的各个环节,以及掌握常见的编译器构建工具和技术。
具体目标如下:1.理解编译器的基本原理和工作流程;2.掌握常见的编译器构建工具和技术;3.能够独立设计和实现简单的编译器;4.培养学生的系统设计和问题解决能力。
三、课程内容本课程的主要内容包括:1.编译器的概念和基本原理;2.词法分析器和语法分析器的设计与实现;3.语义分析和中间代码生成;4.优化和目标代码生成;5.编译器构建工具和技术。
四、教学方法本课程采用以学生为中心的教学方法,主要包括以下几种教学手段:1.模块化教学:将课程内容分为多个模块,每个模块进行独立的教学和实践;2.理论与实践相结合:通过理论课、实验课等形式,使学生能够将理论知识应用到实际中;3.项目驱动教学:引入编译器设计与实现的实际项目,让学生能够在实践中巩固所学的知识;4.小组合作学习:将学生分成小组,进行协作学习,增强学生的团队合作能力。
五、评价方式为了评价学生对课程内容的掌握程度,本课程采用以下评价方式:1.平时成绩:包括课堂表现、作业和实验成绩等;2.项目成果:针对编译器设计与实现的项目,评价学生的项目成果和实现质量;3.期末考试:以闭卷考试形式对学生的总体掌握情况进行评价。
六、项目进度安排本课程的项目进度安排如下:1.第1-2周:介绍编译器的概念和基本原理;2.第3-6周:词法分析器和语法分析器的设计与实现;3.第7-9周:语义分析和中间代码生成;4.第10-12周:优化和目标代码生成;5.第13-14周:编译器构建工具和技术;6.第15-16周:项目演示和总结。
七、教学资源支持为了支持本课程的教学,我们将提供以下教学资源:1.教材:选用经典的编译原理教材,如《编译原理》(龙书)等;2.课件:编写详细的课件,包括理论知识和实践案例;3.实验指导:编写实验指导书,引导学生进行编译器设计与实现的实践;4. 实验环境:提供编译器构建工具和开发环境,如Lex/Flex、Yacc/Bison等。
编译原理课程设计报告
编译技术课程设计——表达式的小型编译器专业:计算机1201学生姓名:贺茂纯指导教师:年轶完成时间:2015年7月2日一、目的 _________________________________________________ 1二、题目 _________________________________________________ 1三、要求 _________________________________________________ 11.词法分析___________________________________________ 12.语法分析___________________________________________ 13.代码生成___________________________________________ 24.错误处理___________________________________________ 2四、实验环境 _____________________________________________ 2五、系统实现 _____________________________________________ 21.词法分析___________________________________________ 22.语法分析___________________________________________ 43.中间代码___________________________________________ 64.错误处理___________________________________________ 8六、程序运行结果 _________________________________________ 91.准确的语句分析______________________________________ 92.错误的算术表达式___________________________________ 13七、总结 ________________________________________________ 16一、目的<<编译技术>>是理论与实践并重的课程,而其课程设计要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。
编译原理课设实验报告
《编译技术》课程设计报告实验名称编译器设计学号班级本课设的任务是达成一个完好的编译器,办理用户提交的切合所定文法的源程序代码,生成四元式中间代码,从而翻译成等价的X86 平台上汇编语言的目标程序。
编译程序的工作过程区分为以下 5 个过程:词法剖析,语法剖析,语义剖析和中间代码生成,代码优化,目标代码生成。
此中,词法剖析阶段的基本任务是从以字符串表示的源程序中辨别出拥有独立意义的单词符号,并以二元组的形式输出,以作为语法剖析阶段的输入。
语法剖析阶段的基本任务是将词法剖析阶段产生的二元组作为输入,依据语言的语法例则,辨别出各样语法成分,并判断该单词符号序列是不是该语言的一个句子。
语义剖析的任务是第一对每种语法单位进行静态的语义审察,而后剖析其含义,并用另一种语言形式(本课设采纳四元式 ) 来描绘这类语义。
代码优化的任务是对前阶段产生的中间代码进行等价变换或改造,以期获取更为高效即省时间和空间的目标代码。
目标代码生成的任务是将中间代码变换成特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码(本课设生成汇编指令代码)。
在词法剖析阶段,经过 DOS环境手动输入字符串序列(以’#’作为结束标记)作为带剖析的源程序,调用词法扫描子程序将字符串以二元组的形式输出(如有不属于该语言单词符号出现,则进行犯错办理),词法扫描子程序包含了对源程序的预办理(忽视多余空格、回车换行符等空白字符),以及对单词的辨别和分类,以形成(单词种别,单词自己的值)形式的二元组,并将用户自定义变量信息存入程序变量信息表。
在语法剖析阶段,采纳自上而下的递归降落剖析法,从文法的开始符号出发,依据文法例则正向推导出给定句子。
依据递归降落剖析函数编写规则来编写相应的函数,在各个函数的剖析过程中调用词法剖析程序中的扫描程序,发出“取下一个单词符号”的命令,以获得下一个单词符号作语法剖析。
单词符号词语字符法法字符串表示的源程序分分析析器器取一下个单词符号在语义剖析和中间代码生成阶段,采纳语法制导翻译法,使用属性文法为工具来描绘程序设计语言的语义。
编译原理课程设计报告
《编译原理课程设计》报告MiniC编译器设计与开发分组序号:10设计地点:微601电子邮件:413959124@分组成绩:任课教师:李村合2013 年 12 月 21 日目录1课程设计目的 (1)2课程设计内容 (1)3课程设计原理 (1)4系统需求分析 (3)4.1 MiniC编译器总体流程图 (4)4.2 功能需求 (4)4.3 用到的主要关键词: (4)4.4 汇编成可执行文件 (5)4.5 MiniC语言的文法 (6)5系统设计与实现 (8)5.1 C10编译器的主要功能模块 (8)5.2 词法分析子程序 (8)5.3 语法语义分析子程序 (8)6系统测试与运行结果分析 (9)6.1测试程序1 (9)6. 2 测试程序2 (9)6. 3 测试程序3 (9)6.4测试结果1 (10)6. 5 测试结果2 (13)6. 6 测试结果3 (16)7心得体会 (19)1 课程设计目的(1)根据所掌握的编译原理课程的基本知识,编写出一个 MiniC 编译器;(2)增强阅读和编写程序的能力;(3)理解词法分析、语法分析和语义分析在编译程序中的作用;(4)掌握词法分析、语法分析和语义分析程序的实现方法;(5)实现MiniC 编译器的编辑、编译、连接和运行。
2 课程设计内容用 MFC 编写一个可视化的 MiniC 编译器,要求界面美观,使用方便,能够实现自定义 MiniC 语言的编译。
支持的语句和运算:1)数据类型:int,char ,void2)语句:cin,cout,if, while,for,return,printf,赋值3)数学运算:+,-,*,/4)关系运算:= =,>,<,>=,<=,!=5)逻辑运算:&&,||,!6)支持多重调用函数,不支持函数的声明。
7)支持双重循环。
8)注释语句:C类型的/* */ 和C++类型的//9)支持数组传值10)支持复合语句3 课程设计原理MiniC 语言可以看成C 语言的子集,它的编译程序是一个编译执行环境。
编译原理课程设计报告(一个完整的编译器)
编译原理程序设计报告一个简单文法的编译器的设计与实现专业班级:计算机1406班组长姓名:宋世波组长学号: ******** 指导教师:肖桐2016年12月设计分工组长学号及姓名:宋世波20143753 分工:文法及数据结构设计词法分析语法分析(LL1)基于DAG的中间代码优化部分目标代码生成组员1学号及姓名:黄润华20143740 分工:中间代码生成(LR0)部分目标代码生成组员2学号及姓名:孙何奇20143754 分工:符号表组织部分目标代码生成摘要编译器是将便于人编写,阅读,维护的高级计算机语言翻译为计算机能解读、运行的低阶机器语言的程序。
编译是从源代码(通常为高阶语言)到能直接被计算机或虚拟机执行的目标代码(通常为低阶语言或机器语言)的翻译过程。
一.编译器的概述1.编译器的概念编译器是将便于人编写,阅读,维护的高级计算机语言翻译为计算机能解读、运行的低阶机器语言的程序。
编译器将原始程序作为输入,翻译产生使用目标语言的等价程序。
源代码一般为高阶语言如Pascal、C++、Java 等,而目标语言则是汇编语言或目标机器的目标代码,有时也称作机器代码。
2.编译器的种类编译器可以生成用来在与编译器本身所在的计算机和操作系统(平台)相同的环境下运行的目标代码,这种编译器又叫做“本地”编译器。
另外,编译器也可以生成用来在其它平台上运行的目标代码,这种编译器又叫做交叉编译器。
交叉编译器在生成新的硬件平台时非常有用。
“源码到源码编译器”是指用一种高阶语言作为输入,输出也是高阶语言的编译器。
例如: 自动并行化编译器经常采用一种高阶语言作为输入,转换其中的代码,并用并行代码注释对它进行注释(如OpenMP)或者用语言构造进行注释(如FORTRAN的DOALL指令)。
3.本编译器概述编译程序的工作过程一般可以分为五个阶段:词法分析、语法分析、语义分析与中间代码产生、优化、目标代码生成。
每一个阶段在功能上是相对独立的,它一方面从上一个阶段获取分析的结果来进行分析,另一方面由将结果传递给下一个阶段。
编译原理课程设计报告
编译原理课程设计报告编译原理课程设计——简单编译器的设计与实现班级:组长:组员:指导教师:设计时间: 12月摘要....................................... 错误!未定义书签。
1.概述 ..................................... 错误!未定义书签。
2.课程设计任务及要求 ....................... 错误!未定义书签。
2.1 设计任务............................ 错误!未定义书签。
2.2 设计要求............................ 错误!未定义书签。
3.算法及数据结构 ........................... 错误!未定义书签。
3.1算法的总体思想(流程)............... 错误!未定义书签。
3.2词法分析模块......................... 错误!未定义书签。
3.2.1功能........................... 错误!未定义书签。
3.2.2数据结构 ....................... 错误!未定义书签。
3.2.3算法........................... 错误!未定义书签。
3.3语法分析(含语义分析和中间代码生成)模块错误!未定义书签。
3.3.1功能........................... 错误!未定义书签。
3.3.2数据结构 ....................... 错误!未定义书签。
3.3.3算法........................... 错误!未定义书签。
3.4中间代码优化模块..................... 错误!未定义书签。
3.4.1功能........................... 错误!未定义书签。
3.4.2数据结构 ....................... 错误!未定义书签。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
广西大学编译原理课程设计专业:计算机科学与技术姓名:课程:编译原理指导教师:目录一.程序简介与分析---------------------------------------------------------1 二.程序适用围-----------------------------------------------------------1 三.词法分析---------------------------------------------------------------1 四.语法分析---------------------------------------------------------------3 五.语义分析和中间代码生成------------------------------------------------9 六.代码生成--------------------------------------------------------------11 七.流程图----------------------------------------------------------------12 八.实现------------------------------------------------------------------13 九.程序运行结果----------------------------------------------------------13 十.总结------------------------------------------------------------------18 十一.附录(源程序)--------------------------------------------------------19简单的编译程序设计一.程序简介与分析本程序由四个部分组成:词法分析子程序,语法分析子程序,语义分析子程序,目标代码生成程序。
本程序输入一个叫haominjie.txt的c语言源程序,然后对它进行词法,语法,语义分析,并输出汇编代码。
词法分析输入的是c语言源程序,输出的3是具有独立语法意义的单词符号。
语法分析以词法分析产生的编码流为输入,按照SLR(1)分析方法进行语法分析,产生语法树,输出移进和归约的动作,如果源程序不符合文法,则有“语法分析出错”的提示。
语义分析阶段,在语法分析的同时,在归约的时候,给出相应的语义动作,最后输出中间代码四元式和新的符号表,如果有未声明的变量出现,则会提示出出错,并显示出此变量的名称。
代码生成阶段,将语义分析得到的中间代码四元式转化为汇编语言的目标代码并输出。
二.程序适用围本程序的使用围为:整型常量,四则运算(为了简化问题,本程序只考虑加法运算和乘法运算)和布尔表达式以及相应的赋值语句,条件转移语句和循环语句。
三.词法分析根据词法分析的需要,我将源程序中的单词符号分为:保留字,字母(标识符),界符三类,统一用一表表示如下:界符,保留字表程序从源程序文件haominjie.txt中一次读入一个字符,并判断它是不是字母,界符,保留字,空格,换行,结束符号或者非法字符。
流程图如下:词法分析流程图四.语法分析○1.源程序中涉及的文法G[P]定义如下表:○2.上述文法的每个非终结符的FIRST 集和FOLLOW集如下表:FIRST 集 FOLLOW 集P { id } { # }L { id } { ; }D { id } { ; }E {(,id } { },;,+,),#}T {(,id } { },;,+,),*,#}F {(,id } { },;,+,),*,#}B { id } {then,do,and}M { id } { },;}S {id,while,if} { },;}N {id,while,if} { },;}R { { } { # }○3.文法G[P]的项目集部分如下:0. P’→.P 1. P’→P.2. P→.id()L;R3. P→id.()L;R4. P→id(.)L;R5. P→id().L;R6. P→id()L.;R7. P→id()L;.R8. P→id()L;R. 9. L→.L;D10.L→L.;D 11. L→L;.D 12. L→L;D.13.D→.id:int 14. D→id .:int 15. D→id: .int16. D→id:int. 17.E→.E+T 18. E→E.+T19. E→E+.T 20. E→E+T. 21. E→.T22. E→T. 23. T→.T*F 24. T→T.*F25. T→T*.F 26. T→T*F. 27. T→.F28. T→F. 29. F→ (E) 30. F→ (.E)31. F→ (E.) 32. F→ (E). 33. F→.id34. F→id.○4.再由项目集构造文法的DFA活前缀。
为了方便,省去了项目族集的每个状态的项目,直接在状态转换的箭头上标明终结符或非终结符。
对于有规约动作和接受的状态,将其特别标明。
文法G[P]的DFA图如下:*五.语义分析和中间代码生成载语法分析过程中,随着分析的步步进展,根据每个产生式所对应的语义子程序(或语义规则描述的语义动作)进行翻译的办法称作语法制导翻译。
语法制导翻译语法翻译生成的四元式如下:六.代码生成目标代码生成阶段的任务是把中间代码变换成特定机器上的绝对指令代码或可重定位的指令代码或汇编指令代码。
这是编译的最后阶段,它的工作与硬件系统结构和指令含义有关,这个阶段的工作很复杂,涉及到硬件系统功能部件的运用、机器指令的选择、各种数据类型变量的存储空间分配以及寄存器和后缓寄存器的调度等。
本程序生成的目标代码与0x8086微处理器兼容。
下面列举几个简单的四元式与汇编代码的转化列子:○1.(+,A,B,T)→MOV R ,A ;ADD R ,B ;ST R , T○2. ( *, A , B , T ) →MOV R ,A ;MUL R ,B ;ST R , T○3. ( J, _ , _ , L) →JMP L○4. ( J> , A , B , L ) →MOV R , ACMP R , BJB L○5. ( =,A , _ ,T ) →LD R , AST R , T本程序生成的目标代码如下:七.程序流程图编译程序流程图八.实现本程序运行的硬件环境为CPU 2GHZ ,存为4G .软件环境为windows 8.1 系统,Visual C++环境。
九.程序运行结果1.输入源文件路径:2.输出保留字3.输出符号表的容5.输出语法分析的结果(本程序采用自下而上的LR语法分析)6.输出中间代码7.输出目标代码十.总结通过本次实验,对编译程序各阶段有了更深刻更深入的了解,也纠正了自己在某些方面的的错误,丰富了自己关于编译原理方面的知识。
同时也培养了自己热爱思考,勤查资料的习惯。
由于水平本次实验涉及面并不是很全面,我只考虑了c语言的一个子集。
当然本程序的算法在某些地方也还存在一些缺陷。
十一.附录(源程序)本程序输入的c源代码如下:haominjie()a:int;b:int;ccc:int;d:int;{if ccc>b and ccc>a then a=b+a;while ccc>d do a=d;a=(b+ccc)*a+d}本程序的完整源代码如下:#include<cstdio>#include<iostream>#include<cstdlib>#include<fstream>#include<string>#include<cmath>using namespace std;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;//变量名称int addr;//变量地址symb *next;};symb *symb_head,*symb_tail;//语义符号链表////////////////////////////////词法分析有关函数声明void outdaima() ;void scan();//按字符读取源文件void cifa_main();//词法分析主程序int judge(char ch);//判断输入字符的类型void out1(char ch);//写入token.txtvoid out3(char ch,string word);//写入string.txtvoid input1(token *temp);//插入结点到队列tokenvoid input3(str *temp);//插入结点到队列stringvoid output();//输出三个队列的容void outfile();//输出三个队列的容到相应文件中////////////////////////////////语法分析有关函数声明void yufa_main();//语法分析主程序void yufa_initialize();//初始化语法分析数据结构int yufa_SLR1(int a);//语法分析主体部分int ID1(int a);//给输入字符编号,转化成action表列编号string ID10(int i);//给输入字符反编号int ID2(char ch);//给非终结状态编号,转化成go_to表列编号int ID20(char ch);//给非终结状态编号char ID21(int j);//给非终结状态反编号void add(ike *temp);//给ike分析栈链表增加一个结点void del();//给ike分析栈链表删除一个结点/////////////////////////////////语义分析相关函数的声明void yuyi_main(int m);//语义分析主程序void add_L_four(L *temp);//向四元式链中加一个结点void add_L_true(L *temp);//向true链中加一个结点void add_L_false(L *temp);//向false链中加一个结点void add_symb(symb *temp);//向语义符号表链中加一个结点void output_yuyi();//输出中间代码四元式和最后符号表string newop(int m);//把数字变成字符串string id_numtoname(int num);//把编号转换成相应的变量名int lookup(string m);//变量声明检查/////////////////////////////////全局变量的声明FILE *fp;//文件指针int wordcount;//标志符计数int err;//标志词法分析结果正确或错误int nl;//读取行数int yuyi_linshi;//语义临时变量stringE_name,T_name,F_name,M_name,id_name,id1_name,id2_name,errword;//用于归约时名称传递和未声明变量的输出int id_num,id1_num,id2_num,id_left,id_while,id_then,id_do;//用于记录一些特殊的字符位置信息////////////////////////////////主程序开始int main(){cout<<"************************"<<endl;cout<<"* 说明: *"<<endl;cout<<"* 第一部分:词法分析 *"<<endl;cout<<"* 第二部分:语法分析 *"<<endl;cout<<"* 第三部分:语义分析 *"<<endl;cout<<"* 第四部分:目标代码生成 *"<<endl;cout<<"************************"<<endl;cifa_main();//词法yufa_main();//语法output_yuyi();//语义outdaima(); //代码生成cout<<endl;system("pause");return(0);}//////////////////////////////////词法分析子程序void cifa_main(){token_head=new token;token_head->next=NULL;token_tail=new token;token_tail->next=NULL;string_head=new str;string_head->next=NULL;string_tail=new str;string_tail->next=NULL;//初始化三个队列的首尾指针L_four_head=new L;L_four_head->next=NULL;L_four_tail=new L;L_four_tail->k=0;L_four_tail->next=NULL;L_true_head=new L;L_true_head->Ltrue=NULL;L_false_head=new L;L_false_head->Lfalse=NULL;symb_head=new symb;symb_head->next=NULL;symb_tail=new symb;symb_tail->next=NULL;yuyi_linshi=-1;id_num=0;wordcount=0;//初始化字符计数器err=0;//初始化词法分析错误标志nl=1;//初始化读取行数scan();if(err==0){char m;output();cout<<"词法分析正确完成!"<<endl<<endl<<"如果将结果保存到文件中请输入 y ,否则请输入其它字母:";cin>>m;cout<<endl;if(m=='y'){outfile();cout<<"结果成功保存在token.txt和sting.txt两个文件中,请打开查看"<<endl;cout<<endl;}}}void scan(){cout<<endl;system("pause");cout<<endl;char ch;string word;char document[50];int flag=0;cout<<"请输入源文件路径及名称:";cin>>document;cout<<endl;cout<<"************************"<<endl;cout<<"* 第一部分:词法分析 *"<<endl;cout<<"************************"<<endl;if((fp=fopen(document,"rt"))==NULL){err=1;cout<<"无法找到该文件!"<<endl;return;}while(!feof(fp)){word="";ch=fgetc(fp);flag=judge(ch);if(flag==1)out1(ch);else if(flag==3)out3(ch,word);else if(flag==4 || flag==5 ||flag==6)continue;else{cout<<nl<<"行 "<<"错误:非法字符! "<<ch<<endl;err=1;}}fclose(fp);}int judge(char ch){int flag=0;if(ch=='=' || ch=='+' || ch=='*' || ch=='>' || ch==':' || ch==';' || ch=='{' || ch=='}' || ch=='(' || ch==')')flag=1;//界符else if(('a'<=ch && ch<='z') || ('A'<=ch && ch<='Z'))flag=3;//字母else if(ch==' ')flag=4;//空格else if(feof(fp))flag=5;//结束else if(ch=='\n'){flag=6;//换行nl++;}elseflag=0;//非法字符return(flag);}void out1(char ch){int id;switch(ch){case '=' : id=1;break;case '+' : id=2;break;case '*' : id=3;break;case '>' : id=4;break;case ':' : id=5;break;case ';' : id=6;break;case '{' : id=7;break;case '}' : id=8;break;case '(' : id=9;break;case ')' : id=10;break;//界符编码default : id=0;}token *temp;temp=new token;temp->code=id;temp->num=-1;temp->next=NULL;input1(temp);return;}void out3(char ch,string word){token *temp;temp=new token;temp->code=-1;temp->num=-1;temp->next=NULL;str *temp1;temp1=new str;temp1->num=-1;temp1->word="";temp1->next=NULL;int flag=0;word=word+ch;ch=fgetc(fp);flag=judge(ch);if(flag==1 || flag==4 || flag==5 || flag==6){if(word=="and" || word=="if" || word=="then" || word=="while" || word=="do" || word=="int"){if(word=="and")temp->code=31;else if(word=="if")temp->code=32;else if(word=="then")temp->code=33;else if(word=="while")temp->code=35;else if(word=="do")temp->code=36;else if(word=="int")temp->code=37;//关键字编码input1(temp);if(flag==1)out1(ch);else if(flag==4 || flag==5 || flag==6)return;}else if(flag==1){wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);out1(ch);}else if(flag==4 || flag==5 || flag==6){wordcount++;temp->code=25;temp->num=wordcount;input1(temp);temp1->num=wordcount;temp1->word=word;input3(temp1);}return;}else if(flag==2 || flag==3)out3(ch,word);//形成字符串else{err=1;cout<<nl<<"行 "<<"错误:非法字符! "<<ch<<endl;return;}}void input1(token *temp){if(token_head->next == NULL){token_head->next=temp;token_tail->next=temp;}else{token_tail->next->next=temp;token_tail->next=temp;}}void input3(str *temp){if(string_head->next == NULL){string_head->next=temp;string_tail->next=temp;}else{string_tail->next->next=temp;string_tail->next=temp;}}void output(){cout<<"token表容如下:"<<endl;token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){cout<<temp1->code;if(temp1->num == -1){cout<<endl;}else{cout<<" "<<temp1->num<<endl;}temp1=temp1->next;}cout<<"符号表容如下:"<<endl;str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){cout<<temp3->num<<" "<<temp3->word<<endl;temp3=temp3->next;}}void outfile(){ofstream fout1("token.txt");//写文件ofstream fout3("string.txt");token *temp1;temp1=new token;temp1=token_head->next;while(temp1!=NULL){fout1<<temp1->code;if(temp1->num == -1)fout1<<endl;elsefout1<<" "<<temp1->num<<endl;temp1=temp1->next;}str *temp3;temp3=new str;temp3=string_head->next;while(temp3!=NULL){fout3<<temp3->num<<" "<<temp3->word<<endl;temp3=temp3->next;}}/////////////////////////////////////////语法分析子程序void yufa_main(){if(err==0){system("pause");cout<<endl;cout<<"************************"<<endl;cout<<"* 第二部分:语法分析 *"<<endl;cout<<"************************"<<endl;yufa_initialize();//初始化语法分析数据结构token *temp;temp=new token;temp=token_head->next;int p,q;p=0;q=0;cout<<"语法分析过程如下:"<<endl;while(temp!=NULL){int w;w=ID1(temp->code);p=yufa_SLR1(w);if(p==1) break;if(p==0)temp=temp->next;if(temp==NULL) q=1;}//语法分析if(q==1)while(1){p=yufa_SLR1(17);if(p==3) break;}//最后输入$来完成语法分析}}void yufa_initialize(){stack_head=new ike;stack_tail=new ike;stack_head->pre=NULL;stack_head->next=stack_tail;stack_head->num=0;stack_head->word='!';stack_tail->pre=stack_head;stack_tail->next=NULL;//初始化栈分析链表css[0].left='Q';css[0].right="P";css[1].left='P';css[1].right="id()L;R";css[2].left='L';css[2].right="L;D";css[3].left='L';css[3].right="D";css[4].left='D';css[4].right="id:int";css[5].left='E';css[5].right="E+T";css[6].left='E';css[6].right="T";css[7].left='T';css[7].right="T*F";css[8].left='T';css[8].right="F";css[9].left='F';css[9].right="(E)";css[10].left='F';css[10].right="id";css[11].left='B';css[11].right="B and B";css[12].left='B';css[12].right="id>id";css[13].left='M';css[13].right="id=E";css[14].left='S';css[14].right="if B then M"; css[15].left='S';css[15].right="while B do M"; css[16].left='S';css[16].right="M";css[17].left='N';css[17].right="N;S";css[18].left='N';css[18].right="S";css[19].left='R';css[19].right="{N}";int i,j;for(i=0;i<20;i++){char *css_len;css_len=&css[i].right[0];css[i].len=strlen(css_len);}css[1].len=6;css[4].len=3;css[10].len=1;css[11].len=3;css[12].len=3;css[13].len=3;css[14].len=4;css[15].len=4;//初始化产生式for(i=0;i<46;i++){for(j=0;j<18;j++)action[i][j].sr='#';}//初始化action表for(i=0;i<46;i++){for(j=0;j<11;j++)go_to[i][j]=-1;}//初始化go_to表/****************************以下是给action表和go_to表赋初值************************/action[0][0].sr='s';action[0][0].state=2;action[1][17].sr='';//结束action[2][1].sr='s';action[2][1].state=3;action[3][2].sr='s';action[3][2].state=4;action[4][0].sr='s';action[4][0].state=5;action[5][4].sr='s';action[5][4].state=6;action[6][11].sr='s';action[6][11].state=7;action[7][3].sr='r';action[7][3].state=4; action[8][3].sr='r';action[8][3].state=3; action[9][3].sr='s';action[9][3].state=10; action[10][0].sr='s';action[10][0].state=5; action[10][9].sr='s';action[10][9].state=13; action[11][17].sr='r';action[11][17].state=1; action[12][3].sr='r';action[12][3].state=2; action[13][0].sr='s';action[13][0].state=14; action[13][13].sr='s';action[13][13].state=23; action[13][15].sr='s';action[13][15].state=27; action[14][8].sr='s';action[14][8].state=15; action[15][0].sr='s';action[15][0].state=36; action[15][1].sr='s';action[15][1].state=41; action[16][6].sr='s';action[16][6].state=43; action[16][3].sr='r';action[16][3].state=13; action[16][10].sr='r';action[16][10].state=13; action[17][3].sr='s';action[17][3].state=19; action[17][10].sr='s';action[17][10].state=18; action[18][17].sr='r';action[18][17].state=19; action[19][0].sr='s';action[19][0].state=14; action[19][13].sr='s';action[19][13].state=23; action[19][15].sr='s';action[19][15].state=27; action[20][3].sr='r';action[20][3].state=17; action[20][10].sr='r';action[20][10].state=17; action[21][3].sr='r';action[21][3].state=18; action[21][10].sr='r';action[21][10].state=18; action[22][3].sr='r';action[22][3].state=16; action[22][10].sr='r';action[22][10].state=16; action[23][0].sr='s';action[23][0].state=31;action[24][14].sr='s';action[24][14].state=25; action[25][0].sr='s';action[25][0].state=14; action[26][3].sr='r';action[26][3].state=14; action[26][10].sr='r';action[26][10].state=14; action[27][0].sr='s';action[27][0].state=31; action[28][12].sr='s';action[28][12].state=34; action[28][16].sr='s';action[28][16].state=29; action[29][0].sr='s';action[29][0].state=14; action[30][3].sr='r';action[30][3].state=15; action[30][10].sr='r';action[30][10].state=15; action[31][7].sr='s';action[31][7].state=32; action[32][0].sr='s';action[32][0].state=33; action[33][12].sr='r';action[33][12].state=12; action[33][14].sr='r';action[33][14].state=12; action[33][16].sr='r';action[33][16].state=12; action[34][0].sr='s';action[34][0].state=31; action[35][12].sr='r';action[35][12].state=11; action[35][14].sr='r';action[35][14].state=11; action[35][16].sr='r';action[35][16].state=11; action[36][2].sr='r';action[36][2].state=10; action[36][3].sr='r';action[36][3].state=10; action[36][5].sr='r';action[36][5].state=10; action[36][6].sr='r';action[36][6].state=10; action[36][10].sr='r';action[36][10].state=10; action[37][2].sr='r';action[37][2].state=8; action[37][3].sr='r';action[37][3].state=8; action[37][5].sr='r';action[37][5].state=8; action[37][6].sr='r';action[37][6].state=8;action[38][2].sr='r';action[38][2].state=6; action[38][3].sr='r';action[38][3].state=6; action[38][5].sr='s';action[38][5].state=39; action[38][6].sr='r';action[38][6].state=6; action[38][10].sr='r';action[38][10].state=6; action[39][0].sr='s';action[39][0].state=36; action[39][1].sr='s';action[39][1].state=41; action[40][2].sr='r';action[40][2].state=7; action[40][3].sr='r';action[40][3].state=7; action[40][5].sr='r';action[40][5].state=7; action[40][6].sr='r';action[40][6].state=7; action[40][10].sr='r';action[40][10].state=7; action[41][0].sr='s';action[41][0].state=36; action[41][1].sr='s';action[41][1].state=41; action[42][2].sr='s';action[42][2].state=45; action[42][6].sr='s';action[42][6].state=43; action[43][0].sr='s';action[43][0].state=36; action[43][1].sr='s';action[43][1].state=41; action[44][2].sr='r';action[44][2].state=5; action[44][3].sr='r';action[44][3].state=5; action[44][5].sr='s';action[44][5].state=39; action[44][6].sr='r';action[44][6].state=5; action[44][10].sr='r';action[44][10].state=5; action[45][2].sr='r';action[45][2].state=9; action[45][3].sr='r';action[45][3].state=9; action[45][5].sr='r';action[45][5].state=9; action[45][6].sr='r';action[45][6].state=9; action[45][10].sr='r';action[45][10].state=9;go_to[0][0]=1;go_to[4][1]=8;go_to[4][9]=9;go_to[10][1]=12;go_to[1 0][2]=11;go_to[13][7]=22;go_to[13][8]=21;go_to[13][10]=17;go_to[15][3]=16;go_to[15][4]=38;go_to[15][5]=37;go_to[19][7]=20;g o_to[19][8]=20;go_to[23][6]=24;go_to[25][7]=26;go_to[27][6]=28;go_to[29][7]=30;go_to[34][6]=35;go_to[39][5]=40;go_to[41][3]=42;g o_to[41][4]=38;go_to[41][5]=37;go_to[43][4]=44;go_to[43][5]=37;/****************************action表和go_to表赋初值完毕************************/}int ID1(int i)//按action表,给输入字符编号{int j;j=-1;if(i==25) {j=0;id_num++;}//设置变量名称标志if(i==1) {j=8,id_left=id_num;}//设置产生试左边变量名称标志if(i==2) j=6;if(i==3) j=5;if(i==4) j=7;if(i==5) j=4;if(i==6) j=3;if(i==7) j=9;if(i==8) j=10;if(i==9) j=1;if(i==10) j=2;if(i==31) j=12;if(i==32) j=13;if(i==33) {j=14;id_then=L_four_tail->k+1;}//设置if语句中then位置标志if(i==35) {j=15;id_while=L_four_tail->k+1;}//设置while语句中while 位置标志if(i==36) {j=16;id_do=L_four_tail->k+1;}//设置while语句中do位置标志if(i==37) j=11;return(j);}string ID10(int i)//反编号输入字符{string ch;if(i==0) ch="id";if(i==1) ch="(";if(i==2) ch=")";if(i==3) ch=";";if(i==4) ch=":";if(i==5) ch="*";if(i==6) ch="+";if(i==7) ch=">";if(i==8) ch="=";if(i==9) ch="{";if(i==10) ch="}";if(i==11) ch="int";if(i==12) ch="and";if(i==13) ch="if";if(i==14) ch="then";if(i==15) ch="while";if(i==16) ch="do";if(i==17) ch="$";return(ch);}int ID2(char ch)//按go_to表给非终结符编号{int j;j=-1;if(ch=='P') j=0;if(ch=='D') j=1;if(ch=='R') j=2;if(ch=='E') j=3;if(ch=='T') j=4;if(ch=='F') j=5;if(ch=='B') j=6;if(ch=='M') j=7;if(ch=='S') j=8;if(ch=='L') j=9;if(ch=='N') j=10;return(j);}int ID20(char ch)//给非终结符编号{int j;j=-1;if(ch=='P') j=100;if(ch=='D') j=101;if(ch=='R') j=102;if(ch=='E') j=103;if(ch=='T') j=104;if(ch=='F') j=105;if(ch=='B') j=106;if(ch=='M') j=107;if(ch=='S') j=108;if(ch=='L') j=109;if(ch=='N') j=1010;return(j);}char ID21(int j)//反编号非终结符{char ch;if(j==100 || j==0) ch='P';if(j==101 || j==1) ch='D';if(j==102 || j==2) ch='R';if(j==103 || j==3) ch='E';if(j==104 || j==4) ch='T';if(j==105 || j==5) ch='F';if(j==106 || j==6) ch='B';if(j==107 || j==7) ch='M';if(j==108 || j==8) ch='S';if(j==109 || j==9) ch='L';if(j==1010 || j==10) ch='N';return(ch);}void add(ike *temp)//加一个结点{if(stack_head->next==stack_tail) {temp->pre=stack_head;temp->next=stack_tail;stack_head->next=temp;stack_tail->pre=temp;}else{temp->pre=stack_tail->pre;temp->next=stack_tail;stack_tail->pre->next=temp;stack_tail->pre=temp;}}void del()//删除一个结点{stack_tail->pre->pre->next=stack_tail;stack_tail->pre=stack_tail->pre->pre;}int yufa_SLR1(int w){/*cout<<"当前输入符号:"<<ID10(w)<<" ";*/int i,flag=0,state_temp;//flag错误标志,0正常移进,1错误,2归约,3结束char sr_temp;sr_temp=action[stack_tail->pre->num][w].sr;//动作state_temp=action[stack_tail->pre->num][w].state;//状态变化if(sr_temp=='#')//错误动作{flag=1;err=3;cout<<"语法分析出错!"<<endl;}else if(sr_temp=='s')//移进动作{ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=w;temp->num=state_temp;add(temp);cout/*<<"动作(移进):"*/<<sr_temp<<state_temp<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID10(stack_tail->pre->word)*/<<endl;flag=0;}else if(sr_temp=='r')//归约动作{int p=ID2(css[state_temp].left);int q=css[state_temp].len;for(i=0;i<q;i++)del();ike *temp;temp=new ike;temp->next=NULL;temp->pre=NULL;temp->word=ID20(css[state_temp].left);temp->num=go_to[stack_tail->pre->num][p];//查go_to表add(temp);cout/*<<"动作(归约):"*/<<sr_temp<<state_temp<<" "<<css[state_temp].left<<"→"<<css[state_temp].right<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID21(stack_tail->pre->word)*/<<endl;flag=2;yuyi_main(state_temp);//在产生树的同时进行语义分析}else if(sr_temp=='')//结束动作{cout<<"END"/*<<"动作(归约):"<<sr_temp<<state_temp*/<<" "<<css[state_temp].left<<"→"<<css[state_temp].right<<" "/*<<"状态转为:"<<stack_tail->pre->num<<" "<<"栈顶符号:"<<ID21(stack_tail->pre->word)*/<<endl;flag=3;cout<<"语法分析正确完成!"<<endl;}else//其他意外情况{flag=1;err=3;cout<<"语法分析出错!"<<endl;}return(flag);}/////////////////////////////////////////语义分析子程序void yuyi_main(int m){L *temp;int k;k=1;temp=new L;temp->op=" ";temp->op1=" ";temp->op2=" ";temp->result="";temp->next=NULL;temp->Ltrue=NULL;temp->Lfalse=NULL;if(m==4)//变量声明时加入符号表链{symb *Stemp;Stemp=new symb;id_name=id_numtoname(id_num);Stemp->word=id_name;Stemp->next=NULL;add_symb(Stemp);}if(m==5)//归约E→E+T{temp->op="+";temp->op1=E_name;temp->op2=T_name;yuyi_linshi++;//申请临时变量E_name="t"+newop(yuyi_linshi);temp->result=E_name;add_L_four(temp);//加一个四元式结点}if(m==6)//归约E→T。