📄 scan.h
字号:
#ifndef SCAN_H_
#define SCAN_H_
#include <string>
#include <sstream>
#include <list>
#include "global.h"
#include "util.h"
using namespace std;
string inner_source=
"int input(void){return 0;}\n"
"void output(int x){}\n";
stringstream innersrc(inner_source);
typedef struct tokenunit{
TokenType token;
string tokenstring;
int lineno;
} TokenUnit;
struct{
char * word;
TokenType type;
} ReservedWords[10]={
{"if",IF},{"else",ELSE},{"while",WHILE},
{"return",RETURN},{"void",VOID},{"int",INT},{""}
};
typedef enum{
INID,INNUM,INLTEQ,INGTEQ,INEQ,INNEQ,
INCOMMENT,START,DONE
} ScanState;
list<TokenUnit> tokenHist;
list<TokenUnit>::iterator tokenIt=tokenHist.end();
TokenType LookupReserved(string &token)
{
int i=0;
while(ReservedWords[i].word[0]!='\0')
{
if(token==ReservedWords[i].word)
return ReservedWords[i].type;
i++;
}
return ID;
}
TokenType GetToken()
{
TokenType rettype;
if(tokenIt!=tokenHist.end()){
rettype=(*tokenIt).token;
TokenString=(*tokenIt).tokenstring;
lineno=(*tokenIt).lineno;
++tokenIt;
return rettype;
}
char ch;
int save=1;
ScanState state=START;
TokenString="";
while(state!=DONE)
{
istream *is;
if(!innersrc.eof()){
is=&innersrc;
ch=is->get();
if(ch==EOF) ch='\n';
}
else{
is=&fsource;
ch=is->get();
if(ch=='\n') lineno++;
}
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=is->get())!='*') {
is->putback(ch);
rettype=DIV;
state=DONE;
}
else{
state=INCOMMENT;
save=0;
}
}
else if(ch==' ' || ch=='\n' || ch=='\t') {
save=0;
}
else{
switch(ch){
case '+':
rettype=PLUS;
break;
case '-':
rettype=MINUS;
break;
case '*':
rettype=MUL;
break;
case ';':
rettype=SEMI;
break;
case ',':
rettype=COMMA;
break;
case '(':
rettype=LPAREN;
break;
case ')':
rettype=RPAREN;
break;
case '[':
rettype=LSQUAR;
break;
case ']':
rettype=RSQUAR;
break;
case '{':
rettype=LBRACE;
break;
case '}':
rettype=RBRACE;
break;
case EOF:
save=0;
rettype=ENDFILE;
break;
default:
save=0;
rettype=ERROR;
break;
}
state=DONE;
}
break;
case INID:
if(!isalpha(ch)) {
is->putback(ch);
rettype=ID;state=DONE;
save=0;
}
break;
case INNUM:
if(!isdigit(ch)) {
is->putback(ch);
rettype=NUMBER;state=DONE;
save=0;
}
break;
case INLTEQ:
if(ch=='=') {rettype=LTEQ;state=DONE;}
else{is->putback(ch);rettype=LT;state=DONE;save=0;}
break;
case INGTEQ:
if(ch=='=') {rettype=GTEQ;state=DONE;}
else{is->putback(ch);rettype=GT;state=DONE;save=0;}
break;
case INEQ:
if(ch=='=') {rettype=EQ;state=DONE;}
else{is->putback(ch);rettype=ASSIGN;state=DONE;save=0;}
break;
case INNEQ:
if(ch=='=') {rettype=LTEQ;state=DONE;}
else{is->putback(ch);rettype=ERROR;state=DONE;save=0;}
break;
case INCOMMENT:
if(ch=='*'){
if(is->get()=='/')
state=START;
}
save=0;
break;
}
if(save==1) TokenString+=ch;
else save=1;
}
if(rettype==ID){
rettype=LookupReserved(TokenString);
}
TokenUnit tu;
tu.lineno=lineno;
tu.token=rettype;
tu.tokenstring=TokenString;
tokenHist.push_back(tu);
ftoken<<TokenString<<endl;
return rettype;
}
list<TokenUnit>::iterator Backup()
{
list<TokenUnit>::iterator it;
if(tokenIt==tokenHist.end()) it=--tokenHist.end();
else {
it=--tokenIt;
++tokenIt;
}
return it;
}
void Restore(list<TokenUnit>::iterator &it)
{
tokenIt=it;
token=GetToken();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -