/****************************************************/ /* File: scan.c */ /* The scanner implementation for the TINY compiler */ /* Compiler Construction: Principles and Practice */ /* Kenneth C. Louden */ /****************************************************/ #include "globals.h" #include "util.h" #include "scan.h" /* states in scanner DFA */ typedef enum { START,INASSIGN,INCOMMENT,INNUM,INID,DONE } 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[MAXRESERVED] = {{"if",IF},{"then",THEN},{"else",ELSE},{"end",END}, {"repeat",REPEAT},{"until",UNTIL},{"read",READ}, {"write",WRITE}}; /* 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