1、/ 25(26)272829,30;313233 := main()= =;赋值语句|循环语句=ID=ifelse =do while = +|-*|/=ID|num|(|=|=|!实验目的:1、通过该课程设计,熟练应用编译原理的基本理论和方法2、学会用C/C+高级程序设计语言设计一个编译器的技术3、加深对编译原理的分析理论的理解,培养动手实践能力4、通过设计、编制、调试一个编译器,掌握其设计方法和技术,提高解决实际问题的综合素质实验要求:处理用户提交的符合上述文法的源代码序列,生成四元式中间代码或X86平台上的目标代码。实验步骤:(1)画出识别上述语言单词的状态转换图(2)用C/C+语言编写
2、词法分析程序(应考虑能被语法分析程序调用)(3)预处理,去除注释、多余空格、回车换行符等(3)设计实现语法分析程序(调用上述词法程序分析单词)(4)设计构造属性文法及中间代码序列结构(5)采用语法制导翻译法,完成语义分析程序设计,生成四元式中间代码(6)或将生成的四元式中间代码转换成X86平台上的目标代码(7)设计若干用例,上机测试并通过所设计实现的编译器实验方案设计与实现:总体设计思想经过分析,由于存在冲突项目,上述文法的语法分析无法使用LR(0)分析法,但是上述文法却满足LL(1)文法,故其语法分析可以采用递归下降分析法。故在实验二语法分析的基础上,每当成功识别一个非终结符,根据属性文法的
3、要求采取相应的语义动作,在此过程中可以生成相应的四元式。因此本实验的重点在于四元式结构的定义和生成四元式。详细算法设计数据结构:存储已被识别出单词的结构体四元式定义四元式链表 辅助功能模块:分配临时变量回填 语法分析模块:识别每一个终结符,并同时根据语义需要生成四元式流程框图:识别单词流程图(对应scanner()拼数流程图(对于manageNumberWithoutSign()递归下降分析法中识别非终结符的伪码:Word* element() 如果当前单词是数字或标号 生成一个包含上述单词信息的word; 识别下一个单词; 返回上述word的指针; 否则 如果当前单词是左括号 识别下一个单词
4、; word = expression(); 如果当前单词是右括号 识别下一个单词; 返回word; 否则报错; 否则报错; 返回空指针;Word* item() arg1 = element(); while 当前单词是乘除 arg2 = element(); 获得临时变量 生成新四元式并加入四元式链表中; arg1 = 临时变量; return arg1;Word* expression() arg1 = item (); while 当前单词是加减void condition() arg1 = expression(); 如果当前单词是比较运算符识别下一个单词 arg2 = expres
5、sion();生成新四元式并加入四元式链表中;void assignSentence() 如果当前单词是标号 如果当前单词是浮点数 生成新四元式并加入四元式链表中;void conditionSentence() 如果当前单词是if condition(); 回填true入口; 添加goto判断为假应执行的语句块的四元式; /:=A sentenceBlock(); 如果当前单词是else添加判断为真时避开执行为假时语句块的goto四元式;/:=B 回填A; sentenceBlock(); 回填B; else 回填A; else error();void loopSentence() 如果当
6、前单词是do 识别下一个单词 记录下一个四元式编号; 如果当前单词是while 识别下一个单词 condition(); 生成goto四元式,并把记录的四元式编号填入void sentence() assignSentence(); 否则如果当前单词是if conditionSentence(); 否则如果当前单词是do loopSentence();void sentenceSeries() do sentence(); 如果当前单词是; while(当前单词不是);void sentenceBlock() 如果当前单词是 sentenceSeries(); 如果当前单词是void prog
7、ram() 如果当前单词是main 如果当前单词是( 如果当前单词是) 识别下一个单词; sentenceBlock(); 否则报错;函数相关说明:int isDigit(char c) 判断给定字符是否是数字int isLetter(char c) 判断给定字符是否是字母int isBlank(char c) 判断给定字符是否是空白字符void gotoUnblankChar() 读到第一个非空字符void getLabelOrKey() 读出标识符或者变量名void reserve() 判断标识符是否是关键字int isVar() 判断当前单词是否是符号数或者标识符int isRelati
8、onOperator()判断当前单词是否关系运算符void manageNumberWithoutSign() 拼符号数void scanner() 识别单词void getProgram() 从控制台读入源代码void getProgramFromFile()从文件读入源代码void link(Ptq ptq)/向四元式链表尾添加一个四元式void printQuaternion()/打印四元式Word* getNewTempVariety() /返回一个临时变量Word* getLabel(int i)/返回一个记录回填位置的单词void error()/错误处理Word* element
9、(); /识别因子Word* item(); /识别项Word* expression(); /识别表达式void condition(); /识别条件void assignSentence(); /识别赋值语句void conditionSentence(); /识别条件语句void loopSentence(); /识别循环语句void sentence(); /识别语句void sentenceSeries(); /识别语句序列void sentenceBlock(); /识别语句块void program(); /识别程序输入与输出(包括出错处理)源程序通过文件输入,控制台上显示输出:
10、语法正确与否,如果正确输出四元式,否则输出错误的地方附近的语句和错误的单词;程序运行结果: 语法正确时语法错误时编译器使用说明:在Visual C+ 6.0中运行,输入文件在C盘的program.txt文件下,使用前需要新建该文件并在该文件中输入源程序。实验心得体会:学了这么长时间的编译原理,总是感觉很多有东西虽然知道是什么原理,却并不清楚具体怎么实现。这次实验给了一个机会,本想好好做一做实验,做一个实用的编译器。可惜时间太短了,甚至连目标代码还没有来得及翻译,实验课已经结束。不过这可以理解,上课和实验的时间比较有限,真正的学习是在课程结束后的实践。源程序清单:/ 编译技术课程设计.cpp :
11、 定义控制台应用程序的入口点。/作者:# include stdafx.h# include stdlib.h/*辅助判断小函数*int isDigit(char c)/是否是数字 if(47c & c58) return 1; return 0;int isLetter(char c)/是否是字母 if(6491 | 96 31 & word.type 38)void gotoUnblankChar()/读到第一个非空字符 c = progp+; while(isBlank(c) c = progp+;void getLabelOrKey()/读出标识符或者变量名 while(isLette
12、r(c)|isDigit(c) word.value.stringn+ = c; p-; word.value.stringn+ = 0void reserve()/判断是否是关键字 word.type = 10; for(int k=0;kkeysNunber;k+) if(strcmp(word.value.string,keyk)=0) word.type = k+1; break;void manageNumberWithoutSign() while(isDigit(c) c = progp; if(c = . p+; if(isDigit(progp) c = progp+; wh
13、ile(isDigit(c) word.value.stringn+ = c; c = progp+; p-; word.type = -1; word.value.stringn+ = return; if(progp = e word.value.stringn+ = progp; if(progp = + | progp = - word.value.stringn+ = progp; p+; word.type = 20; word.value.i = atof(word.value.string);/*词法分析*void scanner() n = 0; gotoUnblankCha
14、r(); if(isDigit(c) p-; manageNumberWithoutSign(); else if(isLetter(c) getLabelOrKey(); reserve(); switch(c) case if(progp+ = word.type = 36; word.value.stringn+ = else word.type = 21; p-; word.value.stringn+ = break; if(isDigit(progp) & !isVar() manageNumberWithoutSign(); break; word.type = 22; word.type = 23;* word.type = 24; case/ word.type = 25;( word.type = 26;) word.type = 27;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1