📄 scanner.cpp
字号:
// scanner.cpp: implementation of the scanner class.
//
//////////////////////////////////////////////////////////////////////
#include "scanner.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
scanner::scanner()
{
bufpos=0; //缓冲区中当前读取字符的位置
linenum=0; //行号
trbufsize=0;
fo=fopen(FILENAME1, "w");
fp=fopen(FILENAME, "r");
// if(fp==NULL)
// { cout<<FILENAME<<"没有被创建";
// return;
// }
// else if(feof(fp))
// { cout<<FILENAME<<"文件为空";
// return;
// }
rs[0].str="if";rs[0].tok=IF;
rs[1].str="int";rs[1].tok=INT;
rs[2].str="else";rs[2].tok=ELSE;
rs[3].str="while";rs[3].tok=WHILE;
rs[4].str="rerurn";rs[4].tok=RETURN;
rs[5].str="void";rs[5].tok=VOID;
rs[6].str="class";rs[6].tok=CLASS;
rs[7].str="public";rs[7].tok=PUBLIC;
rs[8].str="private";rs[8].tok=PRIVATE;
rs[9].str="protected";rs[9].tok=PROTECTED;
rs[10].str="this";rs[10].tok=THIS;
rs[11].str="new";rs[11].tok=NEW;
rs[12].str="delete";rs[12].tok=DELETE;
rs[13].str="virtual";rs[13].tok=VIRTUAL;
rs[14].str="try";rs[14].tok=TRY;
rs[15].str="catch";rs[15].tok=CATCH;
rs[16].str="throw";rs[16].tok=THROW;
rs[17].str="exp";rs[17].tok=EXP;
}
scanner::~scanner()
{
}
char scanner::readachar()
{
if(!(bufpos<trbufsize))
{ linenum=linenum+1;
if(fgets(buffer,BUFLENTH,fp)!=NULL)
{
bufpos=0;
trbufsize=strlen(buffer);
return buffer[bufpos++];
}
else return EOF;
}
else return buffer[bufpos++];
}
scanner::backachar()
{
bufpos=bufpos-1;
}
TokenType scanner::LookupReserved(char *string)
{
for(int i=0;i<18;i++)
{ if(!strcmp(string,rs[i].str))
return rs[i].tok;
}
return ID;
}
scanner::foutput(FILE * f , TokenType tokentype, char *tokenstring)
{
switch (tokentype)
{ case IF:
case INT:
case ELSE:
case WHILE:
case RETURN:
case VOID:
case CLASS:
case PUBLIC:
case PRIVATE:
case PROTECTED:
case THIS:
case NEW:
case DELETE:
case VIRTUAL:
case TRY:
case CATCH:
case THROW:
case EXP:
fprintf(f,"reserved word: %s\n",tokenstring); break;
case PLUS: fprintf(f,"+\n"); break;
case MINUS: fprintf(f,"-\n"); break;
case STAR: fprintf(f,"*\n"); break;
case SEMI: fprintf(f,";\n"); break;
case COMMA: fprintf(f,",\n"); break;
case COLON: fprintf(f,":\n"); break;
case LPAREN: fprintf(f,"(\n"); break;
case RPAREN: fprintf(f,")\n"); break;
case LSQUAR: fprintf(f,"[\n"); break;
case RSQUAR: fprintf(f,"]\n"); break;
case LBRACE: fprintf(f,"{\n"); break;
case RBRACE: fprintf(f,"}\n"); break;
case DOT: fprintf(f,".\n"); break;
case WAVE: fprintf(f,"~n"); break;
case ENDFILE: fprintf(f,"EOF\n"); break;
case NEQ: fprintf(f,"!=\n"); break;
case ASSIGN : fprintf(f,":=\n"); break;
case EQ : fprintf(f,"==\n"); break;
case GT : fprintf(f,">\n"); break;
case GTEQ: fprintf(f,">=\n"); break;
case LT: fprintf(f,"<\n"); break;
case LTEQ: fprintf(f,"<=\n");
break;
case ID: fprintf(f,"ID, val= %s\n",tokenstring);
break;
case NUM: fprintf(f,"NUM, name= %s\n",tokenstring);
break;
}
}
token scanner::getToken()
{
int tokenstrpos=0;
char ch;
token curtoken;
TokenType tokType;
Statetype state=START;
int save;
while(state!=DONE)
{ ch = readachar();
//printf("%c",ch);
save=1;
switch(state)
{
case START:
if(isalpha(ch)) state=INID;
else if(isdigit(ch)) state=INNUM;
else if(ch=='<') state=INLTEQ;
else if(ch=='>') state=INGTEQ;
else if(ch=='=') state=INEQ;
else if(ch=='!') state=INNEQ;
else if(ch=='/')
{
if((ch=readachar())!='*')
{
backachar();
tokType=SLASH;
state=DONE;
}
else
{
state=INCOMMENT;
save=0;
}
}
else if(ch==' '|| ch=='\n'|| ch=='\t')
{
save=0;
}
else
{
switch(ch)
{
case '+':
tokType=PLUS;
break;
case '-':
tokType=MINUS;
break;
case '*':
tokType=STAR;
break;
case ';':
tokType=SEMI;
break;
case ',':
tokType=COMMA;
break;
case ':':
tokType=COLON;
break;
case '(':
tokType=LPAREN;
break;
case ')':
tokType=RPAREN;
break;
case '[':
tokType=LSQUAR;
break;
case ']':
tokType=RSQUAR;
break;
case '{':
tokType=LBRACE;
break;
case '}':
tokType=RBRACE;
break;
case '.':
tokType=DOT;
break;
case '~':
tokType=WAVE;
break;
case EOF:
save=0;
tokType=ENDFILE;
break;
default:
save=0;
tokType=ERROR;
break;
}
state=DONE;
}
break;
case INID: //这里决定了变量名的命名规则:以字母开头的任意字母数字串;不包含任何的特殊字符
if(!(isalpha(ch))&&!(isdigit(ch)))
{
backachar();
tokType=ID;
state=DONE;
save=0;
}
break;
case INNUM:
if(!(isdigit(ch))) //这里处理了float类型
{
backachar();
tokType=NUM;
state=DONE;
save=0;
}
break;
case INLTEQ:
if(ch=='=')
{
tokType=LTEQ;
state=DONE;
}
else
{
backachar();
tokType=LT;
state=DONE;
save=0;
}
break;
case INGTEQ:
if(ch=='=')
{
tokType=GTEQ;
state=DONE;
}
else
{
backachar();
tokType=GT;
state=DONE;
save=0;
}
break;
case INEQ:
if(ch=='=')
{
tokType=EQ;
state=DONE;
}
else
{
backachar();
tokType=ASSIGN;
state=DONE;
save=0;
}
break;
case INNEQ:
if(ch=='=')
{
tokType=NEQ;
state=DONE;
}
else
{
backachar();
tokType=ERROR;
state=DONE;
save=0;
}
break;
case INCOMMENT:
if(ch=='*')
{
if(readachar()=='/')
state=START;
}
save=0;
break;
case DONE:
default:
state=DONE;
tokType=ERROR;
break;
}//zuiwai swith
if ((save)&&(tokenstrpos<=MAXTOKEN))
tokenstr[tokenstrpos++]=ch;
if(state==DONE)
tokenstr[tokenstrpos]='\0';
if(tokType==ID)
{
tokType=LookupReserved(tokenstr);
}
}//while
curtoken.ftype(tokType);
curtoken.fstr(tokenstr);
curtoken.fline(linenum);
return curtoken;
//if(linenum>0)
//{fprintf(fo,"\t%d ",linenum);}
// return tokType;
}
scanner::scan()
{ // TokenType flag;
flag=getToken();
while(flag.ttype!=ENDFILE)
{ fprintf(fo,"\t%d ",flag.line);
foutput(fo,flag.ttype,flag.str);
flag=getToken();
}
fclose(fo);
fclose(fp);
//while(flag.ttype!=ENDFILE)
// { fprintf(fo,"\t%d ",linenum);
// foutput(flag.ttype,flag.str);
// flag=getToken();
// }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -