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

📄 symtab.h

📁 C编译器,在VC6.0环境下开发
💻 H
字号:
#ifndef	_C_SYMTAB_H_
#define	_C_SYMTAB_H_

#include	"Common.h"

// for string tab
#include	"GBStrTab.h"

// the first three char must be this
#define		_GLOBE_VAL_NAME		"mm_%s"

// struct _specifier_
#define		SPEC_UNKNOW		0	// only for function return value

	// noun
#define		SPEC_VOID		1	// only for function return value
#define		SPEC_CHAR		2
#define		SPEC_INT		3
#define		SPEC_FLOAT		4	// can be ingored in gen code
#define		SPEC_DOUBLE		5	// can be ingored in gen code
#define		SPEC_LABEL		6

	// sclass
#define		SPEC_AUTO		1
#define		SPEC_REGISTER	2
#define		SPEC_CONSTANT	3
#define		SPEC_TYPEDEF	4

#define		_MAIN_FUNC_NAME		"main"

// const value
typedef union _const_value_
{
	char			v_c;
	unsigned char	v_uc;
	int				v_i;
	unsigned int	v_ui;
	float			f;		// never used
	double			lf;		// never used
	const_string	*v_str; // pointer to the string in table
} const_value;

typedef	struct _specifier_
{
	unsigned	noun;		// CHAR INT FLOAT DOUBLE STRING LABEL
	unsigned	sclass;		// REGISTER AUTO CONSTANT TYPEDEF
	unsigned	is_long;	// 1 = long , 0 = short , can be ingore in code gen
	unsigned	is_unsigned;// 1 = unsigned, 0 = signed
	unsigned	is_static;	// 1 = static keyword found in declaration
	unsigned	is_extern;	// 1 = extern keyword found in declaration

	const_value	v;			// const value
} specifier;

typedef struct _symbol_
{
	char		name[NAME_LEN];		// Input name of symbol
	char		rname[LABEL_LEN];	// Output name of symbol in .asm

	unsigned	is_symtab;			// 1 == symtab ; means is tab head
	unsigned	is_function;		// 1 == the symbol is function
	unsigned	is_declaration;		// 1 == the function is only declaration, not defined
									//  or the label only declaration
	unsigned	is_array;			// 1 == the symbol is array
	unsigned	is_argument;		// 1 == the symbol is argument in function declaration
	unsigned	is_assign;			// 1 == the symbol is var and be assigned
	unsigned	is_cl;				// 1 == the symbol is const value, not var
	unsigned	is_rvalue;			// 1 == the symbol is a rvalue
	unsigned	is_pushed;			// 1 == the symbol has push itself
	int			num_ele;			// if is array use this field to show element number
	specifier	basetype;			// if func, is fun's return value
	int			offset;				// Offset of variable , if var

	struct _symbol_ *next;			// Next symbol in the table
									// if is args, use this to link next args symbol

	struct _symbol_ *args;			// if the symbol stand for function
									// use this to link args
									// if the symbol is not function, it has initalizer
									// use this pointer reference to initalizer
									// if the symbol is array in expression, use this
									// to refer to index expression

	struct _symbol_ *lchild,*rchild;// 二叉树组织
} symbol;

#define		NOUN			basetype.noun
#define		SCLASS			basetype.sclass
#define		IS_LONG			basetype.is_long
#define		IS_UNSIGNED		basetype.is_unsigned
#define		IS_STATIC		basetype.is_static
#define		IS_EXTERN		basetype.is_extern

#define		V_C				basetype.v.v_c
#define		V_UC			basetype.v.v_uc
#define		V_I				basetype.v.v_i
#define		V_UI			basetype.v.v_ui
#define		V_F				basetype.v.f
#define		V_LF			basetype.v.lf
#define		V_STR			basetype.v.v_str

#define		IS_SYMTAB(x)	( (x)->is_symtab )
#define		IS_FUNCTION(x)	( (x)->is_function )
#define		IS_FUNC_DECL(x)	( IS_FUNCTION(x) && (x)->is_declaration )
#define		IS_ARGUMENT(x)	( (x)->is_argument )
#define		IS_ASSIGN(x)	( (x)->is_assign )
#define		IS_ARRAY(x)		( (x)->is_array ) 
#define		IS_LABEL(x)		( (x)->NOUN == SPEC_LABEL )
#define		IS_CL(x)		( (x)->is_cl )
#define		IS_RVALUE(x)	( (x)->is_rvalue )
#define		IS_PUSHED(x)	( (x)->is_pushed )
#define		IS_LAB_DECL(x)	( (x)->NOUN == SPEC_LABEL && (x)->is_declaration )

#define		IS_LOCAL_VAR(x)	( !IS_FUNCTION(x)	&& \
							  !IS_SYMTAB(x)		&& \
							  !IS_ARGUMENT(x)	&& \
							  !IS_TYPEDEF(x)	&& \
							  !IS_CL(x)			&& \
							  !IS_RVALUE(x)		&& \
							  !IS_LABEL(x) )

#define		IS_VAR(x)		( !IS_FUNCTION(x)	&& \
							  !IS_SYMTAB(x)		&& \
							  !IS_TYPEDEF(x)	&& \
							  !IS_CL(x)			&& \
							  !IS_RVALUE(x)		&& \
							  !IS_LABEL(x) )

// tmp array symbol has index expression
#define		IS_ARRAY_HAS_INDEX(x)	( IS_ARRAY(x) && (x)->args )

#define		IS_LVALUE(x)	( ( IS_VAR(x) && !IS_ARRAY(x) )	|| \
								IS_ARRAY_HAS_INDEX(x) )

#define		IS_GLOBE(x)		( !strncmp((x)->rname,_GLOBE_VAL_NAME, 3) )

#define		IS_AUTO(x)		( (x)->SCLASS == SPEC_AUTO )
#define		IS_REGISTER(x)	( (x)->SCLASS == SPEC_REGISTER )
#define		IS_CONSTANT(x)	( (x)->SCLASS == SPEC_CONSTANT )
#define		IS_TYPEDEF(x)	( (x)->SCLASS == SPEC_TYPEDEF )

#define		IS_MAIN_FUNC(x)	( IS_FUNCTION(x)	&&	\
							  !strcmp(_MAIN_FUNC_NAME, (x)->name) )

#define		_CL_SINGLE_OPERATION(x, o)	\
		switch((x)->NOUN)				\
		{								\
		case	SPEC_CHAR:				\
			(x)->V_C = (o((x)->V_C));	\
			break;						\
		case	SPEC_INT:				\
			(x)->V_I = (o((x)->V_I));	\
			break;						\
		case	SPEC_DOUBLE:			\
			(x)->V_LF = (o((x)->V_LF));	\
			break;						\
		case	SPEC_FLOAT:				\
			(x)->V_F = (o((x)->V_F));	\
			break;						\
		default:						\
			yyerror("can't do cl operator");	\
			user_exit(1);						\
		}

#define		_CL_SINGLE_BIT_OPERATION(x, o)	\
		switch((x)->NOUN)				\
		{								\
		case	SPEC_CHAR:				\
			(x)->V_C = (o((x)->V_C));	\
			break;						\
		case	SPEC_INT:				\
			(x)->V_I = (o((x)->V_I));	\
			break;						\
		default:						\
			yyerror("can't do cl bit operator");	\
			user_exit(1);							\
		}

#define		_CL_DOUBLE_OPERATION(x,y,o)			\
		switch((x)->NOUN)						\
		{										\
		case	SPEC_CHAR:						\
			(x)->V_C = ((x)->V_C o ((y)->V_C));	\
			break;								\
		case	SPEC_INT:						\
			(x)->V_I = ((x)->V_I o ((y)->V_I));	\
			break;								\
		case	SPEC_DOUBLE:					\
			(x)->V_LF = ((x)->V_LF o ((y)->V_LF));	\
			break;								\
		case	SPEC_FLOAT:						\
			(x)->V_F = ((x)->V_F o ((y)->V_F));	\
			break;								\
		default:								\
			yyerror("can't do cl operator");	\
			user_exit(1);						\
		}

#define		_CL_DOUBLE_BIT_OPERATION(x,y,o)			\
		switch((x)->NOUN)						\
		{										\
		case	SPEC_CHAR:						\
			(x)->V_C = ((x)->V_C o ((y)->V_C));	\
			break;								\
		case	SPEC_INT:						\
			(x)->V_I = ((x)->V_I o ((y)->V_I));	\
			break;								\
		default:								\
			yyerror("can't do cl bit operator");	\
			user_exit(1);							\
		}

#define		CHECK_BIT_OP_TYPE(x)	\
				if ( (x)->NOUN == SPEC_DOUBLE || (x)->NOUN == SPEC_FLOAT )	\
				{															\
					yyerror("illegal on operands of type 'float ' or 'double'");	\
					user_exit(1);													\
				}

// globe value

// for symtab
symbol	*new_symbol();
void	del_symbol(symbol *p);
void	remove_symtab(symbol *head);
// delete a symtab except function args
void	remove_symtab_except_args(symbol *head);
// delete a function symtab include function args
void	remove_function_symtab_include_args(symbol *func);
// remove the linked symbol
// eg. not use declaration list
void	remove_symbol_list(symbol *p);
symbol	*create_symtab(const char *name);
// return NULL means not found
symbol	*search_symbol_in_symtab(symbol *tab, char *name);
// return NULL means not found
symbol	*search_symbol_to_top(char *name);
int		add_symbol_to_symtab(symbol *tab, symbol *p);
// add symbol to current symtab
// return 0 means ok, otherwise return 1 means already exist
int		add_symbol_to_current_symtab(symbol *p);
// add symbol list to symtab, use ->next to link
int		add_symbol_list_to_current_symtab(symbol *p);
// link two symbol list to one list
// link p2 at ->next of p1's last symbol
symbol	*link_symbol_list(symbol *p1, symbol *p2);
// union the specifier symbol
// change p1
void	union_specifier_symbol(symbol *p1, symbol *p2);
// check declarator
void	check_var_declarator(symbol *decl);
// union the specifier to declarator
// at same time check declarator , not be void
void	unoin_specifier_to_declarator(symbol *spec, symbol *decl);
// union the specifier to declarator list
void	unoin_specifier_to_declarator_list(symbol *spec, symbol *decl_list);
// new symbol from a typedef symbol
symbol	*new_symbol_from_typedef(symbol *def_sym);
// search for typedef name
// return not NULL means found
symbol	*find_symtab_typedef(char *name);
// create compound symtab , and push it
symbol	*new_compound_symtab();
// pop a compound symtab, and destory it
void	del_compound_symtab();
// check args type in function call
int		check_args_type_in_function_call(symbol *p1,symbol *p2);
// check args type
int		check_args_type(symbol *p1,symbol *p2);
// check the function parameter and return type
int		check_func_args_type(symbol *func,symbol *decl);
// add function definition to function tab
// if declaration if exist, check parameter type, 
// and overwrite parameter's name
// actual delete the declaration list
// and add itself to function symtab
symbol	*add_function_def_to_functab(symbol *func);
// only declaration
// add or only check parameter type
// not overwrite parameter's type
void	add_function_decl_to_functab(symbol *decl);
// check function return value
// array can't be return value
void	check_function_retval(symbol *func);
// get symbol 's size
int		get_symbol_size(symbol *p);
// set local value or args rname
void	set_local_or_args_rname(symbol *p);
// get local value or args asm attrib "word ptr [bp-%d]" or "byte ptr [bp-%d]"
// or "word ptr [bp+%d]" or "byte ptr [bp+%d]"
char	*get_asm_attri(symbol *p);
// assign parameters rname
void	assign_parameters_rname(symbol *args_list);
// assign symbol a unused name
void	assign_symbol_unusedname(symbol *p);
// set function 's offset to sub sp, offset
void	set_func_offset(symbol *func);
// change cl value if necessary
void	cast_cl_type(symbol *c1, symbol *c2);
// get symbol value as int
int		get_sym_value(symbol *c);
// clone a symbol with symbol
symbol	*clone_symbol(symbol *p);
// calcu function argument size
int		get_function_args_size(symbol *func);
// create goto label symtab 
void	create_goto_label_symtab();
// destory goto label symtab
void	destory_goto_label_symtab();
// found the goto label in goto label symtab
symbol	*search_goto_label(char *name);
// add goto label to goto label symtab
void	add_goto_label(symbol *lb);

void	InitSymTab();
void	DestorySymTab();

//  dump symbol for debug
void	dump_symbol(symbol *p);
void	dump_function(symbol *func);
void	dump_current_symtab();
void	dump_function_symtab();

#endif


⌨️ 快捷键说明

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