编译原理课程设计c语言编译器 1.docx
- 文档编号:12518631
- 上传时间:2023-04-19
- 格式:DOCX
- 页数:59
- 大小:39.14KB
编译原理课程设计c语言编译器 1.docx
《编译原理课程设计c语言编译器 1.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计c语言编译器 1.docx(59页珍藏版)》请在冰豆网上搜索。
编译原理课程设计c语言编译器1
编译原理课程设计报告
课题名称:
C-语言编译器设计
提交文档学生姓名:
李杰
提交文档学生学号:
0743041240
同组成员名单:
无
指导教师姓名:
金军
指导教师评阅成绩:
指导教师评阅意见:
.
.
提交报告时间:
2010年6月10日
1.课程设计目标
实验建立C-编译器。
只含有scanner和parser部分。
2.分析与设计
(1)实现方法:
编程语言为C语言。
编程方法:
scanner部分根据DFA图用switch-case结构实现状态转换;parser部分用递归下降分析方法实现。
(2)扫描器:
C-惯用的词法
1、语言的关键字:
elseifintreturnvoidwhile
2、专用符号:
+-*/<<=>>===!
==;,()[]{}/**/
3、其他标记是ID和NUM,通过下列正则表达式定义:
ID=letterletter*NUM=digitdigit*letter=a|..|z|A|..|Zdigit=0|..|9
4、空格由空白、换行符和制表符组成。
空格通常被忽略,除了它必须分开ID、NUM关键字。
5.注释用通常的C语言符号/*...*/围起来。
注释可以放在任何空白出现的位置(即注释不能放在标记内)上,且可以超过一行。
注释不能嵌套
各单词的状态转换图(DFA图如下)词法结构见文件"globals.h"中。
(3)分析器:
分析树结构见文件"globals.h"中。
C-的BNF语法如下:
(4)代码设计说明:
程序结构:
语法分析函数parse通过调用词法分析函数getToken实现语法分析。
文件和函数的设计说明:
文件main.c包含相应头文件,及main函数的实现;文件golbals.h包含符号表和分析数的数据结构及在其它文件中使用的变量;文件util.h和util.c实现与词法分析和语法分析输出相关的函数printToken和printTree,以及分析树节点初始化相关的函数newStmtNode,newExpNode(Expkind)和copyString;文件scan.h和scan.c实现词法分析,主要函数为getToken;文件parse.h和parse.c实现语法分析,函数为与文法规则对应的函数。
关键数据结构
3.程序代码实现
文件main.c代码如下:
//实验建立C-编译器。
只含有scanner和parser部分。
#include"globals.h"
#include"util.h"
#include"scan.h"
#include"parse.h"
//全局变量和标志
intlineno=0;
FILE*source;
FILE*listing;
FILE*code;
intEchoSource=TRUE;
intTraceScan=TRUE;
intTraceParse=TRUE;
intError=FALSE;
intmain(intargc,char*argv[])
{
TreeNode*syntaxTree;
charpgm[120];//代码文件名
if(argc!
=2)
{
fprintf(stderr,"usage:
%sC:
\source.c\n",argv[0]);
return-1;
}
strcpy(pgm,argv[1]);
if(strchr(pgm,'.')==NULL)
{strcat(pgm,".tny");}
source=fopen(pgm,"r");
if(source==NULL)
{
fprintf(stderr,"file%snotfound\n",pgm);
return-1;
}
listing=stdout;
fprintf(listing,"\nC-COMPILATION:
%s\n",pgm);
//while(getToken()!
=ENDFILE);
EchoSource=FALSE;
TraceScan=FALSE;
syntaxTree=parse();
if(TraceParse)
{fprintf(listing,"\nSyntaxtree\n:
");
printTree(syntaxTree);
}
fclose(source);
return0;
}
文件globals.h代码如下:
#ifndef_GLOBALS_H_
#define_GLOBALS_H_
#include
#include
#include
#include
#ifndefFALSE
#defineFALSE0
#endif
#ifndefTRUE
#defineTRUE1
#endif
#defineMAXRESERVED6
typedefenum
{
ENDFILE,ERROR,
IF,ELSE,INT,RETURN,VOID,WHILE,//关键字
ID,NUM,
ASSIGN,EQ,LT,PLUS,MINUS,TIMES,OVER,LPAREN,RPAREN,SEMI,BT,LQ,BQ,
UEQ,DOU,LZGH,RZGH,LDGH,RDGH,//特殊字符
}TokenType;
externFILE*source;
externFILE*listing;
externFILE*code;
externintlineno;
//语法分析树
typedefenum{Stmtk,Expk}Nodekind;
typedefenum{IfK,ElseK,IntK,ReturnK,VoidK,WhileK,AssignK,HanK,HanshutiK}Stmtkind;
typedefenum{Opk,Constk,Idk,Vark}Expkind;
typedefenum{Void,Integer,Boolean}ExpType;
#defineMAXCHILDREN3
typedefstructtreeNode
{
structtreeNode*child[MAXCHILDREN];
structtreeNode*sibling;
intlineno;
Nodekindnodekind;
union{Stmtkindstmt;Expkindexp;}kind;
union{TokenTypeop;
intval;
char*name;}attr;
ExpTypetype;
}TreeNode;
externintEchoSource;
externintTraceScan;
externintTraceParse;
externintError;
#endif
文件util.h代码如下:
#ifndef_UTIL_H_
#define_UTIL_H_
voidprintToken(TokenType,constchar*);
//为分析树
TreeNode*newStmtNode(Stmtkind);
TreeNode*newExpNode(Expkind);
char*copyString(char*);
voidprintTree(TreeNode*);
#endif
文件util.c代码如下:
#include"globals.h"
#include"util.h"
voidprintToken(TokenTypetoken,constchar*tokenString)
{switch(token)
{caseIF:
caseINT:
caseELSE:
caseRETURN:
caseVOID:
caseWHILE:
fprintf(listing,
"reservedword:
%s\n",tokenString);
break;
caseASSIGN:
fprintf(listing,"=\n");break;
caseLT:
fprintf(listing,"<\n");break;
caseEQ:
fprintf(listing,"==\n");break;
caseLPAREN:
fprintf(listing,"(\n");break;
caseRPAREN:
fprintf(listing,")\n");break;
caseSEMI:
fprintf(listing,";\n");break;
casePLUS:
fprintf(listing,"+\n");break;
caseMINUS:
fprintf(listing,"-\n");break;
caseTIMES:
fprintf(listing,"*\n");break;
caseOVER:
fprintf(listing,"/\n");break;
caseBT:
fprintf(listing,">\n");break;
caseLQ:
fprintf(listing,"<=\n");break;
caseBQ:
fprintf(listing,">=\n");break;
caseUEQ:
fprintf(listing,"!
=\n");break;
caseDOU:
fprintf(listing,",\n");break;
caseLZGH:
fprintf(listing,"[\n");break;
caseRZGH:
fprintf(listing,"]\n");break;
caseLDGH:
fprintf(listing,"{\n");break;
caseRDGH:
fprintf(listing,"}\n");break;
caseENDFILE:
fprintf(listing,"EOF\n");break;
caseNUM:
fprintf(listing,
"NUM,val=%s\n",tokenString);
break;
caseID:
fprintf(listing,
"ID,name=%s\n",tokenString);
break;
caseERROR:
fprintf(listing,
"ERROR:
%s\n",tokenString);
break;
default:
/*shouldneverhappen*/
fprintf(listing,"Unknowntoken:
%d\n",token);
}
}
TreeNode*newStmtNode(Stmtkindkind)
{
TreeNode*p=(TreeNode*)malloc(sizeof(TreeNode));
intk;
if(p==NULL)
{fprintf(listing,"outofmemoryerroratline%d\n",lineno);}
else
{
for(k=0;k {p->child[k]=NULL;} p->sibling=NULL; p->nodekind=Stmtk; p->kind.stmt=kind; p->lineno=lineno; } returnp; } TreeNode*newExpNode(Expkindkind) { TreeNode*p=(TreeNode*)malloc(sizeof(TreeNode)); intk; if(p==NULL) {fprintf(listing,"outofmemoryerroratline%d\n",lineno);} else { for(k=0;k {p->child[k]=NULL;} p->sibling=NULL; p->nodekind=Expk; p->kind.exp=kind; p->lineno=lineno; p->type=Void; } returnp; } char*copyString(char*s) { inti; char*p; if(s==NULL) {returnNULL;} i=strlen(s)+1; p=malloc(i); if(p==NULL) {fprintf(listing,"outofmemoryerroratline%d\n",lineno);} else{strcpy(p,s);} returnp; } staticindentno=0; #defineINDENTindentno+=2 #defineUNINDENTindentno-=2 staticvoidprintSpace(void) { intk; for(k=0;k {fprintf(listing,"");} } voidprintTree(TreeNode*t) {inti; INDENT; while(t! =NULL) { printSpace(); if(t->nodekind==Stmtk) { switch(t->kind.stmt) { caseIfK: fprintf(listing,"If\n"); break; caseIntK: fprintf(listing,"Int\n"); break; caseVoidK: fprintf(listing,"Void\n"); break; caseReturnK: fprintf(listing,"Return\n"); break; caseWhileK: fprintf(listing,"While\n"); break; caseAssignK: fprintf(listing,"Assignto: %s\n",t->attr.name); break; caseHanK: fprintf(listing,"Hanshu\n"); break; caseHanshutiK: fprintf(listing,"Hanshuti\n"); break; default: fprintf(listing,"Unknownstmtkind\n"); break; } } elseif(t->nodekind==Expk) {switch(t->kind.exp) { caseOpk: fprintf(listing,"Op: "); printToken(t->attr.op,"\0"); break; caseConstk: fprintf(listing,"Const: %d\n",t->attr.val); break; caseIdk: fprintf(listing,"Id: %s\n",t->attr.name); break; caseVark: fprintf(listing,"Vark: %d\n",t->attr.val); break; default: fprintf(listing,"Unknownexpkind\n"); break; } } else{fprintf(listing,"Unknownexpkind\n");} for(i=0;i {printTree(t->child[i]);} t=t->sibling; } UNINDENT; } 文件scan.h代码如下: #ifndef_SCAN_H_ #define_SCAN_H_ #defineMAXTOKENLEN40 externchartokenString[MAXTOKENLEN+1]; TokenTypegetToken(void); #endif 文件scan.c代码如下: #include"globals.h" #include"util.h" #include"scan.h" //DFA中的状态 typedefenum {START,INID,INNUM,DONE,INASSIGN,INCOMMENT,ZHU,ZZHU}StateType; chartokenString[MAXTOKENLEN+1]; #defineBUFLEN256//代码文件的行数 staticcharlineBuf[BUFLEN];//保存当前行 staticintlinepos=0;//lineBuf中的当前位置 staticintbufsize=0;//buffer串的大小 staticintEOF_Flag=FALSE; //获取字符从lineBuf[BUFLEN]中 staticintgetNextChar(void) { if(! (linepos { lineno++;//新一行 if(fgets(lineBuf,BUFLEN-1,source))//取新一行 {if(EchoSource)fprintf(listing,"%4d: %s",lineno,lineBuf); bufsize=strlen(lineBuf); linepos=0; returnlineBuf[linepos++];//先返回lineBuf[linepos],后linepos加1. } else {EOF_Flag=TRUE; returnEOF; } } elsereturnlineBuf[linepos++]; } //没有取得字符。 staticvoidungetNextChar(void) { if(! EOF_Flag)linepos--; } //关键字的查找表 staticstruct {char*str; TokenTypetok; }reservedWords[MAXRESERVED] ={{"if",IF},{"else",ELSE},{"void",VOID},{"return",RETURN},{"int",INT},{"while",WHILE}}; //关键字的查找 staticTokenTypereserveLookup(char*s) { inti; for(i=0;i { if(! strcmp(s,reservedWords[i].str)) { returnreservedWords[i].tok; } } returnID; } TokenTypegetToken(void) { //token串存放的索引 inttokenStringIndex=0; //存放返回的token TokenTypecurrentToken; //现在的状态 StateTypestate=START; //token串的标记 intsave; intf1=0;//标志取>: 1、<: 2、=: 3和! : 4 intd=getNextChar(); if(d==EOF) {currentToken=ENDFILE; returncurrentToken; } else { ungetNextChar(); } while(state! =DONE) {intc=getNextChar(); save=TRUE; switch(state) { caseSTART: if(isdigit(c)) state=INNUM; elseif(isalpha(c)) state=INID; elseif(c=='>') {f1=1; state=INASSIGN; } elseif(c=='<') {f1=2; state=INASSIGN; } elseif(c=='=') {f1=3; state=INASSIGN; } elseif(c=='! ') {f1=4; state=INASSIGN; } elseif((c=='')||(c=='\t')||(c=='\n')) save=FALSE; elseif(c=='/') {save=FALSE; state=ZHU; } else { state=DONE; switch(c) { caseEOF: save=FALSE; currentToken=ENDFILE; break; case'+': currentToken=PLUS; break; case'-': currentToken=MINUS; break; case'*': currentToken=TIMES; break; case'(': currentToken=LPAREN; break; case')': currentToken=RPAREN; break; case'[': currentToken=LZGH; break; case']': currentToken=RZGH; break; case'{': currentToken=LDGH; break; case'}': currentToken=RDGH; break; case';': currentToken=SEMI; break
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译原理课程设计c语言编译器 编译 原理 课程设计 语言 编译器
![提示](https://static.bdocx.com/images/bang_tan.gif)