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

📄 scan.cpp

📁 pascal的编译器 交作业没问题
💻 CPP
字号:
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include "scan.h"

Scan::Scan();
void Scan::Init(FILE *source)        //初始化
{
	this->source=source;
	listing=stdout;
	linepos = 0;
	bufsize = 0;
	lineno = 0;
	EOF_flag = FALSE; 
}
int Scan::getNextChar()         //读取一个字符
{
	if (!(linepos < bufsize))
	{
		lineno++;
        if(fgets(lineBuf,BUFLEN-1,source))
		{ 
            bufsize = strlen(lineBuf);
            linepos = 0;
            return lineBuf[linepos++];
		}
    else
    {
		EOF_flag = TRUE;
        return EOF;
    }
  }
  else return lineBuf[linepos++];
}

void Scan::ungetNextChar(void)
{ 
	if (!EOF_flag) linepos-- ;
}

Token Scan::getToken()                //取得一个单词符号
{ 
   int isSecond=FALSE;
   int tokenStringIndex = 0;
   TokenType currentToken;
   StateType state = START;
   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;
		   isSecond=TRUE;
         }
         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;
           }
         }  //end else
         break;
       case INCOMMENT:
         if(c!='/' && isSecond)
		 {
			 currentToken=OVER;
			 ungetNextChar();
			 state = DONE;
		 }else{ 
             save = FALSE;
			 isSecond=FALSE;
		 }
         if (c == EOF)
         { state = DONE;
           currentToken = ENDFILE;
         }
         else if (c == '\n') state = START;
         break;
       case INASSIGN:
         state = DONE;
         if (c == '=')
           currentToken = ASSIGN;
         else
         {  
           ungetNextChar();
           save = FALSE;
           currentToken = ERROR;
         }
         break;
       case INNUM:
         if (!isdigit(c))
         {  
           ungetNextChar();
           save = FALSE;
           state = DONE;
           currentToken = NUM;
         }
         break;
       case INID:
         if (!isalpha(c) && !isdigit(c))
         {  
           ungetNextChar();
           save = FALSE;
           state = DONE;
           currentToken = ID;
         }
         break;
       case DONE:
       default:  
         fprintf(listing,"Scanner Bug: state= %d\n",state);
         state = DONE;
         currentToken = ERROR;
         break;
     } //End switch
     if ((save) && (tokenStringIndex <= MAXTOKENLEN))
       token.string[tokenStringIndex++] = (char) c;
     if (state == DONE)
     {
		 token.string[tokenStringIndex] = '\0';
         if (currentToken == ID)
            currentToken = reservedLookup(token.string);
     }
   }
    token.type=currentToken;
    fprintf(listing,"\t%d: ",lineno);
    printToken();
    return token;
} 

TokenType Scan::reservedLookup (char * s)
{
	int i;
    for (i=0;i<MAXRESERVED;i++)
       if (!strcmp(s,reservedWords[i].str))
           return reservedWords[i].tok;
    return ID;
}
void Scan::printToken()
{
	switch (token.type)
	{
	case IF:
    case THEN:
    case ELSE:
    case END:
    case REPEAT:
    case UNTIL:
    case READ:
    case WRITE:
      fprintf(listing,"reserved word: %s\n",token.string);
      break;
    case ASSIGN:  
    case LT: 
    case EQ: 
    case LPAREN: 
    case RPAREN: 
    case SEMI:  
    case PLUS: 
    case MINUS: 
    case TIMES: 
    case OVER: fprintf(listing,"%s\n",token.string);break;
    case ENDFILE:fprintf(listing,"EOF\n"); break;
    case NUM:
      fprintf(listing,"NUM, val= %s\n",token.string);
      break;
    case ID:
      fprintf(listing,"ID, name= %s\n",token.string);
      break;
    case ERROR:
      fprintf(listing,"ERROR: %s\n",token.string);
      break;
    default: 
      fprintf(listing,"Unknown token: %d\n",token.type);
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -