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

📄 userfun.cpp

📁 SNL语言编译器源码 小语言的编译器C++实现 包括词法分析
💻 CPP
字号:

#include "globals.h"
#include "string.h"
#include "userfun.h"
#include "iostream.h"

char * userfun::getRoot(char * filename)
{
/* 
  char * point=strchr (filename, '.');
  char * root="";
  if (point == NULL)
  {
     strcat(filename,".txt");
  }
  for(char * p=filename;p<point;p++)
  {
   strcat(root,); 
  }
*/
   char * root=filename;
   return root;

}

 void userfun::printTokenlist(ChainNodeType *tokenlist)
{
ChainNodeType  *currentP=tokenlist;
  
char lex[20];
do 
	{  
	  switch (currentP->Token.Lex)
	   { 
	    /* 单词token为保留字,将保留字词元以指定格式写入列表文件listing */
        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:
		strcpy(lex,"reserved word:");		
            break;

	    /* 单词token为特殊符号:ASSIGN (赋值),将":="写入文件listing */
		case ASSIGN: strcpy(lex,"ASSIGN"); break;
    
		/* 单词token为特殊符号:LT (小于),将"<"写入文件listing */
		case LT: strcpy(lex,"LT"); break;
  
		/* 单词token为特殊符号:EQ (等于),将"="写入文件listing */
		case EQ: strcpy(lex,"EQ");break;
    
		/* 单词token为特殊符号:LPAREN (左括号),将"("写入文件listing */
		case LPAREN: strcpy(lex,"LPAREN"); break;

		/* 单词token为特殊符号:RPAREN (右括号),将")"写入文件listing */
		case RPAREN: strcpy(lex,"RPAREN"); break;
    
		/* 单词token为特殊符号:SEMI (分号),将";"写入文件listing */
		case SEMI: strcpy(lex,"SEMI"); break;
 
		/* 单词token为特殊符号:PLUS (加号),将"+"写入文件listing */
		case PLUS: strcpy(lex,"PLUS"); break;
 
		/* 单词token为特殊符号;MINUS (减号),将"-"写入文件listing */
		case MINUS: strcpy(lex,"MINUS"); break;

		/* 单词token为特殊符号:TIMES (乘号),将"*"写入文件listing */
		case TIMES: strcpy(lex,"TIMES"); break;

		/* 单词token为特殊符号:OVER (除号),将"/"写入文件listing */
		case OVER: strcpy(lex,"OVER");  break;

		case DOT:  strcpy(lex,"DOT"); break;

		case COMMA: strcpy(lex,"COMMA"); break;

		case LMIDPAREN: strcpy(lex,"LMIDPAREN"); break;

		case RMIDPAREN: strcpy(lex,"RMIDPAREN"); break;

		case UNDERANGE: strcpy(lex,"UNDERANGE"); break;

		/* 单词token为簿记单词符号:ENDFILE (文件结尾),将EOF写入文件listing */
		case ENDFILE:strcpy(lex,"ENDFILE"); break;
    
		/* 单词token为多字符单词符号:NUM (数字),将数值写入文件listing */
		case INTC:
			strcpy(lex,"NUM, val=");
				
			 break;

		case CHARC:
			strcpy(lex,"INCHAR, char=");

			
			break;
    
		/* 单词token为多字符单词符号:ID (标识符),将标识符名写入文件listing */
		case ID:
	strcpy(lex,"ID, name=");

			 
			 break;

		/* 单词token为簿记单词符号:ERROR (错误),将错误信息写入文件listing */
		case ERROR:
				strcpy(lex,"ERROR:");
			
			  break;

		/* 单词token为其他未知单词,未知信息写入文件listing,此种情况不应发生 */
		 default: 
			 	strcpy(lex,"Unknown token:");
			  break;
	  
		}
	   cout<<currentP->Token.lineshow<<":"<<lex<<" "<<currentP->Token.Sem<<endl;
       currentP=currentP->nextToken;
    }
    while (currentP!=NULL);
}



void userfun::ChainToFile(ChainNodeType *Chainhead,char * root)
{
  int num=1;
  ChainNodeType  *currentP=Chainhead;
  /*创建一个新的文件,以存储Token序列*/
  strcat(root,".scn");  //词法分析结果文件的扩展名
  FILE *fp;
  fp=fopen(root,"wb+");
  if (fp==NULL)
         {  cout<<"cannot create file Tokenlist!"<<endl;
             Error = TRUE;
			//exit(0);
	     }  
  
  fp=fopen(root,"ab");   /*按追加方式打开文件*/
    if (fp==NULL)
         {  cout<<"cannot open file Tokenlist!"<<endl;
             Error = TRUE;  
			//exit(0);
	     }  
 /*从表头到表尾,依次将所有的Token写入文件*/ 
	do 
	{  fwrite(currentP,TOKENLEN,1,fp);
       currentP=currentP->nextToken;
       num++;
    }
    while (currentP!=NULL);
    cout<<"成功!"<<endl;
  fclose(fp);  /*关闭文件*/
}


/******************************************************/
/* 函数名 printTree                            */
/* 功  能 把语法树输出,显示在屏幕上           */
/* 说  明 该函数运用了宏来定义增量减量的缩进          */
/******************************************************/
void userfun::printTree(treeNode * tree)

{  int i;

  /* 增量缩进宏,每次进入语法树节点都进行增量缩进 */
  /* 静态变量indentno在函数printTree中	*
 * 用于存储当前子树缩进格数,初始为0		*/
static indentno = 0;
/** 增量/减量缩进宏定义 **/
#define INDENT indentno+=4
#define UNINDENT indentno-=4
INDENT;							

  /* 函数参数给定语法树节点指针tree非NULL(空) */
  while (tree != NULL)
 {		
	/*打印行号*/
	if(tree->lineno==0)
			for(int i=0;i<9;i++)
		       cout<<" ";

	else
	    switch((int)(tree->lineno / 10))
		{
			case 0:
				cout<<"line:"<<tree->lineno;
					for( i=0;i<3;i++)
		               cout<<" ";

				break;
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
				cout<<"line:"<<tree->lineno;
				for(i=0;i<2;i++)
		          cout<<" ";

				break;
			default:
				cout<<"line:"<<tree->lineno;
		          cout<<" ";

		}

    /* 打印相应的空格,进行缩进 */ 
     for (i=0;i<indentno;i++)	
      cout<<" ";	

  
  switch ( tree->nodekind)
  {   case ProK : 
			cout<<"ProK ";
		   break;
      case PheadK:
		  {
			  cout<<"PheadK ";
              cout<<tree->name[0]<<" ";
		
		  }
		   break;
	  case DecK:
		{  cout<<"DecK "; 
          if (tree->attr.ProcAttr.paramt==varparamType )
			  cout<<"var param: ";
		  if (tree->attr.ProcAttr.paramt==valparamType)
			  cout<<"value param: ";
		   switch(tree->kind.dec)
		   { case  ArrayK:
		     { 
			   cout<<"ArrayK ";
               cout<<tree->attr.ArrayAttr.up<<" ";
			   cout<<tree->attr.ArrayAttr.low<<" ";
			   if (tree->attr.ArrayAttr.childtype == CharK)
				    cout<<"Chark ";
			   else if( tree->attr.ArrayAttr.childtype == IntegerK)
				    cout<<"IntegerK ";
			 };break;
		     case  CharK:
			 cout<<"CharK ";break;
			 case  IntegerK:
			 cout<<"IntegerK ";break;
			 case  RecordK:
			 cout<<"RecordK ";break;
			 case  IdK:
			 cout<<"IdK ";
			 cout<<tree->attr.type_name<<" ";
			 break;
			 default: 
				 cout<<"error1!";
				 Error = TRUE;
		   };
         if (tree->idnum !=0)
	       for (int i=0 ; i <= (tree->idnum);i++)
		   {
			   cout<<tree->name[i]<<" ";
				
		   }
		else  
			{
			cout<<"wrong!no var!"<<endl;
				Error = TRUE;	
			}
		} break;
	  case TypeK:
		   cout<<"TypeK ";break;
	  
	  case VarK:
		   cout<<"VarK ";
		   if(tree->table[0]!=NULL)
			   cout<<tree->table[0]->attrIR.More.VarAttr.off<<" "<<tree->table[0]->attrIR.More.VarAttr.level<<" ";
		   break;
	  
	  case ProcDecK: 
			cout<<"ProcDecK ";
		    cout<<tree->name[0]<<" ";
			if(tree->table[0]!=NULL)
				cout<<tree->table[0]->attrIR.More.ProcAttr.mOff<<" "<<tree->table[0]->attrIR.More.ProcAttr.nOff<<" "<<tree->table[0]->attrIR.More.ProcAttr.level<<" ";
            break;
	  
	  case StmLK:
		   cout<<"StmLk ";break;
	  
	  case StmtK:
		  { cout<<"StmtK ";
            switch (tree->kind.stmt)
			{ case IfK:
    		      cout<<"If ";break;
			  case WhileK:
		           cout<<"While ";break;
			  
			  case AssignK:
		           cout<<"Assign ";
				   break;
			  
			  case ReadK:
		           cout<<"Read ";
				   cout<<tree->name[0]<<" ";
				   if(tree->table[0]!=NULL)
					   cout<<tree->table[0]->attrIR.More.VarAttr.off<<" "<<tree->table[0]->attrIR.More.VarAttr.level<<" ";
				   break;
			  
			  case WriteK:
		           cout<<"Write ";break;
			  
			  case CallK:
		           cout<<"Call ";
				   cout<< tree->name[0]<<" ";
				   break;
			  
			  case ReturnK:
		           cout<<"Return ";break;
     
			  default: 
				cout<<"error2! ";
				Error = TRUE;	
			}
          };break;
	  case ExpK: 
		  { cout<<"ExpK ";
		    switch (tree->kind.exp)
			{ case OpK:
    		      { cout<<"Op ";
			        switch(tree->attr.ExpAttr.op)
					{ case EQ:   cout<< " ="; break;
                      case LT:   cout<< " <"; break;    
                      case PLUS: cout<< " +"; break;    
                      case MINUS:cout<< " -"; break;    
					  case TIMES:cout<< " *"; break;    
                      case OVER: cout<< " /"; break;    
                      default: 
						  cout<< "error3!"; break;  
						  Error = TRUE;
					}

					if(tree->attr.ExpAttr.varkind==ArrayMembV)
					{
						cout<< "ArrayMember  ";
						cout<< tree->name[0]<<" ";
					}
                  };break;
			  case ConstK:
				   cout<< "Const ";
					switch(tree->attr.ExpAttr.varkind)
					{
						case IdV:
					    cout<< "Id  ";
						cout<< tree->name[0]<<" ";
						break;
						case FieldMembV:
					   cout<< "FieldMember  ";
					    cout<< tree->name[0]<<" ";
						break;
						case ArrayMembV:
					    cout<< "ArrayMember  ";
						cout<< tree->name[0]<<" ";
						break;
						default: 
							cout<< "var type error!";
							Error = TRUE;
					}
					
					cout<< tree->attr.ExpAttr.val<<" ";
					break;
			  case VariK:
		           cout<< "Vari ";
                   switch(tree->attr.ExpAttr.varkind)
				   {
						case IdV:
					    cout<< "Id  ";
						cout<< tree->name[0]<<" ";
						break;
						case FieldMembV:
					    cout<< "FieldMember  ";
					    cout<< tree->name[0]<<" ";
						break;
						case ArrayMembV:
					   cout<< "ArrayMember  ";
						cout<< tree->name[0]<<" ";
						break;
						default: 
							cout<< "var type error!";
							Error = TRUE;
				   }
				   if(tree->table[0]!=NULL)
					   cout<< tree->table[0]->attrIR.More.VarAttr.off<<" "<<tree->table[0]->attrIR.More.VarAttr.level<<" ";

				   break;
              default: 
				 cout<< "error4!";
				  Error = TRUE;
			}
		  };break;
   default: 
	   cout<< "error5!";
	   Error = TRUE;
   }
   
   cout<<endl;
   
    /* 对语法树结点tree的各子结点递归调用printTree过程 *
	 * 缩进写入列表文件listing						   */
    for (i=0;i<MAXCHILDREN;i++)
         printTree(tree->child[i]);

	/* 对语法树结点tree的兄弟节点递归调用printTree过程 *
	 * 缩进写入列表文件listing						   */ 
	tree = tree->sibling;			
  }

  /* 减量缩进宏,每次退出语法树节点时减量缩进 */
  UNINDENT;							
}


/********************************************************/
/* 函数名  PrintOneLayer								*/
/* 功  能  打印符号表的一层								*/
/* 说  明  有符号表打印函数PrintSymbTable调用	        */
/********************************************************/
void  userfun::PrintOneLayer(int level,SymbTable **scope)
{
  SymbTable  *t= scope[level];
  cout<<"\n-------SymbTable  in level" <<level<<"---------"<<endl;
  while (t!=NULL)
  { /*输出标识符名字*/
	cout<<t->idName<<":  ";
	AttributeIR  *Attrib = &(t->attrIR );
	/*输出标识符的类型信息,过程标识符除外*/
	if (Attrib->idtype!=NULL)  /*过程标识符*/
	   switch(Attrib->idtype->kind)
		{case  intTy :  cout<<"intTy  ";   break;
		 case  charTy:	cout<<"charTy  ";  break;
		 case  arrayTy: cout<<"arrayTy  "; break;
		 case  recordTy:cout<<"recordTy  ";break;
		 default : cout<<"error  type!  "; break;
		}
	/*输出标识符的类别,并根据不同类型输出不同其它属性*/
	switch(Attrib->kind)
	{case  typeKind : 
	      cout<<"typekind  "; break;
	 case  varKind :
		  cout<<"varkind  ";
		  cout<<"level="<<Attrib->More.VarAttr.level<<" ";
		  cout<<"Offset="<< Attrib->More.VarAttr.off<<" ";	      
          switch(Attrib->More.VarAttr.access)
		  { case  dir : cout<<"dir  "; break;
		    case  indir: cout<<"indir  ";break;
			default :cout<<"errorkind  ";  break;
		  }
          break;
	case  procKind:
		  cout<<"funckind   ";
		  cout<<"Level="<<Attrib->More.ProcAttr.level<<"  ";
		  cout<<"Noff="<<Attrib->More.ProcAttr.nOff<<" ";
		  break;
    default :cout<<"error  ";
	}
  cout<<endl;
  t = t->next;
  }
}

/********************************************************/
/* 函数名  PrintSymbTable								*/
/* 功  能  打印生成的符号表								*/
/* 说  明										        */
/********************************************************/
void userfun::PrintSymbTable(SymbTable **scope)

{ /*层数从0开始*/
  int  level=0;
  while (scope[level]!=NULL)
  { userfun::PrintOneLayer(level,scope);
    level++;
  }
}

⌨️ 快捷键说明

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