fincparser.c

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

C
2,486
字号
		{			str = finc_token_get_token(self->lex);			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:expecting a declaration type.");			return NULL;		}	}	else if ( token == FinCTokenType_Static ) /*case 4, static [unsigned] base_type*/	{		next_token(token, self->lex);		if ( token == FinCTokenType_Unsigned )		{			next_token(token, self->lex);			if ( is_base_type(token) )			{				str = finc_token_get_token(self->lex);				type = finc_node_new_type(str, FinCArrayType_None, 0);				unref(str);			}			else			{				finc_lang_error_line(self->lex, "Parser Error:expecting a declaration type.");			}		}		else if ( is_base_type(token) )		{			str = finc_token_get_token(self->lex);			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:expecting a declaration type.");			return NULL;		}	}	else	{		finc_token_replay(self->lex);		finc_lang_error_line(self->lex, "Parser Error:unknow type.");		return NULL;	}	return type;}/*identifier:  IDENTIFIER*/static FinCNode* proc_identifier(FinCParser* self){	FinCTokenType token;	match_token(token, self->lex, FinCTokenType_Identifier);	return finc_node_new_name(string_get_str(self->lex->last_str));}/**expr -> expr_assign	| expr ',' expr_assign*/static FinCNode* proc_expr(FinCParser* self){	FinCTokenType token;	FinCNode* assign;	FinCNode* assign_new;	assign = proc_assign_expr(self);	next_token(token, self->lex);	while ( token == FinCTokenType_Comma )	{		assign_new = proc_assign_expr(self);		assign = make_efunc2(",", assign, assign_new);		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return assign;}/**expr_assign -> expr_condition	| expr_unary ASSIGN expr_assign*/static FinCNode* proc_assign_expr(FinCParser* self){	FinCTokenType token;	FinCNode* cond;	FinCNode* assign;	cond = proc_condition_expr(self);	next_token(token, self->lex);	if ( token == FinCTokenType_Assign )	{		assign = proc_assign_expr(self);		return make_efunc2("=", cond, assign);	}	else finc_token_replay(self->lex);	return cond;}/**expr_condition -> expr_logic_or	| expr_logic_or '?' expr ':' expr_condition*/static FinCNode* proc_condition_expr(FinCParser* self){	FinCTokenType token;	FinCNode* logic_or;	FinCNode* expr;	FinCNode* cond_expr;	logic_or = proc_logical_or_expr(self);	next_token(token, self->lex);	if (token == FinCTokenType_Question)	{		expr = proc_expr(self);		match_token(token, self->lex, FinCTokenType_Colon);		cond_expr = proc_condition_expr(self);		return make_efunc3("?", logic_or, expr, cond_expr);	}	finc_token_replay(self->lex);	return logic_or;}/**expr_logic_or -> expr_logic_and	| expr_logic_or OR expr_logic_and*/static FinCNode* proc_logical_or_expr(FinCParser* self){	FinCTokenType token;	FinCNode* logic_and;	FinCNode* logic_and_new;	logic_and = proc_logical_and_expr(self);	next_token(token, self->lex);	while ( token == FinCTokenType_Logic_Or)	{		logic_and_new = proc_logical_and_expr(self);		logic_and = make_efunc2("&&", logic_and, logic_and_new);		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return logic_and;}/*expr_logic_and -> expr_inclusive_or	| expr_logic_and AND expr_inclusive_or*/static FinCNode* proc_logical_and_expr(FinCParser* self){	FinCTokenType token;	FinCNode* or;	FinCNode* or_new;		or = proc_inclusive_or_expr(self);	next_token(token, self->lex);	while ( token == FinCTokenType_Logic_And )	{		or_new = proc_inclusive_or_expr(self);		or = make_efunc2("&&", or, or_new);		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return or;}/*expr_inclusive_or -> expr_exclusive_or	| expr_inclusive_or '|' expr_exclusive_or*/static FinCNode* proc_inclusive_or_expr(FinCParser* self){	FinCTokenType token;	FinCNode* xor;	FinCNode* xor_new;		xor = proc_exclusive_or_expr(self);	next_token(token, self->lex);	while ( token == FinCTokenType_Or )	{		xor_new = proc_exclusive_or_expr(self);		xor = make_efunc2("|", xor, xor_new);		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return xor;}/*expr_exclusive_or -> expr_and	| expr_exclusive '^' expr_and*/static FinCNode* proc_exclusive_or_expr(FinCParser* self){	FinCTokenType token;	FinCNode* and;	FinCNode* and_new;		and = proc_and_expr(self);	next_token(token, self->lex);	while ( token == FinCTokenType_XOR )	{		and_new = proc_and_expr(self);		and = make_efunc2("^", and, and_new);		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return and;}/*expr_and -> expr_equality	| expr_and '&' expr_equality*/static FinCNode* proc_and_expr(FinCParser* self){	FinCTokenType token;	FinCNode* equality;	FinCNode* equality_new;		equality = proc_equality_expr(self);	next_token(token, self->lex);	while ( token == FinCTokenType_And )	{		equality_new = proc_equality_expr(self);		equality = make_efunc2("&", equality, equality_new);		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return equality;}/*expr_equality -> expr_relational	| expr_equality EQ expr_relational	| expr_equality NE expr_relational*/static FinCNode* proc_equality_expr(FinCParser* self){	FinCTokenType token;	FinCNode* rel;	FinCNode* rel_new;	rel = proc_relational_expr(self);	next_token(token, self->lex);	while ( token == FinCTokenType_Eq || token == FinCTokenType_Not_Eqs)	{		rel_new = proc_relational_expr(self);		switch (token)		{		case FinCTokenType_Eq:			rel = make_efunc2("==", rel, rel_new);			break;		case FinCTokenType_Not_Eqs:			rel = make_efunc2("!=", rel, rel_new);			break;		default:			break;		}		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return rel;}/*expr_relational -> expr_shift	| expr_relational '<' expr_shift	| expr_relational '>' expr_shift	| expr_relational LE expr_shift	| expr_relational GE expr_shift*/static FinCNode* proc_relational_expr(FinCParser* self){	FinCTokenType token;	FinCNode* shift;	FinCNode* shift_new;	shift = proc_shift_expr(self);	next_token(token, self->lex);	while ( token == FinCTokenType_GT ||		token == FinCTokenType_LT ||		token == FinCTokenType_Greater_Eqs ||		token == FinCTokenType_Less_Eqs )	{		shift_new = proc_shift_expr(self);		switch (token)		{		case FinCTokenType_GT:			shift = make_efunc2(">", shift, shift_new);			break;		case FinCTokenType_LT:			shift = make_efunc2("<", shift, shift_new);			break;		case FinCTokenType_Greater_Eqs:			shift = make_efunc2(">=", shift, shift_new);			break;		case FinCTokenType_Less_Eqs:			shift = make_efunc2("<=", shift, shift_new);			break;		default:			break;		}		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return shift;}/*expr_shift -> expr_additive	| expr_shift '<<' expr_additive	| expr_shift '>>' expr_additive*/static FinCNode* proc_shift_expr(FinCParser* self){	FinCTokenType token;	FinCNode* add;	FinCNode* add_new;	add = proc_additive_expr(self);	next_token(token, self->lex);	while ( token == FinCTokenType_SHL || token == FinCTokenType_SHR )	{		add_new = proc_additive_expr(self);		switch (token)		{		case FinCTokenType_SHL:			add = make_efunc2("<<", add, add_new);			break;		case FinCTokenType_SHR:			add = make_efunc2(">>", add, add_new);			break;		default:			break;		}		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return add;}/**expr_additive -> expr_multiplicative	| expr_additive SUB expr_multiplicative	| expr_additive ADD expr_multiplicative*/static FinCNode* proc_additive_expr(FinCParser* self){	FinCTokenType token;	FinCNode* mul;	FinCNode* mul_new;	mul = proc_multiplicative_expr(self);	next_token(token, self->lex);	while ( token == FinCTokenType_Sub || token == FinCTokenType_Add )	{		mul_new = proc_multiplicative_expr(self);		switch (token)		{		case FinCTokenType_Sub:			mul = make_efunc2("-", mul, mul_new);			break;		case FinCTokenType_Add:			mul = make_efunc2("+", mul, mul_new);			break;		default:			break;		}		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return mul;}/**expr_multiplicative -> expr_cast	| expr_multiplicative '*' expr_cast	| expr_multiplicative '/' expr_cast	| expr_multiplicative '%' expr_cast*/static FinCNode* proc_multiplicative_expr(FinCParser* self){	FinCTokenType token;	FinCNode* cast;	FinCNode* cast_new;	cast = proc_cast_expr(self);	next_token(token, self->lex);	while (token == FinCTokenType_Mul ||		token == FinCTokenType_Div ||		token == FinCTokenType_Mod )	{		cast_new = proc_cast_expr(self);		switch (token)		{		case FinCTokenType_Mul:			cast = make_efunc2("*", cast, cast_new);			break;		case FinCTokenType_Div:			cast = make_efunc2("/", cast, cast_new);			break;		case FinCTokenType_Mod:			cast = make_efunc2("%", cast, cast_new);			break;		default:			finc_lang_error_line(self->lex, "Parser Error:unexpecting char in expr.");			finc_context_error_inc(g_finc_context);			break;		}		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return cast;}/**expr_cast -> expr_unary	| '(' type ')' expr_cast*/static FinCNode* proc_cast_expr(FinCParser* self){	FinCTokenType token;	FinCNode* type;	FinCNode* cast;	next_token(token, self->lex);	if (token == FinCTokenType_Left_Brace)	{		type = proc_type(self);		match_token(token, self->lex, FinCTokenType_Right_Brace);		cast = proc_cast_expr(self);		return make_efunc2("cast", type, cast);	}	else	{		finc_token_replay(self->lex);		return proc_unary_expr(self);	}}/**expr_unary -> expr_postfix	| ADD expr_cast	| INC expr_cast	| SUB expr_cast	| DEC expr_cast	| NOT expr_cast	| '~' expr_cast	| ADDR_OF '(' expr_unary ')'	| VALUE_OF '(' expr_unary ')'*/static FinCNode* proc_unary_expr(FinCParser* self){	FinCTokenType token;	FinCNode* cast;	FinCNode* unary;	next_token(token, self->lex);	switch (token)	{	case FinCTokenType_Add:		cast = proc_cast_expr(self);		return make_efunc1("plus", cast);	case FinCTokenType_Inc:		cast = proc_cast_expr(self);		return make_efunc1("preinc", cast);	case FinCTokenType_Sub:		cast = proc_cast_expr(self);		return make_efunc1("negative", cast);			case FinCTokenType_Dec:		cast = proc_cast_expr(self);		return make_efunc1("predec", cast);			case FinCTokenType_Not:		cast = proc_cast_expr(self);		return make_efunc1("!", cast);			case FinCTokenType_Bitwise:		cast = proc_cast_expr(self);		return make_efunc1("~", cast);			case FinCTokenType_Addrof:		match_token(token, self->lex, FinCTokenType_Left_Paren);		unary = proc_unary_expr(self);		match_token(token, self->lex, FinCTokenType_Right_Paren);		return make_efunc1("addr_of", unary);	case FinCTokenType_Valueof:		match_token(token, self->lex, FinCTokenType_Left_Paren);		unary = proc_unary_expr(self);		match_token(token, self->lex, FinCTokenType_Right_Paren);		return make_efunc1("value_of", unary);	default:		finc_token_replay(self->lex);		return proc_postfix_expr(self);	}		return NULL;}/**expr_postfix -> expr_primary	| expr_postfix '[' expr ']'	| expr_postfix INC	| expr_postfix DEC	| expr_postfix '.' identifier	| expr_postfix '(' param_list ')'*/static FinCNode* proc_postfix_expr(FinCParser* self){	FinCTokenType token;	FinCNode* postfix;	FinCNode* id;	FinCNode* expr;	postfix = proc_primary_expr(self);	next_token(token, self->lex);	while ( token == FinCTokenType_Left_Brace ||		token == FinCTokenType_Inc ||		token == FinCTokenType_Dec ||		token == FinCTokenType_Dot ||		token == FinCTokenType_Left_Paren )	{		switch (token)		{		case FinCTokenType_Left_Brace :/* '[' */			expr = proc_expr(self);			match_token(token, self->lex, FinCTokenType_Right_Brace);			postfix = make_efunc2("[]", postfix, expr);			break;		case FinCTokenType_Inc :/* '++' */			postfix = make_efunc1("++", postfix);			break;		case FinCTokenType_Dec :/* '--' */			postfix = make_efunc1("--", postfix);			break;		case FinCTokenType_Dot :/* '.' */			id = proc_identifier(self);			postfix = make_efunc2(".", postfix,  id);			break;		case FinCTokenType_Left_Paren :/* '(' */			make_call_begin(self, string_get_str(postfix->identifier));			unref(postfix);			next_token(token, self->lex);			if (token != FinCTokenType_Right_Paren )			{				finc_token_replay(self->lex);				proc_call_param_list(self);								match_token(token, self->lex, FinCTokenType_Right_Paren);			}			postfix = make_call_finish(self);			break;		default:			break;		}		next_token(token, self->lex);	}	finc_token_replay(self->lex);	return postfix;}/*expr_primary -> literal	| '(' expr ')'	| identifier*/static FinCNode* proc_primary_expr(FinCParser* self)

⌨️ 快捷键说明

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