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

📄 compiler.cpp

📁 SNL语言编译器源码 小语言的编译器C++实现 包括词法分析
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************/
/* 文件	compiler.cpp								*/
/* 说明 类compiler的内部实现实现					*/
/* 主题 编译器结构:原理和实例						*/
/****************************************************/

/************ 该代码文件所包含的头文件 **************/

#include "globals.h"	/* 该头文件globals.h定义了全局类与变量 */

#include "string.h"

#include "ctype.h"      /* 用到了该库中的isalnum,isalpha,isdigit函数 */

#include "func.h"		/* 该头文件func.h定义了相关功能函数 */

#include "math.h"       /* 用到了这个库里的取模运算 */

#include "compiler.h"

#include "stdio.h"

#include<iostream.h>



/************************************************************/
/* 成员函数名 compiler						   			    */
/* 功  能 构造函数									        */
/* 说  明 		*/

/************************************************************/
 compiler::compiler()
{

    tokenlist=NULL;
    Tree=NULL;
}

/*=========================词法分析==================================*/

/************************************************************/
/* 函数名 getTokenlist						   			    */
/* 功  能 取得单词函数										*/
/* 说  明 函数从源文件字符串序列中获取所有Token序列 		*/
/*        使用确定性有限自动机DFA,采用直接转向法    		*/
/*        超前读字符,对保留字采用查表方式识别    			*/
/*        产生词法错误时候,仅仅略过产生错误的字符,不加改正  */
/************************************************************/
ChainNodeType * compiler::getTokenlist(FILE * source)
{
   ChainNodeType *chainHead;    /*链表的表头指针*/
   ChainNodeType *currentNode;  /*指向处理当前Token的当前结点*/
   ChainNodeType *preNode;      /*指向当前结点的前驱结点*/
   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 = scanner::getNextChar(source);

    	/* 当前正识别字符的存储标志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;

	    	 
	       /* 当前字符c为',当前DFA状态state设置为字符标志状态*/
	       /* INCHAR,确定性有限自动机DFA处于字符标志类型单词中*/
			 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 = ENDFILE;
                   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设置为错误单词ERROR */
                   default:
                   currentToken.Lex = ERROR;
				   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 = ENDFILE;

         }

		 /* 当前字符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设置为ERROR */
         else
         { 
			 scanner::ungetNextChar();
           save = FALSE;
           currentToken.Lex = ERROR;
		   Error = TRUE;
         }
         break;
        
	   case INRANGE:				

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

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

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

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

⌨️ 快捷键说明

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