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

📄 analyze.cpp

📁 完成一个简化的C语言编译程序
💻 CPP
字号:
#include "globals.h"
#include "symtab.h"
#include "analyze.h"

static int location=0;
static int flocation=0;

static void traverse(TreeNode* t, void(* preProc)(TreeNode*),
					 void(*postProc)(TreeNode*))
{
      if(t!=NULL)
	  {
	     preProc(t);
		 {
		      int i;
			  for(i=0;i<MAXCHILDREN;i++)
				    traverse(t->child[i],preProc,postProc);
		 }
		 postProc(t);
		 traverse(t->sibling,preProc,postProc);
	  }
}

static void nullProc(TreeNode * t)
{
    if(t==NULL) return ;
	else return;
}

static void insertNode(TreeNode *t,tableRec* p)
{
	int result=0;
       switch(t->nodekind)
	   {	   
	    case DeclK:
			switch(t->kind.decl)
			{
			case SingleVarK:
				result=st_lookup(t->attr.name,p);
				if(result==-1)
				   st_insert(t->attr.name,t->type,false,t->lineno,location++,p);
				else if(result==0)
				   fprintf(listing,"redefinetion error at line %d : %s ",t->lineno,t->attr.name);
			    else
                   st_insert(t->attr.name,t->type,false,t->lineno,location++,p);
				break;
			case ArrayVarK:
				result=st_lookup(t->attr.name,p);
				if(result==-1)
				{
                       location+=t->array_size-1;
			           st_insert(t->attr.name,t->type,false,t->lineno,location,p);
				       location++;
				}
			    else if(result==0)
				{
				       fprintf(listing,"redefinetion error at line %d : %s ",t->lineno,t->attr.name);
				}
				else
				{
				       location+=t->array_size-1;
			           st_insert(t->attr.name,t->type,false,t->lineno,location,p);
				       location++;
				}
				break;	
			case FuncVarK:
				result=st_lookup(t->attr.name,p);
				if(result==-1)
				  st_insert(t->attr.name,t->type,true,t->lineno,flocation++,p);
				else if(result==0)
				{
    				fprintf(listing,"redefinetion error at line %d : %s ",t->lineno,t->attr.name);
				}
				else
				{
				    st_insert(t->attr.name,t->type,true,t->lineno,flocation++,p);
				}
				break;
			}
	   }
       
}

void buildSymtab(TreeNode* t,tableRec* parent)
{
   
   if(t!=NULL)
   {
	   tableRec* nextParent=parent;
	   insertNode(t,parent);
	   if(t->nodekind==StmtK&&t->kind.stmt==CompoundK)
	   {
		  tableRec* newchild=new tableRec;
		  for(int i=0;i<BUCKETSIZE;i++)
			  newchild->table[i]=NULL;
		  newchild->sibling=NULL;
		  newchild->parent=NULL;
		  newchild->child=NULL;

	      tableRec* lastchild=parent->child;
		  if(lastchild==NULL)
		  {
		     parent->child=newchild;
			 newchild->parent=parent;
		  }
		  else
		  {
		         while(lastchild->sibling!=NULL)
					 lastchild=lastchild->sibling;
				 lastchild->sibling=newchild;
				 newchild->parent=parent;

		  }
		  nextParent=newchild;
		  t->tablep=nextParent;
	   }//if t is compoundK
	   else
	   {
	     t->tablep=parent;
	   }
      for(int i=0;i<MAXCHILDREN;i++)
		  buildSymtab(t->child[i],nextParent);
	  buildSymtab(t->sibling,parent); 
   }
}

static void typeError(TreeNode* t,char* message)
{
  fprintf(listing,"Type error at line %d: %s\n",t->lineno,message);
  Error=TRUE;
}

static void checkNode(TreeNode* t)
{
	int memloc=0;
     switch(t->nodekind)
	 {
	 case ExpK:
		 switch(t->kind.exp)
		 {
		 case OpK:
			 if((t->child[0]->type!=t->child[1]->type))
				 typeError(t,"Op applied to different type");
			 else
			 {
				 if((t->attr.op==EQ)||(t->attr.op==NE)||(t->attr.op==GT)||
					 (t->attr.op==GE)||(t->attr.op==LT)||(t->attr.op==LE)||(t->attr.op==NOT))
					 t->type=Boolean;
				 else
				 {
			     switch(t->child[0]->type)
				 {
				 case Integer:
					 t->type=Integer;
					 break;
				 case Void:
					 t->type=Void;
					 break;
				 case Float:
					 t->type=Float;
					 break;
				 case Char:
					 t->type=Char;
					 break;
				 default:
					 break;
				 }
				 }
			 }
			 break;
	
		 case IdK:
			 if(st_lookup(t->attr.name,t->tablep,t->type,memloc)==-1)
				 typeError(t,"Undeclarared Identifier!");
			 break;
		 case ArrayK:
			 if(st_lookup(t->attr.name,t->tablep,t->type,memloc)==-1)
				 typeError(t,"Undeclarared Identifier!");
			 break;
		 case CallK:
			 if(st_lookup(t->attr.name,t->tablep,t->type,memloc)==-1)
				 typeError(t,"undeclared function call!");
			 break;
		 default:
			 break;

		 }
		 break;
	case StmtK:
		  switch(t->kind.stmt)
		  {
		  case IfK:
			  if(t->child[0]->type!=Boolean)
				  typeError(t->child[0],"if test is not Boolean");
			  break;
		  case AssignK:
			  if(t->child[0]->type!=t->child[1]->type)
				  typeError(t->child[0],"assignment of diffent type");
			  break;
		  case WhileK:
			  if(t->child[0]->type!=Boolean)
				  typeError(t->child[0],"while test is not Boolean");
			  break;
		  default:
			  break;
		  }
		  break;
    default:
		break;


	 }
}

void typeCheck(TreeNode* syntaxTree)
{
	traverse(syntaxTree,nullProc,checkNode);
}

⌨️ 快捷键说明

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