编译原理课程设计文档格式.docx
《编译原理课程设计文档格式.docx》由会员分享,可在线阅读,更多相关《编译原理课程设计文档格式.docx(33页珍藏版)》请在冰点文库上搜索。
token
语法分析
根据给定语言的文法,描绘程序的语法结构
递归向下
中间结构:
该程序语法树的描绘。
扫描器:
各单词的状态转换图、转换表
Keywords
if–>
keywordsIF
else->
keywordsELSE
int–>
keywordsINT
return->
keywordsRETURN
void->
keywordsVOID
while->
keywordsWHILE
specialsymbols
+-*/……….
---à
special
symbols
分析器:
分析表
用的递归向下的方法,无分析表。
代码设计说明:
程序结构图,文件和函数的设计说明,关键数据结构
总控程序
主要文件:
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<
bufsize))
{
lineno++;
//获取新的一行
if(fgets(lineBuf,BUFLEN-1,source))//存入buffer
if(EchoSource)
%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}
};
/*判断标识符是否是保留字*/
inti;
for(i=0;
i<
MAXRESERVED;
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'
\n'
))
save=FALSE;
elseif(c=='
='
)
state=INASSIGN;
elseif(c=='
/'
state=INLCOMMENT;
//左注释
elseif(c=='
*'
state=INRCOMMENT;
//右注释
!
'
)
state=INNEQ;
elseif(c=='
<
state=INLT;
>
state=INMT;
//已经完成的状态
state=DONE;
switch(c)
caseEOF:
//文件结束
currentToken=ENDFILE;
break;
//
case'
:
//赋值与等号的处理
state=INASSIGN;
+'
currentToken=PLUS;
-'
currentToken=MINUS;
('
currentToken=LPAREN;
)'
currentToken=RPAREN;
{'
currentToken=BIGLBRA;
}'
currentToken=BIGRBRA;
['
currentToken=MIDLBRA;
case'
]'
;
currentToken=SEMI;
'
currentToken=COMMA;
default:
currentToken=ERROR;
caseINLCOMMENT:
if(c==EOF)
save=FALSE;
if(c!
='
ungetNextChar();
currentToken=OVER;
state=DONE;
save=TRUE;
currentToken=LCOMMENT;
caseINRCOMMENT:
if(c!
currentToken=TIMES;
currentToken=RCOMMENT;
caseINNEQ:
//不相等
currentToken=ERROR;
currentToken=NEQ;
caseINLT:
//小于
currentToken=LT;
currentToken=LE;
caseINMT:
//大于
currentToken=MT;
currentToken=ME;
}
caseINASSIGN:
if(c!
currentToken=ASSIGN;
currentToken=EQ;
caseINNUM:
/*if(!
isdigit(c))
currentToken=NUM;
if(!
if(c=='
||c=='
||c=='
||c=='
if((save)&
&
(tokenStringIndex<
=MAXTOKENLEN))
tokenString[tokenStringIndex++]=(char)c;
while((c=getNextChar())&
((c!
)&
(c!
=EOF)))
ungetNextChar();
state=DONE;
currentToken=ERROR;
/*caseINID:
isalpha(c))
currentToken=ID;
*/
caseINID:
caseDONE:
default:
/*shouldneverhappen*/
ScannerBug:
state=%d\n"
state);
//错误报告
if((save)&
tokenString[tokenStringIndex