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

📄 analyze.c

📁 一个编译器的实现
💻 C
字号:
#include "globals.h"
#include "symtab.h"
#include "analyze.h"

/* counter for variable memory locations */
static int location = 0;

/* Procedure traverse is a generic recursive 
 * syntax tree traversal routine:
 * it applies preProc in preorder and postProc 
 * in postorder to tree pointed to by t
 */
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);
  }
}

/* nullProc is a do-nothing procedure to 
 * generate preorder-only or postorder-only
 * traversals from traverse
 */
static void nullProc(TreeNode * t)
{ if (t==NULL) return;
  else return;
}

/* Procedure insertNode inserts 
 * identifiers stored in t into 
 * the symbol table 
 */
static void insertNode( TreeNode * t)
{ 
	Attr attr;
	if(t->nodekind==ExpK){
		if(t->kind.exp==IdK){
				if (st_lookup(t->attr.name).memloc == -1&&t->attr.isDecl){         
					attr.memloc = location;
					attr.type = t->type;
					attr.isArr = FALSE;
					st_insert(t->attr.name,t->lineno,attr);
					if(t->type==Integer)
						location+=sizeof(int);
					else if(t->type==Float)
						location+=sizeof(float);
					else location+=sizeof(char);
				}
				else if(st_lookup(t->attr.name).memloc == -1&&!t->attr.isDecl)
					fprintf(listing,"Error at line %d:Identifier %s undefined.\n",t->lineno,t->attr.name);
					
				else if(st_lookup(t->attr.name).memloc != -1&&t->attr.isDecl)
					fprintf(listing,"Error at line %d:Identifier %s redefined.\n",t->lineno,t->attr.name);
				else{
					attr.memloc = 0;
					st_insert(t->attr.name,t->lineno,attr);
				}
		}
		
		if(t->kind.exp==ArrK){
				if (st_lookup(t->attr.name).memloc == -1&&t->attr.isDecl){         
					attr.memloc = location;
					attr.type = t->type;
					attr.isArr = TRUE;
					st_insert(t->attr.name,t->lineno,attr);
					if(t->type==Integer)
						location+=sizeof(int)*(t->child[0]->attr.val.i);
					else if(t->type==Float)
						location+=sizeof(float)*(t->child[0]->attr.val.i);
					else
						location+=sizeof(char)*(t->child[0]->attr.val.i);

				}
				else if(st_lookup(t->attr.name).memloc == -1&&!t->attr.isDecl)
					fprintf(listing,"Error at line %d:Identifier %s undefined.\n",t->lineno,t->attr.name);
					
				else if(st_lookup(t->attr.name).memloc != -1&&t->attr.isDecl)
					fprintf(listing,"Error at line %d:Identifier %s redefined.\n",t->lineno,t->attr.name);
				else{
					attr.memloc = 0;
					st_insert(t->attr.name,t->lineno,attr);
				}
		}
	}
}




/* Function buildSymtab constructs the symbol 
 * table by preorder traversal of the syntax tree
 */
void buildSymtab(TreeNode * syntaxTree)
{ traverse(syntaxTree,insertNode,nullProc);
  if (TraceAnalyze)
  { fprintf(listing,"\nSymbol table:\n\n");
    printSymTab(listing);
  }
}

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

/* Procedure checkNode performs
 * type checking at a single tree node
 */
static void checkNode(TreeNode * t)
{ switch (t->nodekind)
  { case ExpK:
      switch (t->kind.exp)
      { case OpK:
	      switch(t->attr.op)
		  { case PLUS:
			case MINUS:
			case TIMES:
			case OVER:
				if ((t->child[0]->type != Integer)&&(t->child[0]->type != Float) ||
					(t->child[1]->type != Integer)&&(t->child[1]->type != Float))
					typeError(t,"Op applied to wrong kind");
				else if(t->child[0]->type == Integer && t->child[1]->type == Integer)
					t->type = Integer;
				else t->type = Float;
				break;
			case AND:
			case OR:
			    if(t->child[0]->type != Boolean  || t->child[1]->type != Boolean) 
					typeError(t,"Op applied to wrong kind");
				else t->type = Boolean;
				break;
			case NOT:
				if(t->child[0]->type != Boolean )
					typeError(t,"Op applied to wrong kind");
				else t->type = Boolean;
				break;
			case EQ:
			case NE:
			case LT:
			case MT:
			case LE:
			case ME:
				t->type = Boolean;
				break;
			default:
				break;
          }
		  break;
		case AssignK:
		  if(t->child[0]->type!=t->child[1]->type)
				typeError(t,"Types not match in the assignment");
		  break;
		case IdK:
			t->type=st_lookup(t->attr.name).type;
			break;
		case ArrK:
		  if(t->attr.isDecl&&t->child[0]->kind.exp != IK)
			     typeError(t,"Array Subscript is not integer in declaration");
		  else
				t->type=st_lookup(t->attr.name).type;
		  break;
		default:
			break;
	  }
	  break;
    case StmtK:
      switch (t->kind.stmt)
      { case IfK:
          if (t->child[0]->type != Boolean && t->child[0]->type != Integer)
            typeError(t->child[0],"if test is not Boolean");
          break;
	   case WhileK:
		  if (t->child[0]->type != Boolean && t->child[0]->type != Integer)
            typeError(t->child[0],"while test is not Boolean");
          break;
        default:
          break;
      }
      break;
    default:
      break;

  }
}

/* Procedure typeCheck performs type checking 
 * by a postorder syntax tree traversal
 */
void typeCheck(TreeNode * syntaxTree)
{ traverse(syntaxTree,nullProc,checkNode);
}

⌨️ 快捷键说明

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