fincparser.c

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

C
2,486
字号
{	FinCTokenType token;	FinCNode* expr;	next_token(token, self->lex);	switch ( token )	{	case FinCTokenType_Identifier:		finc_token_replay(self->lex);		return proc_identifier(self);	case FinCTokenType_Left_Paren:		expr = proc_expr(self);		match_token(token, self->lex, FinCTokenType_Right_Paren);		return expr;	case FinCTokenType_Int:		return finc_node_new_integer((int)self->lex->last_double);	#ifdef USING_FLOAT	case FinCTokenType_Float:		return finc_node_new_float((float)self->lex->last_float);	#endif	#ifdef USING_DOUBLE	case FinCTokenType_Double:		return finc_node_new_double((long)self->lex->last_double);	#endif	case FinCTokenType_Long:		return finc_node_new_long((long)self->lex->last_double);	case FinCTokenType_Char:		return finc_node_new_char(self->lex->last_char);	case FinCTokenType_String:		return finc_node_new_string(string_get_str(self->lex->last_str));	case FinCTokenType_Null:		return finc_node_new_pointer(NULL);	case FinCTokenType_True:		return finc_node_new_bool(TRUE);	case FinCTokenType_False:		return finc_node_new_bool(FALSE);	default:		finc_token_replay(self->lex);		break;	}	return NULL;}/*param_list -> empty	| expr_assign	| param_list ',' expr_assign*/static FinCNode* proc_call_param_list(FinCParser* self){	FinCTokenType token;	FinCNode* assign;	assign = proc_assign_expr(self);	make_call_add (self, assign);	next_token(token, self->lex);	while (token == FinCTokenType_Comma )	{		assign = proc_assign_expr(self);		next_token(token, self->lex);		make_call_add (self, assign);	}	finc_token_replay(self->lex);	return NULL;}/*statement -> decl_local	| statement_block	| statement_expr	| statement_return	| statement_for	| statement_while	| statement_if	| statement_continue	| statement_break*/static FinCNode* proc_statement(FinCParser* self){	FinCTokenType token;	String* str;	next_token(token, self->lex);	switch ( token )	{	case FinCTokenType_Left_Curly:		finc_token_replay(self->lex);		return proc_block_statement(self);		break;	case FinCTokenType_Return:	case FinCTokenType_Continue:	case FinCTokenType_Break:		finc_token_replay(self->lex);		return proc_simple_statement(self);		break;	case FinCTokenType_For:		finc_token_replay(self->lex);		return proc_for_statement(self);		break;	case FinCTokenType_While:		finc_token_replay(self->lex);		return proc_while_statement(self);		break;	case FinCTokenType_If:		finc_token_replay(self->lex);		return proc_if_statement(self);		break;	default:		if (is_type(token))		{			if ( token == FinCTokenType_Identifier ) /*if it's a function call.*/			{				str = finc_token_get_token(self->lex);				if (finc_lang_check_type(self->lang_env, str))/*it's a struct type.*/				{					unref(str);					finc_token_replay(self->lex);					return make_efunc1("local", proc_variable_decl(self));				}				else/*it's a function call.*/				{					unref(str);					finc_token_replay(self->lex);					return proc_expr_statement(self);				}			}			finc_token_replay(self->lex);			return make_efunc1("local", proc_variable_decl(self));		}		finc_lang_error_line(self->lex, "Parser Error: unexpecting token.");		finc_context_error_inc(g_finc_context);		finc_token_replay(self->lex);		break;	}	return NULL;}/*statement_in_block -> decl_local	| statement_block	| statement_node	| statement_return	| statement_for	| statement_while	| statement_if*/static FinCNode* proc_in_block_statement(FinCParser* self){	FinCTokenType token;	String* str;	next_token(token, self->lex);	switch ( token )	{	case FinCTokenType_Left_Curly:		finc_token_replay(self->lex);		return proc_block_statement(self);		break;	case FinCTokenType_Return:	case FinCTokenType_Continue:	case FinCTokenType_Break:		finc_token_replay(self->lex);		return proc_simple_statement(self);		break;	case FinCTokenType_For:		finc_token_replay(self->lex);		return proc_for_statement(self);		break;	case FinCTokenType_While:		finc_token_replay(self->lex);		return proc_while_statement(self);		break;	case FinCTokenType_If:		finc_token_replay(self->lex);		return proc_if_statement(self);		break;	default:		if (is_type(token))		{			if ( token == FinCTokenType_Identifier ) /*if it's a function call.*/			{				str = finc_token_get_token(self->lex);				if (finc_lang_check_type(self->lang_env, str))/*it's a struct type.*/				{					unref(str);					finc_token_replay(self->lex);					return make_efunc1("local", proc_variable_decl(self));				}				else/*it's a function call.*/				{					unref(str);					finc_token_replay(self->lex);					return proc_expr_statement(self);				}			}			finc_token_replay(self->lex);			return make_efunc1("local", proc_variable_decl(self));		}		finc_lang_error_line(self->lex, "Parser Error: unexpecting token.");		finc_context_error_inc(g_finc_context);		finc_token_replay(self->lex);		break;	}	return NULL;}/*statement_block -> '{' statement_list '}'statement_list -> statement_in_block	| statement_list statement_in_block*/static FinCNode* proc_block_statement(FinCParser* self){	FinCTokenType token;	FinCNode* statement;	match_token(token, self->lex, FinCTokenType_Left_Curly);	make_block_begin(self);	next_token(token, self->lex);	while (token != FinCTokenType_Right_Curly)	{		finc_token_replay(self->lex);		statement = proc_in_block_statement(self);		if (statement)		{			make_block_add(self, statement);			next_token(token, self->lex);		}		else break;	}	return make_block_finish(self);}/*statement_expr -> ';'	| expr ';'*/static FinCNode* proc_expr_statement(FinCParser* self){	FinCTokenType token;	FinCNode* expr;	expr = NULL;	next_token(token, self->lex);	if ( token != FinCTokenType_Semicolon )	{		finc_token_replay(self->lex);		expr = proc_expr(self);		match_token(token, self->lex, FinCTokenType_Semicolon);	}	return expr;}/*statement_for -> FOR '(' statement_expr statement_expr expr ')' statement*/static FinCNode* proc_for_statement(FinCParser* self){	FinCTokenType token;	FinCNode *expr_s1, *expr_s2, *expr, *statement;	expr = NULL;	match_token(token, self->lex, FinCTokenType_For);	match_token(token, self->lex, FinCTokenType_Left_Paren);	expr_s1 = proc_expr_statement(self);	expr_s2 = proc_expr_statement(self);	next_token(token, self->lex);	if (token != FinCTokenType_Right_Paren)	{		finc_token_replay(self->lex);		expr = proc_expr(self);		match_token(token, self->lex, FinCTokenType_Right_Paren);	}	statement = proc_statement(self);	return make_efunc4 ("for", expr_s1, expr_s2, expr, statement);}/*statement_while -> WHILE '(' expr ')' statement*/static FinCNode* proc_while_statement(FinCParser* self){	FinCTokenType token;	FinCNode *expr, *statement;	match_token(token, self->lex, FinCTokenType_While);	match_token(token, self->lex, FinCTokenType_Left_Paren);	expr = proc_expr(self);	match_token(token, self->lex, FinCTokenType_Right_Paren);	statement = proc_statement(self);	return make_efunc2 ("while", expr, statement);}/*statement_if -> IF '(' expr ')' statement statement_if_elsestatement_if_else -> empty	| ELSE statement*/static FinCNode* proc_if_statement(FinCParser* self){	FinCTokenType token;	FinCNode *expr, *statement_true, *statement_false;	statement_false = NULL;	match_token(token, self->lex, FinCTokenType_If);	match_token(token, self->lex, FinCTokenType_Left_Paren);	expr = proc_expr(self);	match_token(token, self->lex, FinCTokenType_Right_Paren);	statement_true = proc_statement(self);	next_token(token, self->lex);	if ( token == FinCTokenType_Else )		statement_false = proc_statement(self);	else finc_token_replay(self->lex);	if ( statement_false )	{		return make_efunc3 ("if", expr, statement_true, statement_false);	}	else	{		return make_efunc2 ("if", expr, statement_true);	}	return NULL;}/*statement_continue -> CONTINUE ';'statement_break -> BREAK ';'statement_return -> RETURN expr ';'*/static FinCNode* proc_simple_statement(FinCParser* self){	FinCTokenType token;	FinCNode* expr;	expr = NULL;	next_token(token, self->lex);	switch ( token )	{	case FinCTokenType_Continue:		match_token(token, self->lex, FinCTokenType_Semicolon);		return make_efunc("continue");		break;	case FinCTokenType_Break:		match_token(token, self->lex, FinCTokenType_Semicolon);		return make_efunc("break");		break;	case FinCTokenType_Return:		next_token(token, self->lex);		if ( token != FinCTokenType_Semicolon )		{			finc_token_replay(self->lex);			expr = proc_expr(self);			next_token(token, self->lex);		}		check_token(token, self->lex, FinCTokenType_Semicolon);		return make_efunc1("return", expr);		break;	default:		break;	}	return NULL;}static void make_pkg_begin(FinCParser* self, unsigned char* p_package){	FinCNode* pkg_name;	pkg_name = finc_node_new_name(p_package);    self->current_pkg = finc_node_new_func("package");	finc_node_add(self->current_pkg, pkg_name);	unref(pkg_name);}static void make_pkg_func_begin (FinCParser* self, FinCNode* p_type, FinCNode* p_identifier){	self->current_func = finc_node_new_func ("func");	finc_node_add (self->current_func, p_type);	unref (p_type);	finc_node_add (self->current_func, p_identifier);	unref (p_identifier);}static FinCNode* make_pkg_func_finish (FinCParser* self){	FinCNode* l_func;	l_func = self->current_func;	self->current_func = NULL;	return l_func;}static FinCNode* make_pkg_finish(FinCParser* self){	FinCNode* l_pkg;	l_pkg = self->current_pkg;	self->current_pkg = NULL;	return l_pkg;}static void make_func_begin (FinCParser* self, FinCNode* p_type, FinCNode* p_identifier){	self->current_func = finc_node_new_func ("func");	finc_node_add (self->current_func, p_type);	unref (p_type);	finc_node_add (self->current_func, p_identifier);	unref (p_identifier);}static void make_func_add_param (FinCParser* self, FinCNode* p_type, FinCNode* p_name){	finc_node_add (self->current_func, p_type);	unref (p_type);	finc_node_add (self->current_func, p_name);	unref (p_name);}static void make_func_opt_param (FinCParser* self){	finc_node_add (self->current_func, NULL);}static FinCNode* make_func_finish (FinCParser* self, FinCNode* p_code){	FinCNode* l_func;	finc_node_add (self->current_func, p_code);	unref (p_code);	l_func = self->current_func;	self->current_func = NULL;	return l_func;}static void make_block_begin (FinCParser* self){	if (self->current_block)	{		stack_push(self->stack_block, (ADT)self->current_block);		unref(self->current_block);	}	self->current_block = finc_node_new_func ("@");}static void make_block_add (FinCParser* self, FinCNode* p_node){	finc_node_add (self->current_block, p_node);	unref (p_node);}static FinCNode* make_block_finish (FinCParser* self){	FinCNode* l_block;	if (stack_get_size(self->stack_block) > 0)	{		l_block = self->current_block;		self->current_block = stack_pop(self->stack_block);	}	else	{		l_block = self->current_block;		self->current_block = NULL;	}	return l_block;}static void make_call_begin (FinCParser* self, unsigned char* p_identifier){	if (self->current_call)	{		stack_push(self->stack_call, (ADT)self->current_call);		unref(self->current_call);	}	self->current_call = finc_node_new_func (p_identifier);}static void make_call_add (FinCParser* self, FinCNode* p_node){	finc_node_add (self->current_call, p_node);	unref (p_node);}static FinCNode* make_call_finish (FinCParser* self){	FinCNode* l_call;	if (stack_get_size(self->stack_call) > 0)	{		l_call = self->current_call;		self->current_call = stack_pop(self->stack_call);	}	else	{		l_call = self->current_call;		self->current_call = NULL;	}	return l_call;}static FinCNode* make_efunc (unsigned char* p_func){	return finc_node_new_func (p_func);}static FinCNode* make_efunc1 (unsigned char* p_func, FinCNode* p_node1){	FinCNode* l_node;	l_node = finc_node_new_func (p_func);	finc_node_add (l_node, p_node1);	unref (p_node1);	return l_node;}static FinCNode* make_efunc2 (unsigned char* p_func, FinCNode* p_node1, FinCNode* p_node2){	FinCNode* l_node;	l_node = finc_node_new_func (p_func);	finc_node_add (l_node, p_node1);	unref (p_node1);	finc_node_add (l_node, p_node2);	unref (p_node2);	return l_node;}static FinCNode* make_efunc3 (unsigned char* p_func, FinCNode* p_node1, FinCNode* p_node2, FinCNode* p_node3){	FinCNode* l_node;	l_node = finc_node_new_func (p_func);	finc_node_add (l_node, p_node1);	unref (p_node1);	finc_node_add (l_node, p_node2);	unref (p_node2);	finc_node_add (l_node, p_node3);	unref (p_node3);	return l_node;}static FinCNode* make_efunc4 (unsigned char* p_func, FinCNode* p_node1, FinCNode* p_node2, FinCNode* p_node3, FinCNode* p_node4){	FinCNode* l_node;	l_node = finc_node_new_func (p_func);	finc_node_add (l_node, p_node1);	unref (p_node1);	finc_node_add (l_node, p_node2);	unref (p_node2);	finc_node_add (l_node, p_node3);	unref (p_node3);	finc_node_add (l_node, p_node4);	unref (p_node4);	return l_node;}

⌨️ 快捷键说明

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