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

📄 syntax.c

📁 用C++编写的一个编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <string.h>
#include "syntax.h"
#include "utility.h"

struct _stmtnode *newDeclStmt(
	struct _supertype	*spec,
	struct _sym		*declist,
	char			*filename,
	int				lineno
)
{
	StmtNode *stmt = dmalloc(sizeof(StmtNode), true);

	stmt->stmtype = stmt_decl;
	stmt->ss = NULL;
	stmt->s1 = NULL;
	stmt->s2 = NULL;
	stmt->labelno = UNKNOWN;

	stmt->declist = declist;
	stmt->spec  = spec;

	stmt->filename =filename;
	stmt->lineno =lineno;

	return stmt;
}

struct _stmtnode *newCalcStmt(
	int				stmtype,
	struct _expnode	*exp,
	struct _stmtnode *ss,
	struct _stmtnode *s1,
	struct _stmtnode *s2,
	char			*filename,
	int				lineno
)
{
	StmtNode *stmt = dmalloc(sizeof(StmtNode), true);
	stmt->stmtype = stmtype;
	stmt->next = NULL;
	stmt->exp = exp;
	stmt->ss = ss;
	stmt->s1 = s1;
	stmt->s2 = s2;
	stmt->labelno = UNKNOWN;

	stmt->declist = NULL;
	stmt->spec  = NULL;

	stmt->filename =filename;
	stmt->lineno =lineno;
	if(stmtype == stmt_switch)
		preswitch(stmt);
	else if(stmtype == stmt_return)
	{
		if(checkTypeSame(current_func->datatype->subtype, 
			exp->datatype)>1)
			generror(ERR_TYPE_CONFLICT, "return value and the declaration");
	}
	return stmt;
}
void preswitch(struct _stmtnode *stmt)
{
	StmtNode *curcase = NULL, *curstmt = NULL;
	StmtNode *onecase=stmt->ss;// *defaultstmt = NULL;
	stmt->s2=NULL;
	if(onecase->stmtype == stmt_compound)
		onecase = onecase->ss;
	while(onecase)
	{
		if(onecase->stmtype == stmt_case)
		{
			if(curcase == NULL)
				stmt->s1 = curcase = onecase;
			else 
				curcase = curcase->next = onecase;

			onecase->ss->next = onecase->next;
			onecase = onecase->ss;
		}
		else if(onecase->stmtype == stmt_default)
		{
			if(stmt->s2)
				generror(ERR_DEFAULT_MORE, NULL);
			else
				stmt->s2 = onecase;
			onecase->ss->next = onecase->next;
			onecase = onecase->ss;
		}
		else 
		{
			if(curstmt == NULL)
				stmt->ss = curstmt = onecase;
			else 
				curstmt = curstmt->next = onecase;
			onecase = onecase->next;
		}
	}
	if(curcase)
		curcase->next = NULL;
	if(curstmt)
		curstmt->next = NULL;
	return;
}
struct _expnode *newInitExp(
	int exptype
)
{
//	HashNode *hashnode= NULL;
	static Type defaulttype = {0, UNKNOWN,0};

	ExpNode *exp = dmalloc(sizeof(ExpNode),true);
	
	memset(exp, 0, sizeof(exp));
	exp->exptype = exptype;
	//to avoid the null pointer in type analysis
	exp->datatype = &defaulttype;
	return exp;
}

struct _expnode *evaluate_void_exp()
{
	ExpNode  *res = newInitExp(exp_void);
	res->datatype = newType(NULL, bt_void, NULL);
	return res;
}

struct _expnode *evaluate_brace_exp(
	struct _expnode *exp
)
{
	ExpNode  *res = newInitExp(exp_brace);
	res->val.opd[0]= exp;
	return res;
}

//assume every const pointer is immediate addr mode 
struct _expnode	*evaluate_const_exp(
	int bt,
	void *value 
)
{
	ExpNode  *res = newInitExp(exp_const);
	res->datatype =newType(NULL, bt, 0);
	
	if(bt == bt_pointer)
	{
		res->datatype->subtype = newType(NULL, bt_char, 0);
		res->val.addr.base = "string"; //
		res->val.addr.offset = add_const(value);
	}
	else if(bt == bt_long)
	{
		res->val.i = *((long*)value);
	}
	else if(bt == bt_unsignedlong)
	{
		res->val.u = *((unsigned long*)value);
	}
	else if(bt == bt_double)
	{
		res->val.f = *((double*)value);
	}
	else 
	{
		generror(ERR_UNKNOWN_CONST, NULL);
	}
	return res;
}

struct _expnode	*evaluate_id_exp(
	char *name 
)
{
	HashNode *hashnode = lookup_node(symtab, SYMTABSIZE, name);
	ExpNode  *res = newInitExp(exp_vref);
	Symbol *var;
	
	if(hashnode)
	{
		var = hashnode->val;
		if(var->storage_class == sc_label)
		{
			generror(ERR_TYPE_CONFLICT, name);
			return res;
		}
		
		var->refcount++;
		if(var->const_flag)
		{
			//in C named const only enum, function name
			//wait for named const extension
			 //modify
			res->datatype = var->datatype;
			switch(var->datatype->basic_type)
			{
			case bt_funcptr:
				res->val.addr.base = var->name;
				res->exptype = exp_label;
				break;
			case bt_long://enum will be treated as long	
				res->exptype = exp_const;
				res->val.i = var->value.i;
				break;
			default://name of array
				res->exptype = exp_aref;
				if(var->storage_class == sc_auto)
				{
					res->val.addr.base =NULL;
					res->val.addr.offset = var->value.offset;
				}
				else 
				{
					res->val.addr.base = var->value.linkname;
					res->val.addr.offset = 0;
				}
			}
		}
		else
		{
			res->datatype = var->datatype;
			if(var->storage_class == sc_auto)
				res->val.addr.offset = var->value.offset;
			else
				res->val.addr.base = var->value.linkname;
		}
	}
	else 
		generror(ERR_UNKNOWN_ID, name);
	return res;
}
struct _expnode	*evaluate_label_exp(
	char *name 
)
{
	ExpNode  *res = newInitExp(exp_label);
	res->val.label = add_named_label(name, UNKNOWN);
	return res;
}

struct _expnode	*evaluate_call_exp(
	struct _expnode	*func,
	struct _expnode *arglist
)
{
	Symbol *para;
	ExpNode  *res = newInitExp(exp_call), *next, *arg, *topush = NULL;
	
	if(func->datatype->basic_type == bt_funcptr)
	{
		para= func->datatype->arglist;
		arg = arglist;
		while(para&&arg)
		{
			if(checkTypeSame(para->datatype, arg->datatype)>1)
			{
				generror(ERR_ARG_NOTMATCH, para->name);
				break; 
			}
			next = arg->next;//reverse the order
			arg ->next =topush;
			topush = arg;
			arg = next;
			if(para->datatype->basic_type != bt_ellipsis)
				para = para->next;
		}
		if(arg)
			generror(ERR_FEW_ARG, NULL);// no name in exp, weak debug ability
		else 
		{
			res->val.opd[0] = func;
			res->val.opd[1] = topush;
			res->datatype = func->datatype->subtype;
		}
	}
	else 
		generror(ERR_EXPECT_FUNC, NULL);
	return res;
}

struct _expnode	*evaluate_member_exp(
	int exptype,
	struct _expnode	*var,
	char *memname
)
{
	Type *tmptype;
	HashNode *hashnode=NULL;
	Symbol *mem;
	ExpNode *res =newInitExp(exptype);
	
	
	tmptype = var->datatype;
	if(exptype==exp_ptomem)
	{
		if(tmptype->basic_type == bt_pointer)
			tmptype= tmptype->subtype;
		else 
		{
			generror(ERR_EXPECT_POINTER, NULL);
			return res;
		}
	}
	
	if(tmptype->basic_type != bt_struct
		&& tmptype->basic_type != bt_union)
	{
		generror(ERR_EXPECT_STRUCT, NULL);
		return res;
	}
	
	if(tmptype->memlist)
		hashnode = lookup_node(tmptype->memlist, MEMTABSIZE, memname);

	if(hashnode)
	{
		mem = hashnode ->val;
		res->datatype = mem->datatype;
		res->val.opd[0] = var;
		res->val.opd[1] = evaluate_const_exp(bt_long, &(mem->value.offset));
	}
	else
	{
		generror(ERR_NOT_MEMBER, memname);
	}
	return res;
}

struct _expnode	*evaluate_array_exp(
	struct _expnode	*array,
	struct _expnode *index
)
{
	ExpNode *res =newInitExp(exp_array), *tmpexp;
	int size = array->datatype->subtype->size;
	//to ensure the next step of analyzing
	res->datatype = array->datatype->subtype;
	
	if(array->datatype->basic_type != bt_pointer)
	{
		generror(ERR_EXPECT_POINTER,"on the left");
		return res;
	}
	
	if(!(is_integer(index->datatype->basic_type)))
	{
		generror(ERR_EXPECT_INT, "on the right");
		return res;
	}
	
	if(array->datatype->subtype->size == UNKNOWN)
	{
		generror(ERR_UNKNOWN_SIZE, "member of array");
		return res;
	}
	else if(array->datatype->subtype->size == 0)
	{
		generror(ERR_ZERO_SIZE, "member of array");
		return res;
	}

	if(array->exptype==exp_const && index->exptype == exp_const)
	{
		res->datatype = array->datatype->subtype;
		if(res->datatype->array_vol == 0)
			res->exptype = exp_vref;

		res->val.addr.offset=index->val.i*size
			+array->val.addr.offset;
		res->val.addr.base = array->val.addr.base;
	}
	else
	{
		res->val.opd[0]=array;
		if(size>1)
		{
			tmpexp = evaluate_const_exp(bt_long, &(size));
			res->val.opd[1]=evaluate_binary_exp(exp_mul, tmpexp, index);
		}
		else res->val.opd[1]=index;
	}
	return res;
}
		
struct _expnode	*evaluate_typecast_exp(
	struct _datatype *target_type,
	struct _expnode *origin
)
{
	//from float to int need to call extra function
	//no support for this moment
	//??????????????
	//wait for me
	ExpNode *res ;
	res = origin;
	res->datatype = target_type;
	return res;
}

struct _expnode	*evaluate_sizeof_exp(
	struct _datatype *type,
	struct _expnode *exp
)
{
	ExpNode *res = newInitExp(exp_const);
	res->datatype =newType(NULL, bt_long, 0);
	if(type)
	{
		res->val.i = type->size;
	}
	else 
	{
		res->val.i = exp->datatype->size;
	}
	return res;
}

//increase or dcrease
struct _expnode	*evaluate_indecr_exp(
	int exptype, //if it is minus , means the opd is on the left , a little trick
	struct _expnode *exp
)
{
	int abstype = exptype>0?exptype:-exptype;
	ExpNode *res = newInitExp(abstype);
	res->datatype = exp->datatype;
	
	if(!is_variable(exp->exptype))
	{
		generror(ERR_EXPECT_VAR, NULL);
		return res;
	}
	if(exptype<0)
		res->val.opd[0]=exp;
	else 
		res->val.opd[1]=exp;
	return res;
}

struct _expnode *evaluate_unary_exp(
	int exptype,
	struct _expnode *exp
)
{
	ExpNode *res = newInitExp(exptype);
	
	switch(exptype)
	{
	case exp_ptr:
		if(!is_variable(exp->exptype))
		{
			generror(ERR_EXPECT_VAR, NULL);
			break;
		}
		res->datatype= newType(NULL, bt_pointer, NULL);
		compoundType(res->datatype, exp->datatype);
		res->val.opd[1] = exp;
		break;
		
	case exp_val:
		if(exp->datatype->basic_type != bt_pointer)
			generror(ERR_EXPECT_POINTER, NULL);
		res->datatype = exp->datatype->subtype;
		res->val.opd[1] = exp;
		break;
		
	case exp_uplus:
		res=exp;
		break;
		
	case exp_uminus:
		if(!is_real(exp->datatype->basic_type))
		{	

⌨️ 快捷键说明

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