📄 scan.h
字号:
struct
{
char* str;
TokenType tok;
} reservedWords[8] = { {"if",IF},{"then",THEN},{"else",ELSE},{"end",END},{"repeat",REPEAT},
{"until",UNTIL},{"read",READ},{"write",WRITE} };
const int MAXTOKENLEN = 40;
const int BUFLEN = 256;
typedef enum { START,INASSIGN,INCOMMENT,INNUM,INID,DONE } StateType;
class Scan
{
private:
char lineBuf [ BUFLEN ];
int linepos;
int bufsize;
int EOF_flag;
FILE *source;
protected:
int getNextChar();
void ungetNextChar ();
TokenType reservedLookup (char * s);
public:
Scan (const char* filename);
char tokenString [ MAXTOKENLEN+1 ] ;
TokenType getToken ();
void getEachToken ();
};
Scan::Scan (const char* filename)
{
source = fopen (filename,"r");
linepos = 0;
bufsize = 0;
EOF_flag = 0;
};
int Scan::getNextChar()
{
if (!(linepos < bufsize))
{
lineno++;
if (fgets(lineBuf,BUFLEN-1,source))
{
bufsize = strlen(lineBuf);
linepos = 0;
return lineBuf[linepos++];
}
else
{
EOF_flag = 1;
return EOF;
}
}
else return lineBuf[linepos++];
};
void Scan::ungetNextChar()
{
if (!EOF_flag) linepos-- ;
}
TokenType Scan:: reservedLookup (char * s)
{ int i;
for (i=0;i<8;i++)
if (!strcmp(s,reservedWords[i].str))
return reservedWords[i].tok;
return ID;
}
TokenType Scan::getToken()
{
int tokenStringIndex = 0;
TokenType currentToken;
StateType state = START;
int save;
while (state != DONE)
{ int c = getNextChar();
save = 1;
switch (state)
{ case START:
if (isdigit(c))
state = INNUM;
else if (isalpha(c))
state = INID;
else if (c == ':')
state = INASSIGN;
else if ((c == ' ') || (c == '\t') || (c == '\n'))
save = 0;
else if (c == '{')
{ save = 0;
state = INCOMMENT;
}
else
{ state = DONE;
switch (c)
{ case EOF:
save = 0;
currentToken = ENDFILE;
break;
case '=':
currentToken = EQ;
break;
case '<':
currentToken = LT;
break;
case '+':
currentToken = PLUS;
break;
case '-':
currentToken = MINUS;
break;
case '*':
currentToken = TIMES;
break;
case '/':
currentToken = OVER;
break;
case '(':
currentToken = LPAREN;
break;
case ')':
currentToken = RPAREN;
break;
case ';':
currentToken = SEMI;
break;
default:
currentToken = ERROR;
break;
}
}
break;
case INCOMMENT:
save = 0;
if (c == EOF)
{ state = DONE;
currentToken = ENDFILE;
}
else if (c == '}') state = START;
break;
case INASSIGN:
state = DONE;
if (c == '=')
currentToken = ASSIGN;
else
{
ungetNextChar();
save = 0;
currentToken = ERROR;
}
break;
case INNUM:
if (!isdigit(c))
{
ungetNextChar();
save = 0;
state = DONE;
currentToken = NUM;
}
break;
case INID:
if (!isalpha(c))
{
ungetNextChar();
save = 0;
state = DONE;
currentToken = ID;
}
break;
case DONE:
default:
cout<<"Scanner Bug: state= "<<state<<endl;
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);
}
}
printToken(currentToken,tokenString);
return currentToken;
}
void Scan::getEachToken ()
{
while ( getToken() != ENDFILE );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -