CMinus词法分析报告四川大学编译原理.docx
《CMinus词法分析报告四川大学编译原理.docx》由会员分享,可在线阅读,更多相关《CMinus词法分析报告四川大学编译原理.docx(14页珍藏版)》请在冰豆网上搜索。
![CMinus词法分析报告四川大学编译原理.docx](https://file1.bdocx.com/fileroot1/2023-7/12/1fc90c66-e569-4a9a-a98b-dc2c81774594/1fc90c66-e569-4a9a-a98b-dc2c817745941.gif)
CMinus词法分析报告四川大学编译原理
四川大学计算机学院、软件学院
实验报告
学号姓名:
专业:
课程名称
编译原理课程设计
实验课时
4
实验项目
手工构造C-Minus语言的词法分析器
实验时间
实验目的、意义
1.熟悉C-Minus语言的词法特点,构造C-Minus的DFA;
2.设计数据类型、数据结构
3.通过完成词法分析程序,巩固词法分析知识
语言特点
正则表达式
注释:
/*注释*/
关键字:
ifelseintreturnvoidwhile
专用符号:
+-*/<<=>>===!
==;,[](){}
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')||(c=='\n'))
save=FALSE;
elseif(c=='=')
state=INEQ;
elseif(c=='<')
state=INLE;
elseif(c=='>')
state=INGE;
elseif(c=='!
')
state=INNEQ;
elseif(c=='/')
state=LBUFFER;
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=LBRACKET;
break;
case']':
currentToken=RBRACKET;
break;
case'{':
currentToken=LBRACE;
break;
case'}':
currentToken=RBRACE;
break;
case';':
currentToken=SEMI;
break;
case',':
currentToken=COMMA;
break;
default:
currentToken=ERROR;
break;
}
}
break;
}
caseLBUFFER:
{
if(c=='*')
{
tokenStringIndex=0;
save=FALSE;
state=INCOMMENT;
}
elseif(c==EOF)
{
state=DONE;
currentToken=ENDFILE;
}
else
{
currentToken=OVER;
state=DONE;
}
break;
}
caseINCOMMENT:
{
save=FALSE;
if(c=='*')
state=RBUFFER;
elseif(c==EOF)
{
state=DONE;
currentToken=ENDFILE;
}
break;
}
caseRBUFFER:
{
save=FALSE;
if(c=='/')
state=START;
elseif(c=='*')
;
elseif(c==EOF)
{
state=DONE;
currentToken=ENDFILE;
}
else
state=INCOMMENT;
break;
}
caseINNUM:
{
if(!
isdigit(c))
{
ungetNextChar();
save=FALSE;
state=DONE;
currentToken=NUM;
}
break;
}
caseINID:
{
if(!
isalpha(c))
{
ungetNextChar();
save=FALSE;
state=DONE;
currentToken=ID;
}
break;
}
caseINEQ:
{
if(c=='=')
{
state=DONE;
currentToken=EQ;
}
else
{
ungetNextChar();
save=FALSE;
state=DONE;
currentToken=ASSIGN;
}
break;
}
caseINLE:
{
if(c=='=')
{
state=DONE;
currentToken=LE;
}
else
{
ungetNextChar();
save=FALSE;
state=DONE;
currentToken=LT;
}
break;
}
caseINGE:
{
if(c=='=')
{
state=DONE;
currentToken=GE;
}
else
{
ungetNextChar();
save=FALSE;
state=DONE;
currentToken=GT;
}
break;
}
caseINNEQ:
{
if(c=='=')
{
state=DONE;
currentToken=NEQ;
}
else
{
ungetNextChar();
save=FALSE;
state=DONE;
currentToken=ERROR;
}
break;
}
caseDONE:
{
break;
}
default:
{
fprintf(listing,"ScannerBug:
state=%d\n",state);
state=DONE;
currentToken=ERROR;
break;
}
}
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判断。
参考资料:
《编译原理及实践/编译器设计方案》
指导老师
评议
成绩评定:
指导教师签名: