⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scan.c

📁 Tinyc是很出名的C编译器开发实例
💻 C
字号:
/****************************************************//* 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 256static 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<MAXRESERVED;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 state = START;   /* flag to indicate save to tokenString */   int save;   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 = INASSIGN;         else if ((c == ' ') || (c == '\t') || (c == '\n'))           save = FALSE;         else if (c == '{')         { save = FALSE;           state = INCOMMENT;         }         else         { state = DONE;           switch (c)           { case EOF:               save = FALSE;               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 = FALSE;         if (c == EOF)         { state = DONE;           currentToken = ENDFILE;         }         else if (c == '}') state = START;         break;       case INASSIGN:         state = DONE;         if (c == '=')           currentToken = ASSIGN;         else         { /* backup in the input */           ungetNextChar();           save = FALSE;           currentToken = ERROR;         }         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 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 + -