编译原理课程设计.docx
- 文档编号:1620750
- 上传时间:2023-05-01
- 格式:DOCX
- 页数:33
- 大小:19.93KB
编译原理课程设计.docx
《编译原理课程设计.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计.docx(33页珍藏版)》请在冰点文库上搜索。
编译原理课程设计
编译原理课程设计
编译原理课程设计2009-06-2820:
40:
21阅读946评论0 字号:
大中小 订阅
1. 程设计目标
编译器有词法分析部分和语法分析部分,实现了词法分析和语法分析功能
2. 分析与设计
l 实现方法:
编程语言、编程方法
编程语言:
C
编程方法:
词法分析:
总体使用的switchcase结构
语法分析:
使用的递归向下的方法
l 系统总图,各部分的实现原理、方法、中间结果、最后输出
词法分析
实现原理:
根据给定的词法,找出程序中的各个token。
方法:
switchcase结构
中间结果:
无。
最后输出:
token
语法分析
实现原理:
根据给定语言的文法,描绘程序的语法结构
方法:
递归向下
中间结构:
无。
最后输出:
该程序语法树的描绘。
l 扫描器:
各单词的状态转换图、转换表
Keywords
if–>keywordsIF
else->keywordsELSE
int–>keywordsINT
return->keywordsRETURN
void->keywordsVOID
while->keywordsWHILE
specialsymbols
+-*/……….
---àspecial symbols
l 分析器:
分析表
用的递归向下的方法,无分析表。
l 代码设计说明:
程序结构图,文件和函数的设计说明,关键数据结构
总控程序
词法分析
语法分析
主要文件:
Main.c:
总控程序
Scan.c:
完成词法分析
Parse.c:
完成语法分析
Util.c:
辅助程序,完成结果显示。
主要函数:
getToken():
获取一个token
staticintgetNextChar(void):
获取下一个字符
staticvoidungetNextChar(void):
回退一个字符
staticTokenTypereservedLookup(char*s)
在识别出的id序列中,查找关键字。
printToken(currentToken,tokenString):
打印token
parse():
进行语法分析
3. 程序代码实现
按文件列出主要程序代码,添加必要的注释。
main.c
#ifNO_PARSE
while(getToken()!
=ENDFILE);//进行词法分析
#else
syntaxTree=parse();//进行语法分析
if(TraceParse)
{
fprintf(listing,"\nSyntaxtree:
\n");
printTree(syntaxTree);
}
Scan.c
*函数用来从lineBuf中获取下个非空的字符,当lineBuf里的内容都都读取的时候,获取新的一行。
*/
staticintgetNextChar(void)
{
if(!
(linepos { lineno++;//获取新的一行 if(fgets(lineBuf,BUFLEN-1,source))//存入buffer { if(EchoSource) fprintf(listing,"%2d: %s",lineno,lineBuf); bufsize=strlen(lineBuf); linepos=0; returnlineBuf[linepos++]; } else { //文件结束 EOF_flag=TRUE; returnEOF; } } elsereturnlineBuf[linepos++];//当前处理位置 } /*这个函数会在linebuf回退字符*/ staticvoidungetNextChar(void) { if(! EOF_flag) linepos--; } /*关键字*/ staticstruct { charstr[100]; TokenTypetok; }reservedWords[MAXRESERVED] ={ {"if",IF}, {"else",ELSE}, {"int",INT}, {"while",WHILE}, {"void",VOID}, {"return",RETURN} }; /*判断标识符是否是保留字*/ staticTokenTypereservedLookup(char*s) { inti; for(i=0;i if(! strcmp(s,reservedWords[i].str)) returnreservedWords[i].tok; returnID; } /****************************************/ /*theprimaryfunctionofthescanner */ /****************************************/ /*返回源文件中的token*/ TokenTypegetToken(void) { /*token串中的索引 indexforstoringintotokenString*/ inttokenStringIndex=0; /*已经返回的当前token*/ TokenTypecurrentToken; /*当前状态--总是以START开始 currentstate-alwaysbeginsatSTART*/ StateTypestate=START; /* flagtoindicatesavetotokenString 将token存入tokenString的标示 */ intsave; //未完成的状态 while(state! =DONE) { intc=getNextChar(); save=TRUE; switch(state) { caseSTART: if(isdigit(c)) state=INNUM; elseif(isalpha(c)) state=INID; elseif((c=='')||(c=='\t')||(c=='\n')) save=FALSE; elseif(c=='=') state=INASSIGN; elseif(c=='/') state=INLCOMMENT;//左注释 elseif(c=='*') state=INRCOMMENT;//右注释 elseif(c=='! ') state=INNEQ; elseif(c=='<') state=INLT; elseif(c=='>') state=INMT; //已经完成的状态 else { state=DONE; switch(c) { caseEOF: //文件结束 save=FALSE; currentToken=ENDFILE; break; // case'=': //赋值与等号的处理 // state=INASSIGN; // break; case'+': currentToken=PLUS; break; case'-': currentToken=MINUS; break; case'(': currentToken=LPAREN; break; case')': currentToken=RPAREN; break; case'{': currentToken=BIGLBRA; break; case'}': currentToken=BIGRBRA; break; case'[': currentToken=MIDLBRA; break; case']': currentToken=MIDLBRA; break; case';': currentToken=SEMI; break; case',': currentToken=COMMA; break; default: currentToken=ERROR; break; } } break; caseINLCOMMENT: if(c==EOF) { save=FALSE; state=DONE; currentToken=ENDFILE; } if(c! ='*') { save=FALSE; ungetNextChar(); currentToken=OVER; state=DONE; } else { save=TRUE; currentToken=LCOMMENT; state=DONE; } break; caseINRCOMMENT: if(c! ='/') { save=FALSE; ungetNextChar(); currentToken=TIMES; state=DONE; } else { save=TRUE; currentToken=RCOMMENT; state=DONE; } break; caseINNEQ: //不相等 if(c! ='=') { save=FALSE; ungetNextChar(); currentToken=ERROR; state=DONE; } else { save=TRUE; currentToken=NEQ; state=DONE; } break; caseINLT: //小于 if(c! ='=') { save=FALSE; ungetNextChar(); currentToken=LT; state=DONE; } else { save=TRUE; currentToken=LE; state=DONE; } break; caseINMT: //大于 if(c! ='=') { save=FALSE; ungetNextChar(); currentToken=MT; state=DONE; } else { save=TRUE; currentToken=ME; state=DONE; } break; caseINASSIGN: //赋值与等号的处理 if(c! ='=') { save=FALSE; ungetNextChar(); currentToken=ASSIGN; state=DONE; } else { save=TRUE; currentToken=EQ; state=DONE; } break; caseINNUM: /*if(! isdigit(c)) { save=FALSE; ungetNextChar(); state=DONE; currentToken=NUM; } */ if(! isdigit(c)) { if(c==''||c=='\t'||c=='\n'||c=='='||c=='! ') { save=FALSE; ungetNextChar(); state=DONE; currentToken=NUM; } else { if((save)&&(tokenStringIndex<=MAXTOKENLEN)) tokenString[tokenStringIndex++]=(char)c; while((c=getNextChar())&&((c! ='')&&(c! ='\t')&&(c! ='\n')&&(c! =EOF))) { save=TRUE; if((save)&&(tokenStringIndex<=MAXTOKENLEN)) tokenString[tokenStringIndex++]=(char)c; } save=FALSE; ungetNextChar(); state=DONE; currentToken=ERROR; } } break; /*caseINID: if(! isalpha(c)) { save=FALSE; ungetNextChar(); state=DONE; currentToken=ID; } break; */ caseINID: if(! isalpha(c)) { if(c==''||c=='\t'||c=='\n'||c=='='||c=='! ') { save=FALSE; ungetNextChar(); state=DONE; currentToken=ID; } else { if((save)&&(tokenStringIndex<=MAXTOKENLEN)) tokenString[tokenStringIndex++]=(char)c; while((c=getNextChar())&&((c! ='')&&(c! ='\t')&&(c! ='\n')&&(c! ='=')&&(c! ='! ')&&(c! =EOF))) { save=TRUE; if((save)&&(tokenStringIndex<=MAXTOKENLEN)) tokenString[tokenStringIndex++]=(char)c; } save=FALSE; ungetNextChar(); state=DONE; currentToken=ERROR; } } break; caseDONE: default: /*shouldneverhappen*/ fprintf(listing,"ScannerBug: state=%d\n",state);//错误报告 state=DONE; currentToken=ERROR; break; } if((save)&&(tokenStringIndex<=MAXTOKENLEN)) tokenString[tokenStringIndex
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 课程设计