当前位置:文档之家› 编译原理课程设计

编译原理课程设计

编译原理课程设计实验名称:C-语言词法分析器的手工构造C-语言词法分析器的lex生成C-语言语法分析器的手工构造学生姓名:刘恺丽学生学号: 0943041336指导教师姓名:于中华实验一:C-语言词法分析器的手工构造一、实验目的及意义1.理解C-语言的词法特点,并能构造各种token的正则表达式;2.掌握将正则表达式转换为DFA的方法;3.学会设计C-语言手动生成词法分析器的数据类型和数据结构。

二、实验环境1.操作系统:Window XP/Windows 7;2.开发环境:Microsoft Visual C++ 6.0。

三、算法分析与设计1.C-语言的词法规则(1)关键字else if int return void while(2)特殊符号+ - * / <<= >>= == != = ; , ( ) [ ] { } /* */(3)其它token(区分大小写)ID = letter letter*NUM = digit digit*letter = a|…|z|A|...|ZDigit = 0|…|9(4)空白符号空白 \n \t(5)注释由标记符号/*…*/标记起来的部分。

2.C-语言的词法正则表达式digit [0-9]number {digit}+letter [a-zA-Z]identifier {letter}+newline \nwhitespace [" "\t]+3.C-语言的DFA4.重要数据类型设计(1)token类型用枚举量分为以下几个typedefenum{ENDFILE,ERROR,ELSE,IF,INT,RETURN,VOID,WHILE,ID,NUM,PLUS,MINUS,TIMES,OVER,LT,LTE,RT,RTE,EQ,NE,ASSIGN,SEMI,COMMA,LPAR EN,RPAREN,LZ,RZ,LD,RD,LC,RC}TokenType;(2)DFA9个状态typedefenum{START,INNE,INEQ,INLT,INRT,INID,INNUM,INOVER,INCOMMENT1,INCOM MENT2,DONE}StateType;四、代码实现1.查找保留字函数TokenTypeS FindResvd (char * s)须注意:对Keyword先将keyWord归为ID类。

getToken时再匹配。

保留字数据结构如下:staticstruct{char* str;TokenType tok;}reservedWords[MAXRESERVED]={{"else",ELSE},{"if",IF},{"int",INT},{"return",RETURN},{"void",VOID},{"while",WHILE}};static TokenType reservedLookup (char * s){int i;for (i=0;i<MAXRESERVED;i++)if (!strcmp(s,reservedWords[i].str))return reservedWords[i].tok;return ID;2.getToken代码设计说明:1)以状态表为驱动,根据当前的状态以及当前字符来决定下一个状态。

2)嵌套case:通过一个状态标记来标记当前DFA所处的状态,通过case分支语句来执行每一个转移的情况,直观易懂,但是随着DFA状态数量的增多,循环嵌套的程序代码就会变得很冗长。

3)实现DFA的核心代码及分析:扫描程序的主函数为getToken,用的是嵌套case的方法,通过自定义一个状态枚举类型来标记当前所处的DFA状态,并用字符数组tokenString来保存已经扫描过的字符,每次调用getToken函数的时候,当前状态都会被初始化为START状态,用while循环当当前状态不为DONE状态,就从输入流获取一个字符,并根据上面给出的DFA判断如何进行状态转移;当当前状态为接收状态时,tokenString里面就是一个完整的token,于是将tokenString的内容打印到listing文件并返回tokenString里面的内容。

getToken函数调用getNextChar函数获取源文件中下一个字符,如果某些状态需要回溯一个字符,则调用ungetNextChar函数将已经获取的字符释放出来等待下一个状态中重新获取。

GetToken函数中识别token关键代码:TokenType getToken(void){int tokenStringIndex = 0;TokenType currentToken;StateType state = START;int save;while (state !=DONE){int c = getNextChar();save = true;switch (state){case START:if(isdigit(c)){state = INNUM;}elseif (isalpha(c))state = INID;elseif (c == '!')state = INNE;elseif (c == '=')state = INEQ;elseif (c == '>')state = INRT;elseif (c == '<')state = INLT;elseif (c == '/')state = INOVER;elseif ((c ==' ')||(c == '\t')||(c =='\n')){save=false;//state = START;}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';':currentToken = SEMI;break;case',':currentToken = COMMA;break;case'(':currentToken = LPAREN;break;case')':currentToken = RPAREN;break;case'[':currentToken = LZ;break;case']':currentToken = RZ;break;case'{':currentToken = LD;break;case'}':currentToken = RD;break;default:currentToken = ERROR;break;}}break;case INNE:state = DONE;if(c=='=')currentToken=NE;else{ungetNextChar();save=false;currentToken=ERROR;}break;case INEQ:state = DONE;if(c=='=')currentToken=EQ;else{ungetNextChar();currentToken=ASSIGN;}break;case INRT:state = DONE;if(c=='=')currentToken=RTE;else{ungetNextChar();currentToken=RT;}break;case INLT:state = DONE;if(c=='=')currentToken=LTE;else{ungetNextChar();currentToken=LT;}break;case INNUM:if(!isdigit(c)){ungetNextChar();save = false;state = DONE;}currentToken =NUM;break;case INID:if(!isalpha(c)){ungetNextChar();save = false;state = DONE;}currentToken =ID;break;case INOVER:if(c == '*'){save=false;state = INCOMMENT1;tokenStringIndex=0;// currentToken =LC;}else{ungetNextChar();save = false;state = DONE;currentToken =OVER;}break;case INCOMMENT1:if(c == '*'){save=false;state = INCOMMENT2;}elseif(c==EOF){save=false;state=DONE;currentToken=ERROR;}else{save = false;state = INCOMMENT1;//currentToken =ENDFILE;}break;case INCOMMENT2:save = false;if(c == '/'){state = START;}elseif(c==EOF){state=DONE;currentToken=ERROR;}elseif(c == '*'){state =INCOMMENT2;}else{state = INCOMMENT1;}break;case DONE:default:fprintf(listing,"Scanner Bug: state= %d\n",state);state = DONE;currentToken = ERROR;break;}五、测试结果测试小程序:输出结果:程序运行结果分析:如上图所示:通过观察分析,发现程序已经能够成功识别关键字,如第一行的“1”,能成功识别出NUM,如第六行的“int”,成功识别出reserved word等。

相关主题