编译原理课程设计C语言编译器.docx

上传人:b****2 文档编号:1345698 上传时间:2023-04-30 格式:DOCX 页数:58 大小:24.74KB
下载 相关 举报
编译原理课程设计C语言编译器.docx_第1页
第1页 / 共58页
编译原理课程设计C语言编译器.docx_第2页
第2页 / 共58页
编译原理课程设计C语言编译器.docx_第3页
第3页 / 共58页
编译原理课程设计C语言编译器.docx_第4页
第4页 / 共58页
编译原理课程设计C语言编译器.docx_第5页
第5页 / 共58页
编译原理课程设计C语言编译器.docx_第6页
第6页 / 共58页
编译原理课程设计C语言编译器.docx_第7页
第7页 / 共58页
编译原理课程设计C语言编译器.docx_第8页
第8页 / 共58页
编译原理课程设计C语言编译器.docx_第9页
第9页 / 共58页
编译原理课程设计C语言编译器.docx_第10页
第10页 / 共58页
编译原理课程设计C语言编译器.docx_第11页
第11页 / 共58页
编译原理课程设计C语言编译器.docx_第12页
第12页 / 共58页
编译原理课程设计C语言编译器.docx_第13页
第13页 / 共58页
编译原理课程设计C语言编译器.docx_第14页
第14页 / 共58页
编译原理课程设计C语言编译器.docx_第15页
第15页 / 共58页
编译原理课程设计C语言编译器.docx_第16页
第16页 / 共58页
编译原理课程设计C语言编译器.docx_第17页
第17页 / 共58页
编译原理课程设计C语言编译器.docx_第18页
第18页 / 共58页
编译原理课程设计C语言编译器.docx_第19页
第19页 / 共58页
编译原理课程设计C语言编译器.docx_第20页
第20页 / 共58页
亲,该文档总共58页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

编译原理课程设计C语言编译器.docx

《编译原理课程设计C语言编译器.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计C语言编译器.docx(58页珍藏版)》请在冰点文库上搜索。

编译原理课程设计C语言编译器.docx

编译原理课程设计C语言编译器

编译原理课程设计报告

课题名称:

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;

;

;

;

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,"notfound\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

{

END,

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;

case',':

currentToken=DOU;

break;

de

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2