📄 com.c
字号:
/****************************************************/
/* File: c.c */
/* The scanner implementation for the C-Minus compiler */
/* Compiler Construction: Principles a*/
/****************************************************/
#include "GLOBALS2.H"
#include "UTIL.H"
#include "scan.h"
/* states in scanner DFA */
typedef enum
{ START,INID,INNUM,Done,Inassign,Incomment1,Incomment2,M,N}
StateType;
/* lexeme of identifier or reserved word */
char tokenString[MAXTOKENLEN+1];
/* BUFLEN = length of the input buffer for
source code lines */
#define BUFLEN 256
static char lineBuf[BUFLEN]; /* holds the current line */
static int linepos = 0; /* current position in LineBuf */
static int bufsize = 0; /* current size of buffer string */
static int EOF_flag = FALSE; /* corrects ungetNextChar behavior on EOF */
/* getNextChar fetches the next non-blank character
from lineBuf, reading in a new line if lineBuf is
exhausted */
static int getNextChar(void) {
if (!(linepos < bufsize))
{ lineno++;
if (fgets(lineBuf,BUFLEN-1,source)) {
if (EchoSource) fprintf(listing,"%4d: %s",lineno,lineBuf);
bufsize = strlen(lineBuf);
linepos = 0;
return lineBuf[linepos++];
}
else
{ EOF_flag = TRUE;
return EOF;
}
}
else return lineBuf[linepos++];
}
/* ungetNextChar backtracks one character
in lineBuf */
static void ungetNextChar(void)
{ if (!EOF_flag) linepos-- ;}
/* lookup table of reserved words */
static struct
{ char* str;
TokenType tok;
} reservedWords[MAXTOKENLEN]
= {{"if",IF},{"else",ELSE},{"int",INT},{"return",RETURN},{"void",VOID},{"while",WHILE}};
/* lookup an identifier to see if it is a reserved word */
/* uses linear search */
static TokenType reservedLookup (char * s)
{ int i;
for (i=0;i<MAXTOKENLEN;i++)
if (!strcmp(s,reservedWords[i].str))
return reservedWords[i].tok;
return ID;
}
/****************************************/
/* the primary function of the scanner */
/****************************************/
/* function getToken returns the
* next token in source file
*/
TokenType getToken(void)
{ /* index for storing into tokenString */
int tokenStringIndex = 0;
/* holds current token to be returned */
TokenType currentToken;
/* current state - always begins at START
StateType includes:START,ASSIGN,EQ,LT,PLUS,MINUS,TIMES,OVER,LPAREN,RPAREN,SEMI
*/StateType state = START;
/* flag to indicate save to tokenString */
int save;
int judge;
while (state != DONE)
{ int c = getNextChar();
save = TRUE;
switch (state)
{ case START:
if (isdigit(c))
state = INNUM;
else if (isalpha(c))
state = INID;
else if (c == '!')
state = M;
else if ((c == ' ') || (c == '\t') || (c == '\n'))
save = FALSE;
else if (( c== '<')||(c == '>') ||(c == '='))
{
judge = c;
state = Inassign;
}
else if (c == '/')
state = N;
else
{ state = DONE;
switch (c)
{ case EOF:
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 = BL;
break;
case '}':
currentToken = BR;
break;
case '[':
currentToken = ML;
break;
case ']':
currentToken = MR;
break;
case ';':
currentToken = SEMI;
break;
case ',':
currentToken = COMMA;
break;
default:
currentToken = ERROR;
break;
}
}
break;
case INNUM:
if (!isdigit(c))
{ /* backup in the input*/
ungetNextChar();
save = FALSE;
state = DONE;
currentToken = NUM;
}
break;
case INID:
if (!isalpha(c))
{ /* backup in the input*/
ungetNextChar();
save = FALSE;
state = DONE;
currentToken = ID;
}
break;
case N:
if (c == EOF)
{ state = DONE;
save = FALSE;
currentToken = ENDFILE;
}
else if (c == '*')
{ save = FALSE;
state = INCOMMENT1;
}
else
{ currentToken = OVER;
state = DONE;
}
break;
case INCOMMENT1:
if (c == '*') state = INCOMMENT2;
else state = INCOMMENT1;
break;
case INCOMMENT2:
if (c == '*') state = INCOMMENT2;
else if (c == '/')
{ state = DONE;
currentToken = INC;
}
else state = INCOMMENT1;
break;
case M:
state = DONE;
if (c == '=')
currentToken = UN;
else
{ /* backup in the input*/
ungetNextChar();
save = FALSE;
state = DONE;
currentToken = ERROR;
}
break;
case Inassign:
state = DONE;
if(c=='=')
{
if(judge=='>')
currentToken=MORETHAN_EQ;
if(judge=='=')
currentToken=EQ;
if(judge=='<')
currentToken=LESSTHAN_EQ;
}
else
{if(judge=='>')
currentToken=MORETHAN;
if(judge=='=')
currentToken=E;
if(judge=='<')
currentToken=LESSTHAN;
}
break;
case DONE:
default: /* should never happen */
fprintf(listing,"Scanner Bug: 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);
}
return currentToken;
/* end getToken */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -