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

📄 finsh_parser.c

📁 中国人自己的c语言
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct finsh_node* and_new;

	and = proc_and_expr(self);
	next_token(token, &(self->token));
	while ( token == finsh_token_type_xor )
	{
		and_new = proc_and_expr(self);
		and = make_sys_node(FINSH_NODE_SYS_XOR, and, and_new);

		next_token(token, &(self->token));
	}

	finsh_token_replay(&(self->token));
	return and;
}

/**
expr_and -> expr_shift
	| expr_and '&' expr_shift
*/
static struct finsh_node* proc_and_expr(struct finsh_parser* self)
{
	enum finsh_token_type token;
	struct finsh_node* shift;
	struct finsh_node* shift_new;

	shift = proc_shift_expr(self);

	next_token(token, &(self->token));
	while ( token == finsh_token_type_and )
	{
		shift_new = proc_shift_expr(self);
		shift = make_sys_node(FINSH_NODE_SYS_AND, shift, shift_new);

		next_token(token, &(self->token));
	}

	finsh_token_replay(&(self->token));
	return shift;
}

/**
expr_shift -> expr_additive
	| expr_shift '<<' expr_additive
	| expr_shift '>>' expr_additive
*/
static struct finsh_node* proc_shift_expr(struct finsh_parser* self)
{
	enum finsh_token_type token;
	struct finsh_node* add;
	struct finsh_node* add_new;

	add = proc_additive_expr(self);

	next_token(token, &(self->token));
	while ( token == finsh_token_type_shl || token == finsh_token_type_shr)
	{
		add_new = proc_additive_expr(self);
		switch (token)
		{
		case finsh_token_type_shl:
			add = make_sys_node(FINSH_NODE_SYS_SHL, add, add_new);
			break;
		case finsh_token_type_shr:
			add = make_sys_node(FINSH_NODE_SYS_SHR, add, add_new);
			break;
		default:
			break;
		}
		next_token(token, &(self->token));
	}

	finsh_token_replay(&(self->token));
	return add;
}

/**
expr_additive -> expr_multiplicative
	| expr_additive SUB expr_multiplicative
	| expr_additive ADD expr_multiplicative
*/
static struct finsh_node* proc_additive_expr(struct finsh_parser* self)
{
	enum finsh_token_type token;
	struct finsh_node* mul;
	struct finsh_node* mul_new;

	mul = proc_multiplicative_expr(self);

	next_token(token, &(self->token));
	while ( token == finsh_token_type_sub || token == finsh_token_type_add )
	{
		mul_new = proc_multiplicative_expr(self);
		switch (token)
		{
		case finsh_token_type_sub:
			mul = make_sys_node(FINSH_NODE_SYS_SUB, mul, mul_new);
			break;
		case finsh_token_type_add:
			mul = make_sys_node(FINSH_NODE_SYS_ADD, mul, mul_new);
			break;
		default:
			break;
		}
		next_token(token, &(self->token));
	}

	finsh_token_replay(&(self->token));
	return mul;
}

/**
expr_multiplicative -> expr_cast
	| expr_multiplicative '*' expr_cast
	| expr_multiplicative '/' expr_cast
	| expr_multiplicative '%' expr_cast
*/
static struct finsh_node* proc_multiplicative_expr(struct finsh_parser* self)
{
	enum finsh_token_type token;
	struct finsh_node* cast;
	struct finsh_node* cast_new;

	cast = proc_cast_expr(self);
	next_token(token, &(self->token));
	while (token == finsh_token_type_mul ||
		token == finsh_token_type_div ||
		token == finsh_token_type_mod )
	{
		cast_new = proc_cast_expr(self);
		switch (token)
		{
		case finsh_token_type_mul:
			cast = make_sys_node(FINSH_NODE_SYS_MUL, cast, cast_new);
			break;

		case finsh_token_type_div:
			cast = make_sys_node(FINSH_NODE_SYS_DIV, cast, cast_new);
			break;

		case finsh_token_type_mod:
			cast = make_sys_node(FINSH_NODE_SYS_MOD, cast, cast_new);
			break;

		default:
			finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
			break;
		}
		next_token(token, &(self->token));
	}

	finsh_token_replay(&(self->token));
	return cast;
}

/**
expr_cast -> expr_unary
	| '(' type ')' expr_cast
*/
static struct finsh_node* proc_cast_expr(struct finsh_parser* self)
{
	enum finsh_token_type token;
	// enum finsh_type type;
	// struct finsh_node* cast;

	next_token(token, &(self->token));
#if 0
	if (token == finsh_token_type_left_paren)
	{
		type = proc_type(self);
		match_token(token, &(self->token), finsh_token_type_right_paren);

		cast = proc_cast_expr(self);
		return make_sys_node(FINSH_NODE_SYS_CAST, type, cast);
	}
	else
#endif
	{
		finsh_token_replay(&(self->token));
		return proc_unary_expr(self);
	}
}

/**
expr_unary -> expr_postfix
	| ADD expr_cast
	| INC expr_cast
	| SUB expr_cast
	| DEC expr_cast
	| '~' expr_cast
*/
static struct finsh_node* proc_unary_expr(struct finsh_parser* self)
{
	enum finsh_token_type token;
	struct finsh_node* cast;

	next_token(token, &(self->token));
	switch (token)
	{
	case finsh_token_type_add:
		cast = proc_cast_expr(self);
		return cast;

	case finsh_token_type_inc:
		cast = proc_cast_expr(self);
		return make_sys_node(FINSH_NODE_SYS_PREINC, cast, NULL);

	case finsh_token_type_sub:
		cast = proc_cast_expr(self);
		return make_sys_node(FINSH_NODE_SYS_NEGATIVE, cast, NULL);

	case finsh_token_type_dec:
		cast = proc_cast_expr(self);
		return make_sys_node(FINSH_NODE_SYS_PREDEC, cast, NULL);

	case finsh_token_type_bitwise:
		cast = proc_cast_expr(self);
		return make_sys_node(FINSH_NODE_SYS_BITWISE, cast, NULL);

	default:
		finsh_token_replay(&(self->token));
		return proc_postfix_expr(self);
	}

	return NULL;
}

/**
expr_postfix -> expr_primary
	| expr_postfix INC
	| expr_postfix DEC
	| expr_postfix '(' param_list ')'
*/
static struct finsh_node* proc_postfix_expr(struct finsh_parser* self)
{
	enum finsh_token_type token;
	struct finsh_node* postfix;

	postfix = proc_primary_expr(self);

	next_token(token, &(self->token));
	while ( token == finsh_token_type_inc 	||
		token == finsh_token_type_dec 		||
		token == finsh_token_type_left_paren )
	{
		switch (token)
		{
		case finsh_token_type_inc :/* '++' */
			postfix = make_sys_node(FINSH_NODE_SYS_INC, postfix, NULL);
			break;

		case finsh_token_type_dec :/* '--' */
			postfix = make_sys_node(FINSH_NODE_SYS_DEC, postfix, NULL);
			break;

		case finsh_token_type_left_paren :/* '(' */
			{
				struct finsh_node* param_list;

				param_list = NULL;
				next_token(token, &(self->token));
				if (token != finsh_token_type_right_paren)
				{
					finsh_token_replay(&(self->token));
					param_list = proc_param_list(self);

					match_token(token, &(self->token), finsh_token_type_right_paren);
				}

				postfix = make_sys_node(FINSH_NODE_SYS_FUNC, postfix, param_list);
			}
			break;

		default:
			break;
		}

		next_token(token, &(self->token));
	}

	finsh_token_replay(&(self->token));
	return postfix;
}

/**
expr_primary -> literal
	| '(' expr ')'
	| identifier
*/
static struct finsh_node* proc_primary_expr(struct finsh_parser* self)
{
	enum finsh_token_type token;
	struct finsh_node* expr;

	next_token(token, &(self->token));
	switch ( token )
	{
	case finsh_token_type_identifier:
		{
			char id[FINSH_NAME_MAX + 1];

			finsh_token_replay(&(self->token));
			proc_identifier(self, id);
			return finsh_node_new_id(id);
		}

	case finsh_token_type_left_paren:
		expr = proc_expr(self);
		match_token(token, &(self->token), finsh_token_type_right_paren);
		return expr;

	case finsh_token_type_value_int:
		return finsh_node_new_int(self->token.int_value);

	case finsh_token_type_value_long:
		return finsh_node_new_long(self->token.long_value);

	case finsh_token_type_value_char:
		return finsh_node_new_char(self->token.char_value);

	case finsh_token_type_value_string:
		return finsh_node_new_string(self->token.string);

	case finsh_token_type_value_null:
		return finsh_node_new_ptr(NULL);

	default:
		finsh_token_replay(&(self->token));
		break;
	}

	return NULL;
}

/**
param_list -> empty
	| expr_assign
	| param_list ',' expr_assign
*/
static struct finsh_node* proc_param_list(struct finsh_parser* self)
{
	enum finsh_token_type token;
	struct finsh_node *node, *assign;

	assign = proc_assign_expr(self);
	node = assign;

	next_token(token, &(self->token));
	while (token == finsh_token_type_comma )
	{
		finsh_node_sibling(assign) = proc_assign_expr(self);
		if (finsh_node_sibling(assign) != NULL)
			assign = finsh_node_sibling(assign);

		next_token(token, &(self->token));
	}

	finsh_token_replay(&(self->token));

	return node;
}

/**
make a new node as following tree:
new_node
|
node1__
       \
       node2
*/
static struct finsh_node* make_sys_node(u_char type, struct finsh_node* node1, struct finsh_node* node2)
{
	struct finsh_node* node;

	node = finsh_node_allocate(type);

	finsh_node_child(node) = node1;
	finsh_node_sibling(node1) = node2;

	return node;
}

/**
start -> statement_expr | decl_variable
*/
void finsh_parser_run(struct finsh_parser* self, const u_char* string)
{
	enum finsh_token_type token;
	struct finsh_node *node;

    node = NULL;

	/* init parser */
	self->parser_string = string;

	/* init token */
	finsh_token_init(&(self->token), self->parser_string);

	/* get next token */
	next_token(token, &(self->token));
	while (token != finsh_token_type_eof && token != finsh_token_type_bad)
	{
		switch (token)
		{
        case finsh_token_type_identifier:
            /* process expr_statement */
            finsh_token_replay(&(self->token));

			if (self->root != NULL)
			{
				finsh_node_sibling(node) = proc_expr_statement(self);
				node = finsh_node_sibling(node);
			}
			else
			{
            	node = proc_expr_statement(self);
				self->root = node;
			}
            break;

		default:
            if (is_base_type(token) || token == finsh_token_type_unsigned)
            {
            	/* variable decl */
            	finsh_token_replay(&(self->token));

				if (self->root != NULL)
				{
					finsh_node_sibling(node) = proc_variable_decl(self);
					node = finsh_node_sibling(node);
				}
				else
				{
					node = proc_variable_decl(self);
					self->root = node;
				}
            }
            else
            {
            	/* process expr_statement */
                finsh_token_replay(&(self->token));

				if (self->root != NULL)
				{
					finsh_node_sibling(node) = proc_expr_statement(self);
					node = finsh_node_sibling(node);
				}
				else
				{
					node = proc_expr_statement(self);
					self->root = node;
				}
            }

			break;
		}
        /* get next token */
		next_token(token, &(self->token));
	}
}

int finsh_parser_init(struct finsh_parser* self)
{
	memset(self, 0, sizeof(struct finsh_parser));

	return 0;
}

⌨️ 快捷键说明

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