编译原理实验经典指导
- 格式:pdf
- 大小:346.86 KB
- 文档页数:13
编译原理实验吴海涛2012-11-16目录相关问题说明 (1)实验题 (2)实验1 词法分析(2课时) (3)实验2 语法分析(2课时) (5)实验3 语义分析(2课时) (7)实验4 代码生成(2课时) (9)参考书目 (11)相关问题说明本课程共有4个实验,本课程中所实现的程序为普通C/C++程序或Java程序,在Windows环境下,属于控制台应用程序。
可以考虑为程序添加图形界面。
提交实验成果:1. 实验成果包括:⏹源程序。
用学号加姓名方式命名项目或源程序所在目录,例如,学号:100511xxx,姓名:某某,目录名就是:100511xxx某某。
只要源程序,不要编译后文件。
⏹实验报告。
2. 实验报告由班干部收齐后在实验后下一次上课时交给我(如果最后一次实验是最后一次课,则另做安排),源程序发我邮箱。
实验成果评价标准:1. 及时提交实验成果,过期再交,不计成绩。
2. 实验成果和他人雷同者,不计成绩。
3. 实验报告采用手写方式,书写格式按照数学与计算机学院要求执行,不按要求办事的,不计成绩。
4. 实验成果不完整的,即缺源程序或实验报告者,不计成绩。
5. 实验报告内容充实,能够真实反映实验情况的,酌情加分。
6. 实验报告字迹工整的,酌情加分。
7. 存在其他加分的可能性。
实验题编译整数四则运算表达式,将整数四则运算表达式翻译为汇编语言代码。
整数四则运算文法:<expr> ::= <expr> + <term> | <expr> - <term> | <term><term> ::= <term> * <factor> | <term> / <factor> | <factor><factor> ::= (<expr>) | num消除左递归得<expr> ::= <term> <expr-rest><expr-rest> ::= + <term> <expr-rest> | - <term> <expr-rest> |ε<term> ::= <factor> <term-rest><term-rest> ::= * <factor> <term-rest> | / <factor> <term-rest> | ε<factor> ::= (<expr>) | num其中<expr>、<expr-rest>、<term>、<term-rest>和<factor>为非终结符,+、-、*、/、(、)、num为终结符。
词法:1.运算符:+ - * /2.界符:( )3.num是非负整数。
4.空白包括空格、换行符和水平制表符。
用来分开运算符、界符和num。
也可以不包括换行符,这时换行符就成为表达式的终结标志。
实验1 词法分析(2课时)实验目的:了解词法分析器的功能和输出形式,掌握词法分析器设计原理和方法。
实验内容:设计并实现整数四则运算表达式的词法分析程序。
实验要求:编写程序,上机调试和测试,纪录调试和测试情况,结合程序进行分析。
实验环境:Visual C++ 6.0或以上版本,Windows 2000或以上版本,汇编工具(在Software子目录下)。
实现要点与提示:需要实现的词法分析程序的功能是,接受一个表达式,输出该表达式中的各类单词符号。
测试词法分析程序时,可以按照一定格式输出各类单词符号。
单词符号的种类和所属类型可定义如下typedef enum Symbol { ERR = -1, END, NUM, PLUS, MINUS, TIMES, SLASH, LPAREN, RPAREN } Symbol;对运算符和界符只需处理种类编码即可,而对num需要处理其对应的具体属性信息。
ERR表示词法分析错,END表示表达式分析结束。
例如1+2*(3+4)所对应的单词符号序列为NUM: 1+NUM: 2*(NUM: 3+NUM: 4)词法分析函数的原型如下Symbol gettoken();实现的具体方法可参考文献[1]中44-46页。
这里不涉及Reserve、InsertId和InsertConst。
在实现过程中可能会用到isdigit、isspace、getchar、ungetc、atoi等函数,使用时注意包含相关头文件。
状态转换图如下实现的具体方法也可以参考文献[3]中的47-53页和79-83页。
如果使用Lex或JFlex工具实现,则可参考文献[3]中86-90页、文献[4][5]以及Lex或JFlex工具的手册。
如果使用JLex或JFlex工具实现,则可参考JLex或JFlex的手册。
实验2 语法分析(2课时)实验目的:理解自上而下分析法的基本思想,理解递归下降分析法的基本思路,掌握构造递归下降子程序的方法。
实验内容:运用递归下降子程序法,实现整数四则运算表达式的语法分析程序。
实验要求:编写程序,上机调试和测试,纪录调试和测试情况,结合程序进行分析。
实验环境:Visual C++ 6.0或以上版本,Windows 2000或以上版本,汇编工具(在Software子目录下)。
实现要点与提示:需要实现的语法分析程序的功能是,接受一个表达式,分析该表达式,并根据输入正确与否给出相应信息。
测试时,如果输入的表达式分析正确,则输出表示分析正确的信息;否则,输出表示分析错误的信息。
下面的叙述主要参考了文献[1]。
分析程序由一组递归过程组成,文法中每个非终结符对应一个过程。
在分析过程中,语法分析程序需要调用实验1所实现的词法分析程序。
几个全局过程和变量:ADVANCE,把输入串指示器IP指向下一个输入符号,即读入一个单字符号。
SYM,IP当前所指的输入符号。
ERROR,出错处理子程序。
每个非终结符有对应的子程序的定义,在分析过程中,当需要从某个非终结符出发进行展开(推导)时,就调用这个非终结符对应的子程序。
例:给定文法G(E):E→TE'E'→+TE' |εT→FT'T'→*FT' |εF→(E) | i对应的递归子程序为PROCEDURE E; BEGINT;E'END; PROCEDURE E'; IF SYM=‘+’ THEN BEGINADVANCE;T;E'END; PROCEDURE T; BEGINF;T'END;PROCEDURE T';IF SYM=‘*’ THENBEGINADVANCE;F;T'END;PROCEDURE F;IF SYM=‘i’ THEN ADVANCE ELSE IF SYM=‘(’ THEN BEGINADVANCE;E;IF SYM=‘)’ THEN ADVANCEELSE ERROR END ELSE ERROR;主程序为:PROGRAM PARSER; BEGINADVANCE;E;IF SYM <>’#’ THENERROREND.或者对应的递归子程序为:PROCEDURE E;BEGINT;E'END;PROCEDURE T;BEGINF;T'END;PROCEDURE E';IF SYM=‘+’ THENBEGINADVANCE;T;E'END ELSE IF SYM<>‘#’ AND SYM<>’)’ THEN ERROR; PROCEDURE T'; IF SYM=‘*’ THENBEGINADVANCE;F;END ELSE IF SYM<>‘#’ ANDSYM<>’)’AND SYM<>’+’ THEN ERROR; PROCEDURE F;IF SYM=‘i’ THEN ADVANCEELSE IF SYM=‘(’ THENBEGINADVANCE;E;IF SYM=‘)’ THEN ADVANCEELSE ERROREND ELSE ERROR主程序为:PROGRAM PARSER;BEGINADVANCE;EEND;具体实现语法分析程序时,ADVANCE的功能由实验1中的gettoken实现。
程序中可设置一个全局变量nexttoken,与SYM对应,保存调用gettoken时的返回结果。
ERROR的一种简单实现是输出错误提示,然后调用exit,使程序立即终止执行。
实现整数四则运算表达式的语法分析程序时,可在上面例子的基础上修改扩充。
实现的具体方法也可以参考文献[3]中的43-47页和128-129页。
如果使用Yacc或Bison工具实现,则可参考文献[3]中170-177页以及文献[4][5]。
如果使用Java CUP工具实现,则可参考Java CUP的手册。
实验3 语义分析(2课时)实验目的:理解属性文法,理解语法制导翻译的基本思想和方法。
实验内容:设计并实现实现整数四则运算的递归下降翻译器。
实验要求:编写程序,上机调试和测试,纪录调试和测试情况,结合程序进行分析。
实验环境:Visual C++ 6.0或以上版本,Windows 2000或以上版本,汇编工具(在Software子目录下)。
实现要点与提示:需要实现的语义分析程序的功能是,接受一个表达式,分析该表达式,并在分析的过程中建立该表达式的抽象语法树。
由于四则运算表达式的抽象语法树可基本上看作是二叉树,因此中序遍历序列应该和输入的表达式一样——除了没有括号之外。
可输出中序遍历序列检测程序功能是否正确。
如果每个分支节点用一个临时变量标记,则对四则运算表达式的抽象语法树进行后序遍历,可以得到输入表达式所对应的四元式序列(实验4要用到这样的四元式序列)。
例如输入1+2*(3+4),对应的抽象语法树的中序遍历序列、四元式序列分别为1 +2 *3 + 4和+ 3 4 T1* 2 T1 T2+ 1 T2 T3抽象语法树的一种类型定义为typedef int V alType;typedef struct ASTNode {Symbol sym;V alType val;struct ASTNode * arg1, *arg2;} ASTNode, *AST;创建节点的操作为ASTNode *mknode(Symbol op, ASTNode *arg1, ASTNode *arg2);返回新创建的一个运算节点,标号是op,域arg1和arg2分别指向一棵子树。