1、编译原理课程设计报告课 程 设 计 报 告课程名称 编译程序设计原理 课题名称 带括号的四则混合运算 专 业 班 级 学 号 姓 名 指导教师 2014年 6 月 27日 湖南工程学院课 程 设 计 任 务 书课程名称 编译程序设计原理 课 题 带括号的四则混合运算 专业班级 学生姓名 学 号 指导老师 审 批 任务书下达日期 2014 年 6月 23日任务完成日期 2014 年 6月 27日2011级编译原理课程设计任务书一、 课程设计的性质和目的编译原理课程设计是计算机专业课程,通过课程设计使学生进一步巩固课堂所学知识,全面熟悉、掌握编译程序编写的基本设计方法和技巧,进一步提高分析问题、解
2、决问题及上机操作能力,为将来从事高层次的计算机软件开发工作打下一定的专业基础。二、 设计课题课题一:应用编译原理的方法实现带括号的四则混合运算 给定条件:1、 词法符号定义如下:INTC D+ FLOATC (D+.D+) | (D+.) | ( .D+) FLOATC ( (D+.D+) | (D+.) | ( .D+)| (D+) ) ( E | e ) ( + | | ) D+ OPADD +OPSUB OPMUL *OPDIV /LPAREN (RPAREN )LINE nASSIGN =2、 表达式文法定义如下:01. S E02. E T03. E E OPADD T04. E E
3、 OPSUB T05. T P06. T T OPMUL P07. T T OPDIV P08. P INTC09. P FLOATC10. P LPAREN E RPAREN基本要求:1、 以ASSIGN作为文法结束符号; 2、 应用词法分析技术识别单词;3、 应用SLR(1)分析技术判别表达式的合法性;4、 应用尾动作文法技术计算表达式的类型与值;5、 要求表达式的类型与值严格一致。三、 课程设计报告要求1、 课程设计报告必须按本系规定的格式要求打印成册;2、 课程设计报告每人一份,正文必须包含如下几个方面的内容:1) 基本设计思想;2) 主要数据结构;3) 总结与体会。3、 课程设计报告
4、装订顺序:封面、任务书、目录、正文、源程序清单。四、 选题及考核办法1、 一人一组,学号为奇数者做课题一,学号为偶数者做课题二。2、 成绩考核按个人课题完成情况、设计报告质量及对课程设计的态度等综合评定。五、设计进度安排1、 讲课时间安排: 18周周一上午2、 上机调试时间安排: 18周周三周四上午3、 答辩时间安排: 18周周五上午4、 其余时间:查阅资料,确定方案,设计课题相关程序。目录一 设计内容与设计要求 61.1 课程设计的性质和目的 61.2 设计课题 61.3 进度安排 7二 基本设计思想 82.1 词法分析 82.2 语法分析 9三 主要数据结构 14四 调试运行结果 15五
5、总结与体会 16一 设计内容与设计要求1.1 课程设计的性质和目的编译原理课程设计是计算机专业课程,通过课程设计使学生进一步巩固课堂所学知识,全面熟悉、掌握编译程序编写的基本设计方法和技巧,进一步提高分析问题、解决问题及上机操作能力,为将来从事高层次的计算机软件开发工作打下一定的专业基础。1.2 设计课题课题一:应用编译原理的方法实现带括号的四则混合运算 给定条件:1、 词法符号定义如下:INTC D+ FLOATC (D+.D+) | (D+.) | ( .D+) FLOATC ( (D+.D+) | (D+.) | ( .D+)| (D+) ) ( E | e ) ( + | | ) D+
6、 OPADD +OPSUB OPMUL *OPDIV /LPAREN (RPAREN )LINE nASSIGN =2、 表达式文法定义如下:01. S E02. E T03. E E OPADD T04. E E OPSUB T05. T P06. T T OPMUL P07. T T OPDIV P08. P INTC09. P FLOATC10. P LPAREN E RPAREN基本要求:1、 以ASSIGN作为文法结束符号; 2、 应用词法分析技术识别单词;3、 应用SLR(1)分析技术判别表达式的合法性;4、 应用尾动作文法技术计算表达式的类型与值;5、 要求表达式的类型与值严格一
7、致。1.3 进度安排计算机1181班:第 18 周:星期一 8:0012:00 2:305:30星期二 8:0012:00 2:305:30二 基本设计思想本计算器采用编译原理的方法构建,先用有穷自动机辅助进行词法,把字符串形式的算术表达式的格式标准化,分离出一个个词法单元。然后采用SLR(1)文法分析法进行文法分析,检查表达式的正确性。并在过程中计算出已分析出的部分表达式的值。最终得出表达式的值。2.1 词法分析由于各词法元素都可以用正则表达式来表示,所以做词法分析时采用正则表达式形式化表示各个元素以便于程序实现。四则混合运算各词法元素的正则表达式如下所示:INTC D+ FLOATC D+
8、.D+ | D+. | .D+ FLOATC ( D+.D+ | D+. | .D+ | D+ ) ( E | e ) ( + | | ) D+ OPADD +OPSUB OPMUL *OPDIV /LPAREN (RPAREN )LINE nASSIGN =正则表达式把能够把各词法元素的格式用形式化的方法表示出来,是格式的判断能够用程序来完成,但最终写程序时,用正则表达式直接分析对人来说仍然是不太直接,不方便,所以把正则表达式转化为有限自动机,以是写程序实现词法分析方便。如图1.1为四则混合运算的有限自动机。图 2.1四则混合运算的有限自动机2.2 语法分析 四则混合运算算术表达式符合SLR
9、(1)文法但不符合LR(0)文法,所以语法分析采用SLR(1)语法分析方法。四则混合运算算术表达式的产生式如下: 01. S E02. E T03. E E OPADD T04. E E OPSUB T05. T P06. T T OPMUL P07. T T OPDIV P08. P INTC09. P FLOATC10. P LPAREN E RPAREN通过文法的产生式可以把四则混合运算算术表达式的文法中各个非终极符的FIRST集合和FOLLOW集合一一求出来,以便进行下一步分析。其FIRST集和FOLLOW集如表1.1所示:表2.1四则混合运算算术表达式文法中非终极符的FIRST集和F
10、OLLOW集符号FIRST集合FOLLOW集合SINTC FLOATC LPARENASSIGNEINTC FLOATC LPARENASSIGN OPADD OPSUB RPARENTINTC FLOATC LPARENASSIGN OPADD OPSUB RPAREN OPMUL OPDIVPINTC FLOATC LPARENASSIGN OPADD OPSUB RPAREN OPMUL OPDIV根据文法的产生式和FIRST集、FOLLOW集即可确定文法的规约活前缀DFA (SLR(1)_DFA),如图1.2所示。0S EE TE E OPADD TE E OPSUB TT PT T
11、OPMUL PT T OPDIV PP INTCP FLOATCP LPAREN E RPARENE S1T S2P S3INTC S4FLOATC S5LPAREN S62E TT TOPMUL PT TOPDIV PASSIGN R2OPADD R2OPSUB R2RPAREN R2OPMUL S9OPDIV S103T PASSIGN R5OPADD R5OPSUB R5RPAREN R5OPMUL R5OPDIV R56P LPAREN E RPARENE TE E OPADD TE E OPSUB TT PT T OPMUL PT T OPDIV PP INTCP FLOATCP L
12、PAREN E RPARENE S11T S2P S3INTC S4FLOATC S5LPAREN S67E E OPADD TT PT T OPMUL PT T OPDIV PP INTCP FLOATCP LPAREN E RPARENT S12P S3INTC S4FLOATC S5LPAREN S65P FLOATCASSIGN R9OPADD R9OPSUB R9RPAREN R9OPMUL R9OPDIV R94P INTCASSIGN R8OPADD R8OPSUB R8RPAREN R8OPMUL R8OPDIV R81S EE E OPADD TE E OPSUB TASSI
13、GN R1OPADD S7OPSUB S8图2.2 SLR(1)_DFA9T T OPMUL PP INTCP FLOATCP LPAREN E RPARENP S14INTC S4FLOATC S5LPAREN S610T T OPDIV PP INTCP FLOATCP LPAREN E RPARENP S15INTC S4FLOATC S5LPAREN S68E E OPSUB TT PT T OPMUL PT T OPDIV PP INTCP FLOATCP LPAREN E RPARENT S13P S3INTC S4FLOATC S5LPAREN S614T T OPMUL P A
14、SSIGN R6OPADD R6OPSUB R6RPAREN R6OPMUL R6OPDIV R616P LPAREN E RPARENASSIGN R10OPADD R10OPSUB R10RPAREN R10OPMUL R10OPDIV R1015T T OPDIV P ASSIGN R7OPADD R7OPSUB R7RPAREN R7OPMUL R7OPDIV R713E E OPSUB TT T OPMUL PT T OPDIV PASSIGN R4OPADD R4OPSUB R4RPAREN R4OPMUL S9OPDIV S1012E E OPADD TT T OPMUL PT
15、T OPDIV PASSIGN R3OPADD R3OPSUB R3RPAREN R3OPMUL S9OPDIV S1011P LPAREN E RPARENE E OPADD TE E OPSUB TRPAREN S16OPADD S7OPSUB S8根据SLR(1)_DFA即可用构造文法的相应action表和goto表如表1.3和表1.3所示。表2.2 SLR(1)_actionINTCFLOATCOPADDOPSUBOPMULOPDIVLPARENRPARENASSIGN0S4S5S31S7S8R12R2R2R2R23R5R5R5R5R5R54R8R8R8R8R8R85R9R9R9R9R
16、9R96S4S5S67S4S5S68S4S5S69S4S5S610S4S5S611S7S8S1612R3R3S9S10R3R313R4R4S9S10R4R414R6R6R6R6R6R615R7R7R7R7R7R716R10R10R10R10R10R10表2.3 SLR(1)_gotoETP01231234561123712381339141015111213有了文法的action表和goto表,就可以根据表中所指示的状态转移情况,编写程序并完成相应功能。三 主要数据结构程序的主要数据结构为栈。1 词法分析中用一个栈来保存分析中到达的状态。 static char lexstackBUFSIZE
17、;2 语法分析中一个状态栈用来保存已到达的状态,一个符号栈用来保存已读入的符号或规约产生的符号中还没被规约掉的语法符号。 struct int state; TokenType token; stackBUFSIZE;由于状态栈,与符号栈的出入栈是同步的所以两个栈写在同一个结构中。当读入一个字符或前一个规约产生一个符号,之后若不能直接规约这将该符号入栈到token并跳转到新的状态,原状态入栈state。当一个活前缀被规约,被规约符号出栈,相应状态也出栈。四 调试运行结果 正确的输入结果,得到值35五 总结与体会这次课程设计的过程我遇到了很多的困难,不过有足够的时间给我看书和查资料,从这次课程设
18、计的过程我也看到了自己学习的理论知识的不足。通过这次课程设计我对于编译原理有了更加深入的了解,也懂得了构造一种语言的编译器所要考虑的过程,还有锻炼了我看别人写的大型的程序的能力。进一步加强了我写程序和读程序的能力。 这次实验用是C语言,对此并不熟练,所以在修改的过程中遇到了一些比较难的问题,但在老师与同学们的讨论后才得以解决。同时,也就此机会熟悉和回忆了了C语言,为今后进行C+设计积累了不少的经验。这次实验我做了五个内容,其中在增加一些语句的时候遇到的困难比较大,不过通过查资料和与同学讨论我最后解决了这个问题,也学到了很多的东西,在这次实验中充分理解了团结就是力量。在编译程序实现的过程中反复使
19、用了递归调用的思想,且也使用了模块化处理问题的思想,使用模块化的思想关键是在抽象阶段要抽象出对应的模块,且模块的层次必须是清晰的。在实现此程序中,由于要实现关键字和符号表中字段的搜索,实现中就必须注意快速查找的方法,而在实现的过程中多次用到了二分搜索的方法,这是个比较快的搜索方法。由于此程序的实现相对比较复杂,且不方便调试,改进时可以把此程序的词法分析,语法分析和执行原代码作为单独的测试程序来测试,这样也方便大家来调试。通过本次的课设我知道了一个算法的设计是需要静下心来仔细的研究的,且实现中必须先了解程序的整个流程,也就是说在编程中首先必须看懂那些对应的UML图,只有在图的指导下,编程中才不会
20、盲目,也有一定的方向性。同样在编程中必须注意代码的规范,多写一些对应的注释是很必要的,要时刻想这代码并不是给你自己看的,而是必须要给别人看,因此我觉得代码的规范是相当重要的。附录(源程序)#include #include #include #define BUFSIZE 256static FILE *in;static FILE *out; typedef enum NONE=-3, FEOF, ERROR, INTC,FLOATC,OPADD,OPSUB,OPMUL,OPDIV,LPAREN,RPAREN,LINE,ASSIGN, S,E,T,P/文法的非终极符 11-13 LexTyp
21、e;#define Macro_caseD 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9LexType lex(char *word) static int lexstacktop=-1; static char lextrywordBUFSIZE; static char lexstackBUFSIZE; static LexType lextryflagBUFSIZE; static char lexcurch= ; static LexType lexstateflag= ERROR,
22、INTC, FLOATC, ERROR,ERROR, ERROR, FLOATC,OPADD, OPSUB,OPMUL,OPDIV,LPAREN,RPAREN,LINE,ASSIGN; int state=0; int lexindex=0; doif (lexstacktop=-1) lexcurch=fgetc(in); else lexcurch=lexstacklexstacktop-; while(lexcurch= |lexcurch=t); while (1) switch (state) case 0: switch (lexcurch) case Macro_caseD: s
23、tate=1;break; case .: state=3;break; case +: state=7;break; case -: state=8;break; case *: state=9;break; case /: state=10;break; case (: state=11;break; case ): state=12;break; case n: state=13;break; case =: state=14;break; default: state=-1;break; ; break; case 1: switch (lexcurch) case Macro_cas
24、eD: state=1;break; case .: state=2;break; case E: case e: state=4;break; default: state=-1;break; ; break; case 2: switch (lexcurch) case Macro_caseD: state=2;break; case E: case e: state=4;break; default: state=-1;break; ; break; case 3: switch (lexcurch) case Macro_caseD: state=2;break; default: s
25、tate=-1;break; ; break; case 4: switch (lexcurch) case Macro_caseD: state=6;break; case +: case -: state=5;break; default: state=-1;break; ; break; case 5: switch (lexcurch) case Macro_caseD: state=6;break; default: state=-1;break; ; break; case 6: switch (lexcurch) case Macro_caseD: state=6;break;
26、default: state=-1;break; ; break; default: state=-1;break; if (state=-1) break; lextrywordlexindex+=lexcurch; /*maybe overflow*/ lextryflaglexindex-1=lexstateflagstate; if (lexstacktop=-1) lexcurch=fgetc(in); else lexcurch=lexstacklexstacktop-; if (lexindex=0 & lexcurch=EOF)return FEOF; lextrywordlexindex=lexcurch; lextryflaglexindex=ERROR; while (lexindex0 & lextryflaglexindex=ERROR) lexstack+lexstacktop=lextrywordlexindex-; /*maybe overflow*/ lextrywordlexindex+1=0; strcpy(word,lextryword); return lextryflaglexindex;s
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1