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

📄 scan.cpp

📁 上课时老师用过的SNL编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	  return;
   }
   
   ChainNodeType *chainHead;    /*链表的表头指针*/
  
   ChainNodeType *currentNode;  /*指向处理当前Token的当前结点*/
   
   ChainNodeType *preNode;      /*指向当前结点的前驱结点*/
   
   ChainNodeType *p1;           /*临时指针,用于释放链表部分*/
   
   TokenType currentToken;      /*存放当前的Token*/

/*产生链表的第一个结点*/   
 chainHead=preNode=currentNode=(ChainNodeType *)malloc(CHAINNODELEN);

/*初始化当前结点中,指向下一个结点的指针为空*/
 currentNode->nextToken=NULL;
do 
{  /* tokenStringIndex用于记录当前正在识别单词的词元存储区 *
	* tokenString中的当前正在识别字符位置,初始为0          */
   int tokenStringIndex = 0;
   
   /* 当前状态标志state,始终都是以START作为开始 */
   StateType state = START;

   /* tokenString的存储标志save,整数类型						*
    * 决定当前识别字符是否存入当前识别单词词元存储区tokenString */
   int save;

   /* 当前确定性有限自动机DFA状态state不是完成状态DONE */
   while (state != DONE)
   
   { 
     /* 从源代码文件中获取下一个字符,送入变量c作为当前字符 */
	   int c = getNextChar();

	 /* 当前正识别字符的存储标志save初始为TRUE */
     save = TRUE;					

     switch (state)
     { 
	   /* 当前DFA状态state为开始状态START,DFA处于当前单词开始位置 */
       case START:

    	 /* 当前字符c为数字,当前DFA状态state设置为数字状态INNUM *
	      * 确定性有限自动机DFA处于数字类型单词中               */
		 if (isdigit(c))				
           state = INNUM;				

		 /* 当前字符c为字母,当前DFA状态state设置为标识符状态INID *
		  * 确定性有限自动机DFA处于标识符类型单词中              */
         else if (isalpha(c))
           state = INID;				

		 /* 当前字符c为冒号,当前DFA状态state设置为赋值状态INASSIGN *
		  * 确定性有限自动机DFA处于赋值类型单词中				   */
         else if (c == ':')
           state = INASSIGN;		
  		 
		 /* 当前字符c为.,当前DFA状态state设置为数组下标界限状态*/
		 /* INRANGE,确定性有限自动机DFA处于数组下标界限类型单词中*/                         
		 else if (c == '.')
		   state = INRANGE;

		 else if (c == '\'')
		     { save = FALSE;
		       state = INCHAR; }
		   
		   /* 当前字符c为空白(空格,制表符,换行符),字符存储标志save设置为FALSE *
		  * 当前字符为分隔符,不需要产生单词,无须存储                        */
         else if ((c == ' ') || (c == '\t') || (c == '\n'))
           save = FALSE;				

		 /* 当前字符c为左括号,字符存储标志save设置为FALSE     *
		  * 当前DFA状态state设置为注释状态INCOMMENT			  *	
		  * 确定性有限自动机DFA处于注释中,不生成单词,无需存储 */
         else if (c == '{')
         { save = FALSE;
           state = INCOMMENT;			
         }

	     /* 当前字符c为其它字符,当前DFA状态state设置为完成状态DONE *
	      * 确定性有限自动机DFA处于单词的结束位置,需进一步分类处理 */
         else

         { state = DONE;				
           switch (c)
           {
			 /* 当前字符c为EOF,字符存储标志save设置为FALSE,无需存储     *
			  * 当前识别单词返回值currentToken设置为文件结束单词ENDFILE */
		     case EOF:
               save = FALSE;
               currentToken.Lex = ENDFILE1;
               break;					

			 /* 当前字符c为"=",当前识别单词返回值currentToken设置为等号单词EQ */
             case '=':
               currentToken.Lex = EQ;
               break;

			 /* 当前字符c为"<",当前识别单词返回值currentToken设置为小于单词LT */
             case '<':
               currentToken.Lex = LT;
               break;

			 /* 当前字符c为"+",当前识别单词返回值currentToken设置为加号单词PLUS */
             case '+':
               currentToken.Lex = PLUS;
               break;

			 /* 当前字符c为"-",当前识别单词返回值currentToken设置为减号单词MINUS */
             case '-':
               currentToken.Lex = MINUS;
               break;

			 /* 当前字符c为"*",当前识别单词返回值currentToken设置为乘号单词TIMES */
             case '*':
               currentToken.Lex = TIMES;
               break;

			 /* 当前字符c为"/",当前识别单词返回值currentToken设置为除号单词OVER */
             case '/':
               currentToken.Lex = OVER;
               break;

			 /* 当前字符c为"(",当前识别单词返回值currentToken设置为左括号单词LPAREN */
             case '(':
               currentToken.Lex = LPAREN;
               break;

			 /* 当前字符c为")",当前识别单词返回值currentToken设置为右括号单词RPAREN */
             case ')':
               currentToken.Lex = RPAREN;
               break;

			 /* 当前字符c为";",当前识别单词返回值currentToken设置为分号单词SEMI */
             case ';':
               currentToken.Lex = SEMI;
               break;
   	    	 /* 当前字符c为",",当前识别单词返回值currentToken设置为逗号单词COMMA */
 			 case ',':
			   currentToken.Lex = COMMA;
               break;     		 
		     /* 当前字符c为"[",当前识别单词返回值currentToken设置为左中括号单词LMIDPAREN */
			 case '[':
			   currentToken.Lex = LMIDPAREN;
			   break;
    		 
			 /* 当前字符c为"]",当前识别单词返回值currentToken设置为右中括号单词RMIDPAREN */
			 case ']':
			   currentToken.Lex = RMIDPAREN;
			   break;
    
			 /* 当前字符c为其它字符,当前识别单词返回值currentToken设置为错误单词ERROR1 */
             default:
               currentToken.Lex = ERROR1;
               Error = true;
			   break;
           }
         }
         break;						
	   /********** 当前状态为开始状态START的处理结束 **********/

	   /* 当前DFA状态state为注释状态INCOMMENT,确定性有限自动机DFA处于注释位置 */
       case INCOMMENT:

		 /* 当前字符存储状态save设置为FALSE,注释中内容不生成单词,无需存储 */
         save = FALSE;				

		 /* 当前字符c为EOF,当前DFA状态state设置为完成状态DONE,当前单词识别结束 *
		  * 当前识别单词返回值currentToken设置为文件结束单词ENDFILE            */
         if (c == EOF)			
         { state = DONE;
           currentToken.Lex = ENDFILE1;

         }

		 /* 当前字符c为"}",注释结束.当前DFA状态state设置为开始状态START */
         else if (c == '}') state = START;
         break;

	   /* 当前DFA状态state为赋值状态INASSIGN,确定性有限自动机DFA处于赋值单词位置 */
       case INASSIGN:				

		 /* 当前DFA状态state设置为完成状态DONE,赋值单词结束 */
         state = DONE;				

		 /* 当前字符c为"=",当前识别单词返回值currentToken设置为赋值单词ASSIGN */
		 if (c == '=')
           currentToken.Lex = ASSIGN;

		 /* 当前字符c为其它字符,即":"后不是"=",在输入行缓冲区中回退一个字符       *
		  * 字符存储状态save设置为FALSE,当前识别单词返回值currentToken设置为ERROR1 */
         else
         { 
           ungetNextChar();
           save = FALSE;
           currentToken.Lex = COLON;
         }
         break;
        
	   case INRANGE:				

		 /* 当前DFA状态state设置为完成状态DONE,赋值单词结束 */
         state = DONE;				

		 /* 当前字符c为".",当前识别单词返回值currentToken设置为下标界UNDERANGE */
		 if (c == '.')
           currentToken.Lex = UNDERANGE;

		 /* 当前字符c为其它字符,即"."后不是".",在输入行缓冲区中回退一个字符       *
		  * 字符存储状态save设置为FALSE,当前识别单词返回值currentToken设置为ERROR1 */
         else
         { 
           ungetNextChar();
           save = FALSE;
           currentToken.Lex = DOT;
         }
         break;
 
	   /* 当前DFA状态state为数字状态INNUM,确定性有限自动机处于数字单词位置 */
    case INNUM:					

		 /* 当前字符c不是数字,则在输入行缓冲区源中回退一个字符					*
		  * 字符存储标志设置为FALSE,当前DFA状态state设置为DONE,数字单词识别完成 *
		  * 当前识别单词返回值currentToken设置为数字单词NUM                     */
         if (!isdigit(c))
         { 
           ungetNextChar();
           save = FALSE;
           state = DONE;
           currentToken.Lex = INTC;
         }
         break;
  case INCHAR:					

         if (isalnum(c))
        
		 { int c1=getNextChar();
            if (c1 =='\'')
			{ save = TRUE;
			   state = DONE;
			  currentToken.Lex = CHARC;
			}
		    else 
			{	ungetNextChar();
                ungetNextChar();
			    //save = TRUE;
                state = DONE;
                currentToken.Lex = ERROR1;
				Error = true;
			}
		 }
		 else
		 {      ungetNextChar();
			    //save = TRUE;
                state = DONE;
                currentToken.Lex = ERROR1;
				Error = true;
			}
		 break;
   /* 当前DFA状态state为标识符状态INID,确定性有限自动机DFA处于标识符单词位置 */
       case INID:					

		 /* 当前字符c不是字母,则在输入行缓冲区源中回退一个字符		 			  *
		  * 字符存储标志设置为FALSE,当前DFA状态state设置为DONE,标识符单词识别完成 *
		  * 当前识别单词返回值currentToken设置为标识符单词ID                      */
         if (!isalnum(c))
         { 
           ungetNextChar();
           save = FALSE;
           state = DONE;
           currentToken.Lex = ID;
         }
         break;

	   /* 当前DFA状态state为完成状态DONE,确定性有限自动机DFA处于单词结束位置 */
       case DONE:	break;	

	   /* 当前DFA状态state为其它状态,此种情况不应发生 */
       default: 

		 /* 将词法扫描器产生错误的状态state写入列表文件listing	*
		  * 当前DFA状态state设置为完成状态DONE					*
		  * 当前识别单词返回值currentToken设置为错误单词ERROR1	*/
         fprintf(listing,"Scanner Bug: state= %d\n",state);
         state = DONE;
         currentToken.Lex = ERROR1;
		 Error = true;
         break;

     }
	 /*************** 分类判断处理结束 *******************/

	 /* 当前字符存储状态save为TRUE,且当前正识别单词已经识别部分未超过单词最大长度 *
	  * 将当前字符c写入当前正识别单词词元存储区tokenString						  */
     if ((save) && (tokenStringIndex <= MAXTOKENLEN))
       tokenString[tokenStringIndex++] = (char) c;

	 if (state == DONE)
     {
	   /* 当前DFA状态state为完成状态DONE,单词识别完成   *
	    * 当前识别单词词元存储区tokenString加上结束标志 */
	   tokenString[tokenStringIndex] = '\0';

	   /* 当前单词currentToken为标识符单词类型,查看其是否为保留字单词 */
    if (currentToken.Lex == ID)
	  { currentToken.Lex =  reservedLookup(tokenString);
		// if (currentToken.Lex != ID)
		//	 strcpy(tokenString," ");
      }
     }
   }
   /**************** 循环处理结束 ********************/
   /*将行号信息存入Token*/
   currentToken.lineshow = lineno;
   /*将单词的语义信息存入Token*/
   strcpy(currentToken.Sem , tokenString); 

  /*将已处理完的当前Token存入链表的Token部分*/
    (currentNode->Token).lineshow=currentToken.lineshow;
   	(currentNode->Token).Lex=currentToken.Lex;
	strcpy((currentNode->Token).Sem,currentToken.Sem);
 
     Tokennum++;   /*Token总数目加1*/
  
     /*若不是第一个结点,则将当前结点连入链表*/ 
	 if (preNode!=currentNode)
	    {  preNode->nextToken=currentNode;
           preNode=currentNode;
	    }   
   /*申请一个新的结点,以记录下一个Token的信息*/
	 currentNode=(ChainNodeType *)malloc(CHAINNODELEN);
   /*初始化这个结点中,指向下一个结点的指针为空*/ 
	 currentNode->nextToken=NULL;
 }
/* 直到处理完表示文件结束的Token:ENDFILE,说明处理完所有的Token*/
/* 并存入了链表中,循环结束*/
 while ((currentToken.Lex)!=ENDFILE1); 

/*将由chainHead指向的Token链表存入文件"Tokenlist"中*/
  ChainToFile(chainHead);   

/*释放链表*/
while (chainHead!=NULL)
{ p1=chainHead->nextToken;
  free(chainHead);  
  chainHead=p1; 
}

//关闭读入的源文件:
fclose(source);

/* 词法分析函数结束 */


}

⌨️ 快捷键说明

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