fincparser.c

来自「FinC编译器源代码」· C语言 代码 · 共 2,486 行 · 第 1/4 页

C
2,486
字号
			match_token(token, self->lex, FinCTokenType_Right_Brace);			match_token(token, self->lex, FinCTokenType_Semicolon);			finc_node_add(type, id);			unref(id);			return type;		}		else		{			finc_lang_error_line(self->lex, "Parser Error:must use a interger in an array declaration.");			finc_context_error_inc(g_finc_context);			return NULL;		}		break;	case FinCTokenType_Comma:/*',', it's a variable_list declaration.*/		finc_node_add(type, id);		unref(id);		id = proc_identifier(self);		next_token(token, self->lex);		if ( token == FinCTokenType_Assign )		{			assign = proc_assign_expr(self);			finc_node_add (id, assign);			unref(assign);			next_token(token, self->lex);		}		finc_node_add(type, id);		unref(id);		while ( token == FinCTokenType_Comma )		{			id = proc_identifier(self);			next_token(token, self->lex);			if ( token == FinCTokenType_Assign )			{				assign = proc_assign_expr(self);				finc_node_add (id, assign);				unref(assign);				next_token(token, self->lex);			}			finc_node_add(type, id);			unref(id);		}		check_token(token, self->lex, FinCTokenType_Semicolon);		return type;		break;	case FinCTokenType_Assign:/*'=', it's a variable with assign declaration.*/		assign = proc_assign_expr(self);		finc_node_add (id, assign);		unref(assign);		finc_node_add (type, id);		unref(id);		next_token(token, self->lex);		while ( token == FinCTokenType_Comma )		{			id = proc_identifier(self);			next_token(token, self->lex);			if ( token == FinCTokenType_Assign )			{				assign = proc_assign_expr(self);				finc_node_add (id, assign);				unref(assign);				next_token(token, self->lex);			}			finc_node_add(type, id);			unref(id);		}		check_token(token, self->lex, FinCTokenType_Semicolon);		return type;		break;	case FinCTokenType_Semicolon:/*';', it's a variable declaration.*/		finc_node_add(type, id);		unref(id);		return type;		break;	default:		finc_lang_error_line(self->lex, "Parser Error:variable declaration error.");		finc_context_error_inc(g_finc_context);		unref(type);		unref(id);		return NULL;		break;	}}/*decl_package -> PACKAGE V_STRING '{' decl_package_func_list '}' ';'*/static FinCNode* proc_package(FinCParser* self){	FinCTokenType token;	FinCNode* pkg;	match_token(token, self->lex, FinCTokenType_Package);	match_token(token, self->lex, FinCTokenType_String);	make_pkg_begin(self, string_get_str(self->lex->last_str));	match_token(token, self->lex, FinCTokenType_Left_Curly);	next_token(token, self->lex);	if (token != FinCTokenType_Right_Curly)	{		finc_token_replay(self->lex);		proc_package_func(self);		match_token(token, self->lex, FinCTokenType_Right_Curly);	}	match_token(token, self->lex, FinCTokenType_Semicolon);	pkg = make_pkg_finish(self);	#ifdef USING_PACKAGE	finc_lang_proc_pkg(self->lang_env, pkg);#endif	unref(pkg);	return NULL;}/*decl_package_func_list -> decl_package_func	| decl_package_func_list decl_package_funcdecl_package_func -> type identifier '(' decl_param_type_list ')' ';'*/static FinCNode* proc_package_func(FinCParser* self){	FinCTokenType token;	FinCNode* type;	FinCNode* id;	FinCNode* node_pkg;	next_token(token, self->lex);	while ( is_type(token) )	{		finc_token_replay(self->lex);		type = proc_type(self);		id = proc_identifier(self);				make_pkg_func_begin(self, type, id);		match_token(token, self->lex, FinCTokenType_Left_Paren);		next_token(token, self->lex);		if ( token != FinCTokenType_Right_Paren )		{			finc_token_replay(self->lex);			proc_param_list(self);			match_token(token, self->lex, FinCTokenType_Right_Paren);		}		match_token(token, self->lex, FinCTokenType_Semicolon);		node_pkg = make_pkg_func_finish(self);		finc_node_add (self->current_pkg, node_pkg);		unref(node_pkg);		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return NULL;/*support for pkg.*/}/*decl_struct -> STRUCT identifier '{' decl_field_list '}' ';'*/static FinCNode* proc_struct(FinCParser* self){	FinCTokenType token;	FinCNode* id;	FinCNode* node_struct;	match_token(token, self->lex, FinCTokenType_Struct);	id = proc_identifier(self);	if (id) 	{		self->current_struct = finc_node_new_func ("struct");		finc_node_add (self->current_struct, id);		unref (id);	}	else return NULL;	match_token(token, self->lex, FinCTokenType_Left_Curly);	next_token(token, self->lex);	if ( token != FinCTokenType_Right_Curly )	{		finc_token_replay(self->lex);		proc_field_list(self);	}	match_token(token, self->lex, FinCTokenType_Right_Curly);	match_token(token, self->lex, FinCTokenType_Semicolon);	node_struct = self->current_struct;	self->current_struct = NULL;	finc_lang_proc_struct(self->lang_env, node_struct);	unref(node_struct);	return NULL;}/*decl_field_list -> decl_field_declarator	| decl_field_list decl_field_declarator*/static FinCNode* proc_field_list(FinCParser* self){	FinCTokenType token;	FinCNode* field;	next_token(token, self->lex);	while ( (token!= FinCTokenType_Right_Curly) && (is_type(token)) )	{		finc_token_replay(self->lex);		field = proc_field(self);		finc_node_add (self->current_struct, field);		unref(field);		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return NULL;}/*decl_field_declarator -> type struct_declarator_list ';'	| type identifier '[' V_INT ']'	| type identifier '[' ']'struct_declarator_list -> struct_declarator_list ',' struct_declarator	| struct_declaratorstruct_declarator -> identifier*/static FinCNode* proc_field(FinCParser* self){	FinCTokenType token;	FinCNode* type;	FinCNode* id;	FinCNode* assign;	Bool b_static, b_unsigned;	b_static = FALSE;	b_unsigned = FALSE;	type = proc_type(self);	id = proc_identifier(self); /* process id. */	next_token(token, self->lex);	switch ( token )	{	case FinCTokenType_Left_Brace:/*'[', it's a array variable declaration.*/		next_token(token, self->lex);		if (token == FinCTokenType_Right_Brace)/*it's a dynamic array declaration.*/		{			type->type->array_type = FinCArrayType_Dynamic;			type->type->array_size = 0;			match_token(token, self->lex, FinCTokenType_Semicolon);			finc_node_add(type, id);			unref(id);			return type;		}		else if (token == FinCTokenType_Int)/*it's a fixed array declaration.*/		{			type->type->array_type = FinCArrayType_Fixed;			type->type->array_size = self->lex->last_long;			match_token(token, self->lex, FinCTokenType_Right_Brace);			match_token(token, self->lex, FinCTokenType_Semicolon);			finc_node_add(type, id);			unref(id);			return type;		}		else		{			finc_lang_error_line(self->lex, "Parser Error:must use a interger in an array declaration.");			finc_context_error_inc(g_finc_context);			return NULL;		}		break;	case FinCTokenType_Comma:/*',', it's a variable_list declaration.*/		finc_node_add(type, id);		unref(id);		id = proc_identifier(self);		next_token(token, self->lex);		if ( token == FinCTokenType_Assign )		{			assign = proc_assign_expr(self);			finc_node_add (id, assign);			unref(assign);			next_token(token, self->lex);		}		finc_node_add(type, id);		unref(id);		while ( token == FinCTokenType_Comma )		{			id = proc_identifier(self);			next_token(token, self->lex);			if ( token == FinCTokenType_Assign )			{				assign = proc_assign_expr(self);				finc_node_add (id, assign);				unref(assign);				next_token(token, self->lex);			}			finc_node_add(type, id);			unref(id);		}		check_token(token, self->lex, FinCTokenType_Semicolon);		return type;		break;	case FinCTokenType_Semicolon:/*';', it's a variable declaration.*/		finc_node_add(type, id);		unref(id);		return type;		break;	default:		finc_lang_error_line(self->lex, "Parser Error:variable declaration error.");		finc_context_error_inc(g_finc_context);		unref(type);		unref(id);		return NULL;		break;	}}#ifdef USING_FILE/**decl_import -> IMPORT V_STRING ';'*/static FinCNode* proc_import(FinCParser* self){	FinCTokenType token;	FinCNode* string;	FinCNode* import;	match_token(token, self->lex, FinCTokenType_Import);	match_token(token, self->lex, FinCTokenType_String);	/*perform at last.*/	string = finc_node_new_string(string_get_str(self->lex->last_str));	match_token(token, self->lex, FinCTokenType_Semicolon);	import = make_efunc1 ("import", string);	finc_lang_proc_import(self->lang_env, import);	unref(import);	return NULL;}#endif/**decl_param_type_list -> decl_param_list	| decl_param_list ',' OPT_PARAMdecl_param_list -> empty	| decl_param	| decl_param_list ',' decl_paramdecl_param -> type identifier	| type identifier '[' ']'	| type identifier '[' V_INT ']'*/static FinCNode* proc_param_list(FinCParser* self){	FinCTokenType token;	FinCNode* type;	FinCNode* id;	type = proc_type(self);	id = proc_identifier(self);	next_token(token, self->lex);	if (token == FinCTokenType_Left_Brace)/*if it's a array param.*/	{		next_token(token, self->lex);		if (token == FinCTokenType_Right_Brace)		{			type->type->array_type = FinCArrayType_Dynamic;			type->type->array_size = 0;		}		else		{			type->type->array_type = FinCArrayType_Fixed;			type->type->array_size = (int)self->lex->last_double;		}		next_token(token, self->lex);	}	make_func_add_param(self, type, id);	while (token == FinCTokenType_Comma)	{		type = proc_type(self);		id = proc_identifier(self);		next_token(token, self->lex);		if (token == FinCTokenType_Left_Brace)/*if it's a array param.*/		{			next_token(token, self->lex);			if (token == FinCTokenType_Right_Brace)			{				type->type->array_type = FinCArrayType_Dynamic;				type->type->array_size = 0;			}			else			{				type->type->array_type = FinCArrayType_Fixed;				type->type->array_size = (int)self->lex->last_double;			}			next_token(token, self->lex);		}		make_func_add_param(self, type, id);	}	finc_token_replay(self->lex);	return NULL;}#ifdef USING_OO/*decl_class -> CLASS identifier [:] [public] [class] class_scope '{' decl_class_member_list '}' [;]*/static FinCNode* proc_class(FinCParser* self){	FinCTokenType token;	FinCNode* id;	match_token(token, self->lex, FinCTokenType_Class);	id = proc_identifier(self);	if ( id )	{	}	else return NULL;	next_token(token, self->lex);	if ( token != FinCTokenType_Colon ) /* [:] */	{		match_token(token, self->lex, FinCTokenType_Left_Curly); /* { */		next_token (token, self->lex);				if ( token != FinCTokenType_Right_Curly ) /* } */		{			finc_token_replay(self->lex);			proc_class_member_list(self); /* decl_class_member_list */		}				match_token(token, self->lex, FinCTokenType_Right_Curly);		match_token(token, self->lex, FinCTokenType_Semicolon); /* ; */	}	else	{		next_token(token, self->lex);		if ( token != FinCTokenType_Public ) finc_token_replay(self->lex);		next_token(token, self->lex);		if ( token != FinCTokenType_Class  ) finc_token_replay(self->lex);		proc_class_scope(self);	}}/*class_scope -> ID	| class_scope ':'':' ID*/static FinCNode* proc_class_scope(FinCParser* self){	FinCTokenType token;	FinCNode* id;	id = proc_identifier(self); /* ID */	while ( token == FinCTokenType_Identifier )	{		id = proc_identifier(self);	}	return id;}/*decl_class_member_list -> decl_class_class_member	| decl_class_member_list decl_class_member*/static FinCNode* proc_class_member_list(FinCParser* self){	FinCTokenType token;	FinCNode* field;	next_token(token, self->lex);	while ( (token!= FinCTokenType_Right_Curly) && ((is_type(token))||		token == FinCTokenType_Public	||		token == FinCTokenType_Private	||		token == FinCTokenType_Virtual	||		token == FinCTokenType_Class	|| ) )	{		finc_token_replay(self->lex);		member = proc_class_member(self);		finc_node_add(self->current_class, member);		unref(member);		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return NULL;}/*decl_member -> access-specifier decl_variable	| access-specifier type identifier '(' decl_param_type_list ')' statement_block	| virtual access-specifier type identifier '(' decl_param_type_list ')' statement_block	| virtual access-specifier type identifier '(' decl_param_type_list ')' '=' '0' ';'	| access-specifier decl_classaccess-specifier -> PUBLIC | PRIVATE*/static FinCNode* proc_class_member(FinCParser* self){	FinCTokenType token;	FinCNode* _class;	FinCNode* type;	FinCNode* id;	FinCNode* assign;	Bool b_public, b_virtual, b_static, b_unsigned;	b_public	= FALSE;	b_virtual	= FALSE;	b_static	= FALSE;	b_unsigned	= FALSE;	next_token(token, self->lex);	if ( token == FinCTokenType_Virtual ) b_virtual = TRUE;	else if ( token == FinCTokenType_Public ) b_public = TRUE;	else if ( token == FinCTokenType_Private ) b_public = FALSE;	else if ( token == FinCTokenType_Static ) b_static = TRUE;	else if ( token == FinCTokenType_unsigned ) b_unsigned = TRUE;	else if ( token == FinCTokenType_Class )	{		finc_token_replay(self->lex);		_class = proc_class(self);	}	else finc_token_replay(self->lex);	/* attribute and method */}#endif/*type -> type_list	| identifiertype_list -> type_basic	| type_list type_basictype_basic -> VOID	| CHAR	| SHORT	| INT	| STRING	| POINTER	| FLOAT	| DOUBLE	| BOOLidentifier -> IDENTIFIERnote:there is only one base type in type_list.so there are only four case:idbase_typeunsigned base_typestatice [unsigned] base_type*/static FinCNode* proc_type(FinCParser* self){	FinCTokenType token;	FinCNode* type;	String* str;	type = NULL;	next_token(token, self->lex);	if ( token == FinCTokenType_Identifier ) /*case 1, id*/	{		str = finc_token_get_token(self->lex);		if (finc_lang_check_type(self->lang_env, str))/*it's a struct type.*/		{			type = finc_node_new_type(str, FinCArrayType_None, 0);			unref(str);		}		else		{			finc_token_replay(self->lex);			finc_lang_error_line(self->lex, "Parser Error:unknow struct name.");			unref(str);			return NULL;		}	}	else if ( is_base_type(token) ) /*case 2, base_type*/	{		str = finc_token_get_token(self->lex);		type = finc_node_new_type(str, FinCArrayType_None, 0);		unref(str);	}	else if ( token == FinCTokenType_Unsigned ) /*case 3, unsigned base_type*/	{		next_token(token, self->lex);		if ( is_base_type(token) )

⌨️ 快捷键说明

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