1、编译原理课程设计报告C语言词法与语法分析器的实现doc编译原理课程设计报告C语言词法与语法分析器的实现 编译原理课程设计报告 课题名称 编译原理课程设计 C-语言词法与语法分析器的实现 提交文档学生姓名 提交文档学生学号 同组 成 员 名 单 指导 教 师 姓 名 指导教师评阅成绩 指导教师评阅意见 . . 提交报告时间 年 月 日 C-词法与语法分析器的实现 1.课程设计目标 (1)题目实用性 C-语言拥有一个完整语言的基本属性,通过编写C-语言的词法分析和语法分析,对于理解编译原理的相关理论和知识有很大的作用。 通过编写C-语言词法和语法分析程序,能够对编译原理的相关知识正则表达式、有限自
2、动机、语法分析等有一个比较清晰的了解和掌握。 (2)C-语言的词法说明 语言的关键字 else if int return void while 所有的关键字都是保留字,并且必须是小写。 专用符号 - * / ; , /* */ 其他标记是ID和NUM,通过下列正则表达式定义 ID letter letter* NUM digit digit* letter a|.|z|A|.|Z digit 0|.|9 注ID表示标识符,NUM表示数字,letter表示一个字母,digit表示一个数字。 小写和大写字母是有区别的。 空格由空白、换行符和制表符组成。 空格通常被忽略。 注释用通常的c语言符号/
3、 * . . . * /围起来。 注释可以放在任何空白出现的位置即注释不能放在标记内上,且可以超过一行。 注释不能嵌套。 (3)程序设计目标 能够对一个程序正确的进行词法及语法分析。 2.分析与设计 (1)设计思想 a. 词法分析 词法分析的实现主要利用有穷自动机理论。 有穷自动机可用作描述在输入串中识别模式的过程,因此也能用作构造扫描程序。 通过有穷自动机理论能够容易的设计出词法分析器。 b. 语法分析 语法分析采用递归下降分析。 递归下降法是语法分析中最易懂的一种方法。 它的主要原理是,对每个非终结符按其产生式结构构造相应语法分析子程序,其中终结符产生匹配命令,而非终结符则产生过程调用命令
4、。 因为文法递归相应子程序也递归,所以称这种方法为递归子程序下降法或递归下降法。 其中子程序的结构与产生式结构几乎是一致的。 (2)程序流程图 程序主流程图 词法分析 语法分析 读取程序 读取程序 进行递归下降分析匹配或建立树 对输入的字符进行匹配判断 对应输出各行代码的词法分析结果 输出程序对应的语法树 词法分析子流程图 Start 否 是 Num 是否为dight 是否为num 否 否 是 ID 是否为alpha 是否为id 否 是 是否为 是否为, “; fprintflisting,”Syntax error at line d s“,lineno,message; Error TRU
5、E; /*判断读取的字符*/ static void matchTokenType expected iftokenexpected tokengetToken ; else syntaxError“unexpected token - “; printTokentoken,tokenString; fprintflisting,“ “; /*进行语法分析,构建语法树*/ TreeNode * declaration_listvoid TreeNode * t declaration; TreeNode * p t; while tokenINT | tokenVOID TreeNode *q
6、 declaration; if qNULL if tNULL t p q; else /* now p cannot be NULL either */ p-sibling q; p q; return t; TreeNode * declarationvoid TreeNode * t NULL; switch token case VOID case INT t newStmtNodeDecK; iftoken INT t-type Integer; else t-type Void; matchtoken; switch token case ID t-attr.name copySt
7、ringtokenString; t-kind.stmt VarDK; matchID; switch token case LZKH t-kind.stmt VarDK; t-type IntArray; matchLZKH; matchNUM; matchRZKH; matchSEMI; break; case LPAREN t-kind.stmt FunDK; matchLPAREN; t-child0 params; matchRPAREN; t-child1 compound_stmt; break; default matchSEMI;break; break; defaultsy
8、ntaxError“unexpected token - “; printTokentoken,tokenString; token getToken; break; break; default syntaxError“unexpected token - “; printTokentoken,tokenString; token getToken; break; /* end case */ return t; TreeNode * paramsvoid TreeNode * t NULL; iftoken VOID matchtoken; t newStmtNodeParamList;
9、t-child0 newStmtNodeParamK; t-child0-type Void; else iftoken RPAREN tNULL; else t param_list; return t; TreeNode * param_listvoid TreeNode * t newStmtNodeParamList; int i 1; t-child0 param; whiletoken RPAREN matchDOT; t-childi param; i; return t; TreeNode * paramvoid TreeNode * t NULL; matchINT; t n
10、ewStmtNodeParamK; t-typeInteger; t-attr.namecopyStringtokenString; matchID; iftoken LZKH t-typeIntArray; matchLZKH; matchRZKH; return t; TreeNode * compound_stmtvoid TreeNode * t newStmtNodeComK; matchLDKH; t-child0 local_declarations; t-child1 statement_list; matchRDKH; return t; TreeNode * local_d
11、eclarationsvoid TreeNode * t newStmtNodeLocalDecK; int i0; whiletoken INT | token VOID t-childi declaration; i; return t; TreeNode * statement_listvoid TreeNode * t newStmtNodeStmtList; int i0; whiletoken RDKH t-childi statement; i; return t; TreeNode * statementvoid TreeNode * t ; switch token case
12、 IF t if_stmt; break; case WHILE t while_stmt; break; case ID case SEMI t expression_stmt; break; case RETURN t return_stmt; break; case LDKH tcompound_stmt;break; default syntaxError“unexpected token - “; printTokentoken,tokenString; token getToken; break; /* end case */ return t; TreeNode * expres
13、sion_stmtvoid TreeNode * t newStmtNodeExpstmtK; iftoken SEMI matchSEMI; else t expression; matchSEMI; return t; TreeNode * if_stmtvoid TreeNode * t newStmtNodeIfK; iftNULL matchIF; matchLPAREN; t-child0 expression; matchRPAREN; t-child1 statement; if tokenELSE matchELSE; if tNULL t-child2 newStmtNod
14、eElseK; t-child2-child0 statement; return t; TreeNode * while_stmtvoid TreeNode * t newStmtNodeWhileK; matchWHILE; matchLPAREN; if tNULL t-child0 expression; matchRPAREN; if tNULL t-child1 statement; return t; TreeNode * return_stmtvoid TreeNode * t newStmtNodeRetK; iftoken RETURN matchRETURN; iftok
15、en SEMI matchSEMI; else t-child0 expression; matchSEMI; return t; TreeNode * expressionvoid TreeNode * t simple_exp; return t; TreeNode* varvoid TreeNode* t newExpNodeIdK; if tNULL matchID; iftoken LZKH matchtoken; t-type ArrayUnit; t-child0 expression; matchRZKH; return t; TreeNode * simple_expvoid
16、 TreeNode * t additive_expression; iftNULL if token LT | token LE| token MT | token ME|token EQ|token NEQ TreeNode * p newExpNodeOpK; ifpNULL p-attr.op token; p-child0 t; matchtoken; p-child1 additive_expression; tp; return t; TreeNode* additive_expressionvoid TreeNode * t term; whiletoken PLUS | to
17、ken MINUS TreeNode * p newExpNodeOpK; p-attr.op token; p-child0 t; matchtoken; p-child1 term; t p; return t; TreeNode * termvoid TreeNode * t factor; while tokenTIMES|tokenOVER TreeNode * p newExpNodeOpK; if pNULL p-child0 t; p-attr.op token; matchtoken; p-child1 factor; t p; return t; TreeNode * fa
18、ctorvoid TreeNode * t NULL; switch token case NUM t newExpNodeConstK; if tNULL matchNUM; break; case ID t var; if token ASSIGN TreeNode* p newStmtNodeAssignK; p-attr.name t-attr.name; matchtoken; p-child0 expression; t p; if token LPAREN TreeNode * p newStmtNodeCallK; p-attr.name t-attr.name; tp; ma
19、tchtoken; p-child0 args; matchRPAREN; break; case LPAREN matchLPAREN; t expression; matchRPAREN; break; default syntaxError“unexpected token - “; printTokentoken,tokenString; token getToken; break; return t; TreeNode * argsvoid TreeNode * t newStmtNodeArgList; iftoken RPAREN t-child0 arg_list; retur
20、n t; else return NULL; TreeNode * arg_listvoid TreeNode * t newStmtNodeArgK; int i 1; iftoken RPAREN t-child0 expression; whiletokenRPAREN matchDOT; t-childi expression; i; return t; TreeNode * parsevoid TreeNode * t; token getToken; t declaration_list; if tokenENDFILE syntaxError“Code ends before f
21、ilen“; return t; scan.cpp include “globals.h“ include “util.h“ include “scan.h“ /*对扫描的字符进行匹配判断*/ TokenType getTokenvoid /* index for storing into tokenString */ int tokenStringIndex 0; /* holds current token to be returned */ TokenType currentToken; /* current state - always begins at START */ State
22、Type state START; /* flag to indicate save to tokenString */ int save; while state DONE int c getNextChar; save TRUE; switch state case START if isdigitc state INNUM; else if isalphac state INID; else if c state INEQUAL; else if c state INME; else if c | c t | c n save FALSE; else if c state INNEQ;
23、else if c / ifgetNextChar * ungetNextChar; state DONE; currentToken OVER; break; else save FALSE; state INCOMMENT; else state DONE; switch c case EOF save FALSE; currentToken ENDFILE; break; case currentToken PLUS; break; case - currentToken MINUS; break; case * currentToken TIMES; break; case curre
24、ntToken LPAREN; break; case currentToken RPAREN; break; case ; currentToken SEMI; break; case currentTokenLZKH; break; case currentTokenRZKH; break; case currentTokenLDKH; break; case currentTokenRDKH; break; case , currentTokenDOT; break; default currentToken ERROR; break; break; case INCOMMENT sav
25、e FALSE; if c EOF state DONE; currentToken ERROR; else ifc * ifgetNextChar / state START; else ungetNextChar; break; case INNEQ stateDONE; ifc currentTokenNEQ; else ungetNextChar; saveFALSE; currentTokenERROR; break; case INEQUAL state DONE; if c currentToken EQ; else /* backup in the input */ unget
26、NextChar; currentToken ASSIGN; break; case INNUM if isdigitc /* backup in the input */ ungetNextChar; save FALSE; state DONE; currentToken NUM; break; case INID if isalphac /* backup in the input */ ungetNextChar; save FALSE; state DONE; currentToken ID; break; case INLE state DONE; ifc currentToken
27、 LE; else /* backup in the input */ ungetNextChar; currentToken LT; break; case INME state DONE; ifc currentToken ME; else /* backup in the input */ ungetNextChar; currentToken MT; break; case DONE default /* should never happen */ fprintflisting,“Scanner Bug state dn“,state; state DONE; currentToke
28、n ERROR; break; if save break; case NEQfprintflisting,“n“;break; case ASSIGNfprintflisting,“n“;break; case DOTfprintflisting,“,n“;break; case LZKHfprintflisting,“n“;break; case RZKHfprintflisting,“n“;break; case LDKHfprintflisting,“n“;break; case RDKHfprintflisting,“n“;break; case LZSfprintflisting,
29、“/*n“;break; case RZSfprintflisting,“*/n“;break; case MEfprintflisting,“n“;break; case LEfprintflisting,“childiNULL; t-siblingNULL; t-nodekindStmtK; t-kind.stmtkind; t-linenolineno; return t; /* Function newExpNode creates a new expression node for syntax tree construction*/ TreeNode * newExpNodeExp
30、Kind kind TreeNode * t TreeNode *mallocsizeofTreeNode; int i; iftNULL fprintflisting, “Out of memory error at line dn“,lineno; else fori0;ichildiNULL; t-siblingNULL; t-nodekindExpK; t-kind.expkind; t-linenolineno; t-typeVoid; return t; char * copyStringchar * s int n; char * t; ifsNULL return NULL;
31、nstrlens1; tchar *mallocn; /*其作用是在内存的动态存储区中分配一个长度为n的连续空间.保存tokenstring*/ iftNULL fprintflisting, “Out of memory error at line dn“,lineno; else strcpyt,s; /*该函数是字符串拷贝函数,用来将一个字符串复制到一个字符数组中。 */ /*例如strcpy str1,“china“; 作用是将”China“这个字符串拷贝到str1数组中*/ return t; static int indentno 0; define INDENT indentno2 define UNINDENT indentno-2 static void printSpacesvoid int i; fori0;inodekindStmtK switchtree-kind.stmt case IfK fprintflisting,“Ifn“; break; case WhileK fprintflisting,“Whilen“; break; case ElseK fprintfl
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1