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

📄 analyze.h

📁 一个简单的C语言子集的编译器,一个简单的C语言子集的编译器
💻 H
字号:

#ifndef ANALYZE_H_
#define ANALYZE_H_

#include "global.h"
#include "symtable.h"

using namespace std;

int InsertSymbolList(TreeNode *p)
{
	int location_old=location;
	if(p==NULL || p->kind!=DECLAR)
		return 0;
	while(p!=NULL)
	{
		st_insert(p->name,GetType(p),GetSymbolType(p),location,p->lineno);
		if(p->childkind.declarK!=FUNC_DECLAR)
		{
			if(p->arraynum>0)
				location+=p->arraynum;
			else location+=1;
		}
		p=p->pNext;
	}
	return location-location_old;
}
void SymbolTraverse(TreeNode *t)
{
	static SymbolRecord * sFunc;
	if (t != NULL)
	{
		if(t->kind==DECLAR && t->childkind.declarK==FUNC_DECLAR)
		{
			location=-3; //skip ret&ofp
			SymbolRecord *s;
			s=sFunc=st_lookup(t->name);
			TreeNode *tempt=t->pChild[0];
			if(tempt!=NULL){
				s=s->pParam=new SymbolRecord;
				while(tempt!=NULL){
					s->name=tempt->name;
					s->type=GetType(tempt);
					if(tempt->childkind.declarK==ARRAY_DECLAR)
						s->symboltype=
						(tempt->arraynum==0?
							ARRAYADDR_SYMBOL:ARRAY_SYMBOL);
					else s->symboltype=VAR_SYMBOL;
					s->lineno=tempt->lineno;
					s->location=location;
					s->nestlevel=1;
					s->pNext=NULL;
					location--;
					tempt=tempt->pNext;
					if(tempt!=NULL){
						SymbolRecord *stemp=s;
						s=s->pNext=new SymbolRecord;
					}
				}
			}
			else s->pParam=NULL;
			sFunc->paramAlloc=-location-3;
			location=0;
		}
		else if(t->kind==CSTMT)
		{
			pCurrentST=t->pBucketList=st_new();
			nestlevel++;
			sFunc->localAlloc+=InsertSymbolList(t->pChild[0]);
		}
		for (int i=0; i < MAXCHILDREN; i++){
			SymbolTraverse(t->pChild[i]);
		}
		if(t->kind==CSTMT) nestlevel--;
		SymbolTraverse(t->pNext);
	}
}
void BuildSymbolTable(TreeNode *t)
{
	globalAlloc=InsertSymbolList(t);
	SymbolTraverse(t);
}

void CheckNode(TreeNode *t)
{
	SymbolRecord *s=st_lookup(t->name);
	switch(t->kind)
	{
	case DECLAR:
		break;
	case OP:
		if(t->pChild[0]->type!=INTEGER_TYPE ||
			t->pChild[1]->type!=INTEGER_TYPE) {
			SyntaxError(string("Operands of '")+t->name+"' not consist",
				t->lineno);
		}
		t->type=INTEGER_TYPE;
		break;
	case RELOP:
		if(t->pChild[0]->type!=INTEGER_TYPE ||
			t->pChild[1]->type!=INTEGER_TYPE) {
			SyntaxError(string("Operands of '")+t->name+"' not consist",
				t->lineno);
		}
		t->type=BOOLEAN_TYPE;
		break;
	case STMT:
		switch(t->childkind.stmtK)
		{
		case IF_STMT:
			if(t->pChild[0]->type!=BOOLEAN_TYPE){
				SyntaxError("The expression of 'if' statement is not type of boolean",
					t->lineno);
			}
			break;
		case WHILE_STMT:
			if(t->pChild[0]->type!=BOOLEAN_TYPE){
				SyntaxError("The expression of 'while' statement is not type of boolean",
					t->lineno);
			}
			break;
		case RETURN_STMT:
			s=st_lookup(FuncName);
			if(s->type==VOID_TYPE){
				if(t->pChild[0]!=NULL){
					SyntaxError(string("Function '")+FuncName+"' do not return a value",
						t->lineno);
				}
			}
			else if(t->pChild[0]==NULL){
				SyntaxError(string("Function '")+FuncName+"' must return a value",
					t->lineno);
			}
			else if(s->symboltype!=FUNC_SYMBOL ||
				t->pChild[0]->type!=s->type) {
				SyntaxError(string("Function '")+FuncName+"' must return a value of type int",
					t->lineno);
			}
			break;
		}
		break;
	case REFER:
		if(s==NULL){
			SyntaxError(string("ID '")+t->name+"' not defined",
				t->lineno);
			t->type=ERROR_TYPE;
			break;
		}
		if(t->pChild[0]!=NULL)
			if(s->symboltype!=ARRAY_SYMBOL &&
				s->symboltype!=ARRAYADDR_SYMBOL){
				SyntaxError(string("ID '")+t->name+"' must be an array",
					t->lineno);
			}
		t->type=s->type;
		break;
	case CALL:
		if(s==NULL){
			SyntaxError(string("ID '")+t->name+"' must be an array",
				t->lineno);
			t->type=ERROR_TYPE;
			break;
		}
		t->type=s->type;
		if(s->symboltype!=FUNC_SYMBOL){
			SyntaxError(string("'")+t->name+"' is not a function",
				t->lineno);
		}
		else{
			TreeNode *ttemp=t->pChild[0];
			s=s->pParam;
			while(s!=NULL && ttemp!=NULL){
				if(ttemp->type!=s->type) break;
				s=s->pNext;
				ttemp=ttemp->pNext;
			}
			if(ttemp!=NULL || s!=NULL){
				SyntaxError(string("Function call '")+t->name+"' has an error in its arguments",
					t->lineno);
			}
		}
		break;
	case PARAM:
		break;
	case CSTMT:
		break;
	case EXP:
		switch(t->childkind.expK)
		{
		case ASSIGN_EXP:
			if(s->type!=t->pChild[1]->type){
				SyntaxError(string("Oprands of '=' not consist"),
					t->lineno);
			}
			if(t->pChild[0]!=NULL)
				if(s->symboltype!=ARRAY_SYMBOL &&
					s->symboltype!=ARRAYADDR_SYMBOL){
					SyntaxError(string("ID '")+t->name+"' must be an array",
						t->lineno);
				}
			t->type=s->type;
			break;
		}
		break;
	case NUM:
		t->type=INTEGER_TYPE;
		break;	
	}
}
void CheckTraverse( TreeNode * t)
{ 
	if (t != NULL)
	{
		if(t->kind==DECLAR && t->childkind.declarK==FUNC_DECLAR){
			FuncName=t->name;
			location=0;
		}
		else if(t->kind==CSTMT) st_addon(t->pBucketList);
		for (int i=0; i<MAXCHILDREN; i++)
			CheckTraverse(t->pChild[i]);
		if(t->kind==DECLAR && t->childkind.declarK==FUNC_DECLAR){
			FuncName="";
		}
		else if(t->kind==CSTMT) st_takeoff();
		CheckNode(t);
		CheckTraverse(t->pNext);
	}
}
void TypeCheck(TreeNode *t)
{
	CheckTraverse(t);
}
#endif

⌨️ 快捷键说明

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