CMinus词法分析四川大学编译原理Word文件下载.docx
《CMinus词法分析四川大学编译原理Word文件下载.docx》由会员分享,可在线阅读,更多相关《CMinus词法分析四川大学编译原理Word文件下载.docx(14页珍藏版)》请在冰豆网上搜索。
专用符号:
+-*/<
<
=>
>
===!
==;
[](){}
ID=letter+
NUM=digit+
letter=[a-z,A-Z]
digit=[0-9]
DFA
数据类型
数据结构设计
//定义数据类型TokenType
typedefenum
{ENDFILE,ERROR,
IF,ELSE,INT,RETURN,VOID,WHILE,
ID,NUM,
ASSIGN,EQ,LT,LE,GT,GE,NEQ,PLUS,MINUS,TIMES,OVER,LPAREN,
RPAREN,LBRACKET,RBRACKET,LBRACE,RBRACE,COMMA,SEMI
}TokenType;
//定义状态类型
typedefenum{START,LBUFFER,RBUFFER,INCOMMENT,INNUM,INID,INEQ,INLE,INGE,INNEQ,DONE}StateType;
//结构定义
staticstruct
{char*str;
TokenTypetok;
}reservedWords[MAXRESERVED]={{"
if"
IF},{"
else"
ELSE},{"
int"
INT},{"
return"
RETURN},{"
void"
VOID},{"
while"
WHILE}};
DFA代码映射方法
双层CASE实现代码映射,外层CASE关注状态变换,内层CASE关注输入字符。
外层CASE一共有12个状态:
START,LBUFFER,RBUFFER,INCOMMENT,INNUM,INID,INEQ,INLE,INGE,INNEQ,DONE,default;
内层CASE判断getNextChar()获取的下一个字符使当前状态转换为其他状态。
关键代码分析
TokenTypegetToken(void)
{
inttokenStringIndex=0;
TokenTypecurrentToken;
StateTypestate=START;
intsave;
//是否保存到tokenString
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=INEQ;
<
'
state=INLE;
>
state=INGE;
!
state=INNEQ;
/'
state=LBUFFER;
else
{
state=DONE;
switch(c)
{
caseEOF:
save=FALSE;
currentToken=ENDFILE;
break;
case'
+'
:
currentToken=PLUS;
-'
currentToken=MINUS;
*'
currentToken=TIMES;
('
currentToken=LPAREN;
)'
currentToken=RPAREN;
['
currentToken=LBRACKET;
]'
currentToken=RBRACKET;
{'
currentToken=LBRACE;
}'
currentToken=RBRACE;
;
currentToken=SEMI;
'
currentToken=COMMA;
default:
currentToken=ERROR;
}
}
break;
}
caseLBUFFER:
if(c=='
{
tokenStringIndex=0;
state=INCOMMENT;
}
elseif(c==EOF)
state=DONE;
currentToken=ENDFILE;
else
currentToken=OVER;
break;
caseINCOMMENT:
save=FALSE;
state=RBUFFER;
caseRBUFFER:
state=START;
elseif(c=='
;
else
caseINNUM:
if(!
isdigit(c))
ungetNextChar();
currentToken=NUM;
caseINID:
isalpha(c))
save=FALSE;
currentToken=ID;
caseINEQ:
currentToken=EQ;
currentToken=ASSIGN;
caseINLE:
currentToken=LE;
currentToken=LT;
caseINGE:
currentToken=GE;
currentToken=GT;
caseINNEQ:
currentToken=NEQ;
currentToken=ERROR;
caseDONE:
default:
fprintf(listing,"
ScannerBug:
state=%d\n"
state);
state=DONE;
currentToken=ERROR;
}
}
if((save)&
&
(tokenStringIndex<
=MAXTOKENLEN))
tokenString[tokenStringIndex++]=(char)c;
if(state==DONE)
tokenString[tokenStringIndex]='
\0'
if(currentToken==ID)
currentToken=reservedLookup(tokenString);
}
if(TraceScan){
fprintf(listing,"
\t%d:
"
lineno);
printToken(currentToken,tokenString);
returncurrentToken;
实验结果截图
总结
词法分析程序的输出和输入:
词法分析程序的功能是读入源程序,输出单词符号。
单词符号是程序设计语言的本语法符号,程序设计语言的单词符号一般分为如下几种:
关键字,标示符,常数,运算符,界符,单词的输出是二元式的形式,需要知道二元式的表示方法,把得到的二元式写入输出文件。
实验注意事项:
1.试验中在设计注释部分的解析时,因为C-Minus的注释符是四个字符组成,设计DFA时设计了两个中间态,用来判断状态转换;
在代码中,如果由中间态转换为INCOMMENT状态,注意字符回退和save置false
2.在判断运算符<
,<
=,>
,>
=,!
=时,第二字符是’=’可成功识别出运算符,第二字符是其他字符时也可能是合法符号,注意字符回退与token判断。
参考资料:
《编译原理及实践/编译器设计方案》
指导老师
评议
成绩评定:
指导教师签名: