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

📄 compiler.cpp

📁 SNL语言编译器源码 小语言的编译器C++实现 包括词法分析
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    case INCHAR:					

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

		 /* 当前字符c不是字母,则在输入行缓冲区源中回退一个字符		 			  *
		  * 字符存储标志设置为FALSE,当前DFA状态state设置为DONE,标识符单词识别完成 *
		  * 当前识别单词返回值currentToken设置为标识符单词ID                      */
         if (!isalnum(c))
         { 
			  scanner::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设置为错误单词ERROR	*/
         cout<<"Scanner Bug: state="<<state<<endl;
		 Error = TRUE;
         state = DONE;
         currentToken.Lex = ERROR;
         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 = scanner::reservedLookup(tokenString);
		   if (currentToken.Lex != ID)
			 strcpy(tokenString,tokenString);
       }
     }
   }
   /**************** 循环处理结束 ********************/
   /*将行号信息存入Token*/
   currentToken.lineshow = lineno;

   /*将单词的语义信息存入Token*/
   
       switch (currentToken.Lex)
	   { 
	    /* 单词tokenString为保留字,将保留字词元写入currentToken.Sem*/
        case PROGRAM:
        case PROCEDURE:
		case TYPE:
		case VAR:
		case IF:
		case THEN:
		case ELSE:
		case FI:
		case INTEGER:
		case CHAR:
		case WHILE:
		case DO:
		case ENDWH:
		case BEGIN:
		case END:
		case READ:
		case WRITE:
		case ARRAY:
		case OF:
		case RECORD:
		case RETURN:
	    
			
		/* 单词tokenString为特殊符号:*/
        case ASSIGN: 
        case LT: 
        case EQ:
		case LPAREN:	
		case RPAREN:    		
		case SEMI: 	
		case PLUS: 		
		case MINUS:	
		case TIMES:
		case OVER: 
		case DOT: 
		case COMMA: 
		case LMIDPAREN: 
		case RMIDPAREN: 
		case UNDERANGE: 
  
   	
		case INTC: //NUM (整型常量)		
		case CHARC: //字符型常量
		case ID:  //标识符

		case ERROR: //错误
		
              strcpy(currentToken.Sem, tokenString); 

              break;
		/* 簿记单词符号 */
	    case ENDFILE: //ENDFILE (文件结尾)

              strcpy(currentToken.Sem, "EOF"); 
		/* 单词token为其他未知单词,未知信息写入文件listing,此种情况不应发生 */
		 default: 
              strcpy(currentToken.Sem, "unkown token"); 
			  break;

	   }

  /*将已处理完的当前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)!=ENDFILE);


/*将chainHead赋值给成员变量tokenlist*/
tokenlist=chainHead;
chainHead=NULL;

return tokenlist;
 

}









/*=========================语法分析==================================*/

/********************************************************************/
/* 函数名 getTree       											*/
/* 功  能 语法分析函数												*/
/* 说  明 该函数把词法分析程序作为子程序调用,采用递归下降法			*/
/*		  根据产生式调用递归处理函数,函数为源程序创建语法分析树		*/
/********************************************************************/
TreeNode * compiler::getTree(void)

{ 
  Syntax syn;
  ChainNodeType * tokenl=tokenlist;
  /* 从文件Tokenlist中取得第一个单词,将词法信息送给token */
  syn.setCurrentP(tokenl);
  syn.ReadNextToken();

  /* 开始调用基本语法分析处理函数,递归下降处理 */
  Tree=syn.program();
  
  /* 当前单词token不是ENDFILE,报代码在文件结束前提前结束错误 */
  if (syn.getToken().Lex!=ENDFILE)
	  syn.syntaxError("Code ends before file\n");
 
  /* 函数返回语法树根节点t */
  return Tree;
}

/************************************************************/
/* 函数名  getScope()                                          */
/* 功  能  该函数处理总的语义分析                           */
/* 说  明  对语法树进行分析,得到符号表头指针                                 */
/************************************************************/
SymbTable  ** compiler::getScope(void)
{
	SymbTable * entry=  NULL;
	TreeNode * p = NULL;
	TreeNode * pp = Tree;
    TreeNode *t=Tree;

	SemAnalyze sem;
	/*创建符号表*/
	sem.CreatTable();
	
	/*调用类型内部表示初始化函数*/
	sem.initialize();
	/*语法树的声明节点*/
	p=t->child[1];
    while (p!=NULL) 
    {
	   switch ( p->nodekind ) 
	   { case  TypeK:     sem.TypeDecPart(p->child[0]);  break ;
		 case  VarK :     sem.VarDecPart(p->child[0]);   break ;
         case  ProcDecK:  sem.procDecPart(p);        break ;
		 default:
			sem.ErrorPrompt(p->lineno,"","no this node kind in syntax tree!");
			break;
       }
       p = p->sibling ;/*循环处理*/
	}
	
	/*程序体*/
	t = t->child[2];
	if(t->nodekind==StmLK)
		sem.Body(t);
	
	/*撤销符号表*/
	if (Level!=-1)
	     sem.DestroyTable();
	
	/*输出语义错误*/
	if(Error==TRUE)
		cout<<"\nanalyze error:\n"<<endl;
	/*如果无错误,则输出提示信息*/
	else
		cout<<"\n........ no error!"<<endl;	
    return sem.returnScope();
}


compiler::~compiler()
{
  ChainNodeType *tempNode;     /*临时指针,用于释放链表部分*/

/*释放链表*/
while (tokenlist!=NULL)
 { 
	tempNode=tokenlist->nextToken;
    delete(tokenlist);  
    tokenlist=tempNode; 
 }
tokenlist=NULL;

}



⌨️ 快捷键说明

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