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

📄 scanner.cpp

📁 用C++语言在VC6.0环境下编写的小型c语言编译器
💻 CPP
字号:
// scanner.cpp: implementation of the scanner class.
//
//////////////////////////////////////////////////////////////////////

#include "scanner.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


scanner::scanner()
{
	bufpos=0;              //缓冲区中当前读取字符的位置
    linenum=0;                    //行号
	trbufsize=0;
	fo=fopen(FILENAME1, "w");
    fp=fopen(FILENAME, "r");
//	if(fp==NULL)
//	{ cout<<FILENAME<<"没有被创建";
//	return;
//	}
//	else if(feof(fp))
//	{ cout<<FILENAME<<"文件为空";
//	return;
//	}
	 rs[0].str="if";rs[0].tok=IF;        
	 rs[1].str="int";rs[1].tok=INT;
     rs[2].str="else";rs[2].tok=ELSE;   
	 rs[3].str="while";rs[3].tok=WHILE;
	 rs[4].str="rerurn";rs[4].tok=RETURN;
	 rs[5].str="void";rs[5].tok=VOID;
	 rs[6].str="class";rs[6].tok=CLASS;  
	 rs[7].str="public";rs[7].tok=PUBLIC;
	 rs[8].str="private";rs[8].tok=PRIVATE;
	 rs[9].str="protected";rs[9].tok=PROTECTED;
	 rs[10].str="this";rs[10].tok=THIS;      
	 rs[11].str="new";rs[11].tok=NEW;
	 rs[12].str="delete";rs[12].tok=DELETE;
     rs[13].str="virtual";rs[13].tok=VIRTUAL;
	 rs[14].str="try";rs[14].tok=TRY;
	 rs[15].str="catch";rs[15].tok=CATCH;
	 rs[16].str="throw";rs[16].tok=THROW;
	 rs[17].str="exp";rs[17].tok=EXP;
}

scanner::~scanner()
{

}

char scanner::readachar()
{
 if(!(bufpos<trbufsize))
	{   linenum=linenum+1;
        if(fgets(buffer,BUFLENTH,fp)!=NULL)
		{   
			bufpos=0;
		  trbufsize=strlen(buffer);
          return buffer[bufpos++];
		}
        else  return EOF;
	}
  else  return buffer[bufpos++];
}

scanner::backachar()
{
bufpos=bufpos-1;
}

TokenType scanner::LookupReserved(char *string)
{
for(int i=0;i<18;i++)
  { if(!strcmp(string,rs[i].str))
       return rs[i].tok;
  }
  return  ID;
}

scanner::foutput(FILE * f , TokenType tokentype, char *tokenstring)
{
switch (tokentype)
{     case  IF:        
	  case  INT:
      case ELSE:   
	  case WHILE:
	  case RETURN:
	  case VOID:
	  case CLASS:
	  case PUBLIC:
	  case PRIVATE:
	  case PROTECTED:
	  case THIS:      
	  case NEW:
	  case DELETE:
      case VIRTUAL:
	  case TRY:
	  case CATCH:
	  case THROW:
	  case EXP:	
           fprintf(f,"reserved word:    %s\n",tokenstring); break;
      case PLUS: fprintf(f,"+\n"); break;
	  case MINUS: fprintf(f,"-\n"); break;
	  case STAR: fprintf(f,"*\n"); break;				 
	  case SEMI: fprintf(f,";\n"); break;	
	  case COMMA: fprintf(f,",\n"); break;	
	  case COLON: fprintf(f,":\n"); break;	
	  case LPAREN: fprintf(f,"(\n"); break;	
	  case RPAREN: fprintf(f,")\n"); break;
	  case LSQUAR: fprintf(f,"[\n"); break;
	  case RSQUAR: fprintf(f,"]\n"); break;
	  case LBRACE: fprintf(f,"{\n"); break;
	  case RBRACE: fprintf(f,"}\n"); break;
	  case DOT: fprintf(f,".\n"); break;
	  case WAVE: fprintf(f,"~n"); break;
	  case ENDFILE: fprintf(f,"EOF\n"); break;
	  case NEQ: fprintf(f,"!=\n"); break;
	  case ASSIGN : fprintf(f,":=\n"); break;
      case EQ : fprintf(f,"==\n"); break;   
      case GT : fprintf(f,">\n"); break;
      case GTEQ: fprintf(f,">=\n"); break;
	  case LT: fprintf(f,"<\n");  break;
	  case LTEQ: fprintf(f,"<=\n");  
		   break;
      case ID: fprintf(f,"ID,  val= %s\n",tokenstring); 
	       break;
      case NUM: fprintf(f,"NUM,  name= %s\n",tokenstring); 
	       break;
      
}
}

token scanner::getToken()
{

    int  tokenstrpos=0;  
    char ch; 
	token curtoken;
    TokenType  tokType;               
    Statetype  state=START;
    int save;
    
    while(state!=DONE)
	{ ch = readachar();
	  //printf("%c",ch);
      save=1;
      switch(state)
	  {
        case  START:
			 if(isalpha(ch))	state=INID;
			 else if(isdigit(ch))	state=INNUM;
			 else if(ch=='<') state=INLTEQ;
			 else if(ch=='>') state=INGTEQ;
			 else if(ch=='=') state=INEQ;
			 else if(ch=='!') state=INNEQ;
			 else if(ch=='/') 
			 {
				 if((ch=readachar())!='*') 
				 {
					 backachar();
					 tokType=SLASH;
					 state=DONE;
				 }
				 else
				 {
					 state=INCOMMENT;
					 save=0;
				 }
			 }
			 else if(ch==' '|| ch=='\n'|| ch=='\t') 
			 {
				 save=0;
			 }
			 else
			 {   
				 
				 switch(ch)
				 {
				 case '+':
					 tokType=PLUS;
					 break;
				 case '-':
					 tokType=MINUS;
					 break;
				 case '*':
					 tokType=STAR;
					 break;
				 case ';':
					 tokType=SEMI;
					 break;
				 case ',':
					 tokType=COMMA;
					 break;
				 case ':':
					 tokType=COLON;
					 break;
				 case '(':
					 tokType=LPAREN;
					 break;
				 case ')':
					 tokType=RPAREN;
					 break;
				 case '[':
					 tokType=LSQUAR;
					 break;
				 case ']':
					 tokType=RSQUAR;
					 break;
				 case '{':
					 tokType=LBRACE;
					 break;
				 case '}':
					 tokType=RBRACE;
					 break;
				 case '.':
					 tokType=DOT;
					 break;
				 case '~':
					 tokType=WAVE;
					 break;
				 case EOF:
					 save=0;
					 tokType=ENDFILE;
					 break;
				 default:
					 save=0;
					 tokType=ERROR;
					 break;
				 }
              state=DONE;
			 }
			 break;
            case INID:	//这里决定了变量名的命名规则:以字母开头的任意字母数字串;不包含任何的特殊字符
	            if(!(isalpha(ch))&&!(isdigit(ch))) 
				{
	           	backachar();
		        tokType=ID;
		        state=DONE;
		        save=0;
				}
	            break;
            case INNUM:
	            if(!(isdigit(ch)))	//这里处理了float类型
				{
		        backachar();
		        tokType=NUM;
		        state=DONE;
		        save=0;
				}
           	    break;
             case INLTEQ:
	            if(ch=='=') 
				{
	         	tokType=LTEQ;
		        state=DONE;
				}
	            else
				{
	         	backachar();
		        tokType=LT;
		        state=DONE;
		        save=0;
				}
	            break;
            case INGTEQ:
	            if(ch=='=') 
				{
		        tokType=GTEQ;
		        state=DONE;
				}
	             else
				 {
		         backachar();
		         tokType=GT;
		         state=DONE;
		         save=0;
				 }
              	break;
           case INEQ:
	            if(ch=='=') 
				{
	        	tokType=EQ;
		        state=DONE;
				}
	           else
			   {
		        backachar();
		        tokType=ASSIGN;
		        state=DONE;
		        save=0;
			   }
            	break;
           case INNEQ:
	           if(ch=='=')
			   {
	        	tokType=NEQ;  
		        state=DONE;
			   }
	           else
			   {
	          	backachar();
	           	tokType=ERROR;
		        state=DONE;
		        save=0;
			   }
            	break;
            case INCOMMENT:
	            if(ch=='*')
				{
		         if(readachar()=='/')
			     state=START;
				}
	            save=0;
	            break;
			case DONE:
                 default:
					state=DONE;
				    tokType=ERROR;
		         	break;
		}//zuiwai  swith
		if ((save)&&(tokenstrpos<=MAXTOKEN))
	    	tokenstr[tokenstrpos++]=ch;           
		if(state==DONE)
			tokenstr[tokenstrpos]='\0';
			if(tokType==ID)
			{   
				tokType=LookupReserved(tokenstr); 
			}
	
    }//while
	  curtoken.ftype(tokType);	
	  curtoken.fstr(tokenstr);
	  curtoken.fline(linenum);
	return curtoken;
	//if(linenum>0)
	//{fprintf(fo,"\t%d  ",linenum);}
//	return tokType;
}



scanner::scan()
{    // TokenType flag;
      flag=getToken();
	 while(flag.ttype!=ENDFILE)
	 { fprintf(fo,"\t%d  ",flag.line);
      foutput(fo,flag.ttype,flag.str);
	  flag=getToken();
	  }
	  fclose(fo);
	  fclose(fp);
	  //while(flag.ttype!=ENDFILE)
	  // {  fprintf(fo,"\t%d  ",linenum);
       //   foutput(flag.ttype,flag.str);
	//	  flag=getToken();
	 // }
}

⌨️ 快捷键说明

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