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

📄 finsh_parser.c.svn-base

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
#include <finsh.h>#include "finsh_token.h"#include "finsh_node.h"#include "finsh_error.h"#include "finsh_parser.h"#include "finsh_var.h"/* * the structure of abstract syntax tree: * root____________ * |               \ * child__        sibling__ * |      \       |        \ * child sibling  child   sibling *                          ... */static enum finsh_type proc_type(struct finsh_parser* self);static int proc_identifier(struct finsh_parser* self, char* id);static struct finsh_node* proc_variable_decl(struct finsh_parser* self);static struct finsh_node* proc_expr(struct finsh_parser* self);static struct finsh_node* proc_assign_expr(struct finsh_parser* self);static struct finsh_node* proc_inclusive_or_expr(struct finsh_parser* self);static struct finsh_node* proc_exclusive_or_expr(struct finsh_parser* self);static struct finsh_node* proc_and_expr(struct finsh_parser* self);static struct finsh_node* proc_shift_expr(struct finsh_parser* self);static struct finsh_node* proc_additive_expr(struct finsh_parser* self);static struct finsh_node* proc_multiplicative_expr(struct finsh_parser* self);static struct finsh_node* proc_cast_expr(struct finsh_parser* self);static struct finsh_node* proc_unary_expr(struct finsh_parser* self);static struct finsh_node* proc_postfix_expr(struct finsh_parser* self);static struct finsh_node* proc_primary_expr(struct finsh_parser* self);static struct finsh_node* proc_param_list(struct finsh_parser* self);static struct finsh_node* proc_expr_statement(struct finsh_parser* self);static struct finsh_node* make_sys_node(u_char type, struct finsh_node* node1,	struct finsh_node* node2);/* check token */#define check_token(token, lex, type) if ( (token) != (type) ) \	{ \		finsh_error_set(FINSH_ERROR_INVALID_TOKEN); \		finsh_token_replay(lex); \	}/* is the token a data type? */#define is_base_type(token)	((token) == finsh_token_type_void \    || (token) == finsh_token_type_char \	|| (token) == finsh_token_type_short \	|| (token) == finsh_token_type_int \	|| (token) == finsh_token_type_long)/* get the next token */#define next_token(token, lex)	(token) = finsh_token_token(lex)/* match a specified token */#define match_token(token, lex, type)	next_token(token, lex); \	check_token(token, lex, type)/**process for function and variable declaration.decl_variable -> type declaration_list ';'declarator_list -> declarator_list ',' declarator	| declaratordeclarator -> identifier	| identifier ASSIGN expr_assign*/static struct finsh_node* proc_variable_decl(struct finsh_parser* self){	enum finsh_token_type token;	enum finsh_type type;	char id[FINSH_NAME_MAX + 1];	struct finsh_node *node;	struct finsh_node *end;	struct finsh_node *assign;    node = NULL;	end  = NULL;	/* get type */	type = proc_type(self);	/*process id.*/	if (proc_identifier(self, id) == 0)	{		/* if add variable failed */		if (finsh_var_insert(id, type) < 0)		{			finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);		}	}	next_token(token, &(self->token));	switch ( token )	{	case finsh_token_type_comma:/*',', it's a variable_list declaration.*/		if (proc_identifier(self, id) == 0)		{			/* if add variable failed */			if (finsh_var_insert(id, type) < 0)			{				finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);			}		}		next_token(token, &(self->token));		if ( token == finsh_token_type_assign )		{			/* get the right side of assign expression */			assign = proc_assign_expr(self);			if (assign != NULL)			{				struct finsh_node* idnode;				idnode = finsh_node_new_id(id);				end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);				node = end;				next_token(token, &(self->token));			}		}		while ( token == finsh_token_type_comma )		{			if (proc_identifier(self, id) == 0)			{				/* if add variable failed */				if (finsh_var_insert(id, type) < 0)				{					finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);				}			}			next_token(token, &(self->token));			if ( token == finsh_token_type_assign )			{				/* get the right side of assign expression */				assign = proc_assign_expr(self);				if (assign != NULL)				{					struct finsh_node* idnode;					idnode = finsh_node_new_id(id);					/* make assign expression node */					if (node != NULL)					{						finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);						end = finsh_node_sibling(end);					}					else					{						end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);						node = end;					}					next_token(token, &(self->token));				}			}		}		check_token(token, &(self->token), finsh_token_type_semicolon);		return node;	case finsh_token_type_assign:/*'=', it's a variable with assign declaration.*/	{		struct finsh_node *idnode;		assign = proc_assign_expr(self);		if (assign != NULL)		{			idnode = finsh_node_new_id(id);			/* make assign expression node */			end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);			node = end;			next_token(token, &(self->token));		}		while ( token == finsh_token_type_comma )		{			if (proc_identifier(self, id) == 0)			{				/* if add variable failed */				if (finsh_var_insert(id, type) < 0)				{					finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);				}			}			next_token(token, &(self->token));			if (token == finsh_token_type_assign)			{				/* get the right side of assign expression */				assign = proc_assign_expr(self);				if (assign != NULL)				{					idnode = finsh_node_new_id(id);					/* make assign expression node */					if (node != NULL)					{						finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);						end = finsh_node_sibling(end);					}					else					{						end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);						node = end;					}					next_token(token, &(self->token));				}			}		}		check_token(token, &(self->token), finsh_token_type_semicolon);		return node;	}	case finsh_token_type_semicolon:/*';', it's a variable declaration.*/		return node;	default:		finsh_error_set(FINSH_ERROR_EXPECT_TYPE);		return NULL;	}}/**type -> type_prefix type_basic | type_basictype_prefix -> UNSIGNEDtype_basic -> VOID	| CHAR	| SHORT	| INT	| STRING*/static enum finsh_type proc_type(struct finsh_parser* self){	enum finsh_type type;	enum finsh_token_type token;	/* set init type */	type = finsh_type_unknown;	next_token(token, &(self->token));	if ( is_base_type(token) ) /* base_type */	{		switch (token)		{		case finsh_token_type_void:			type = finsh_type_void;			break;		case finsh_token_type_char:			type = finsh_type_char;			break;		case finsh_token_type_short:			type = finsh_type_short;			break;		case finsh_token_type_int:			type = finsh_type_int;			break;		case finsh_token_type_long:			type = finsh_type_long;			break;		default:			goto __return;			break;		}	}	else if ( token == finsh_token_type_unsigned ) /* unsigned base_type */	{		next_token(token, &(self->token));		if ( is_base_type(token) )		{			switch (token)			{			case finsh_token_type_char:				type = finsh_type_uchar;				break;			case finsh_token_type_short:				type = finsh_type_ushort;				break;			case finsh_token_type_int:				type = finsh_type_uint;				break;			case finsh_token_type_long:				type = finsh_type_ulong;				break;			default:				goto __return;				break;			}		}		else		{			finsh_token_replay(&(self->token));			finsh_error_set(FINSH_ERROR_EXPECT_TYPE);		}	}	else	{		goto __return;	}	/* parse for pointer */	next_token(token, &(self->token));	if (token == finsh_token_type_mul)	{		switch (type)		{		case finsh_type_void:			type = finsh_type_voidp;			break;		case finsh_type_char:		case finsh_type_uchar:			type = finsh_type_charp;			break;		case finsh_type_short:		case finsh_type_ushort:			type = finsh_type_shortp;			break;		case finsh_type_int:		case finsh_type_uint:			type = finsh_type_intp;			break;		case finsh_type_long:		case finsh_type_ulong:			type = finsh_type_longp;			break;		default:			type = finsh_type_voidp;			break;		}	}	else finsh_token_replay(&(self->token));	return type;__return:	finsh_token_replay(&(self->token));	finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);	return type;}/**identifier -> IDENTIFIER*/static int proc_identifier(struct finsh_parser* self, char* id){	enum finsh_token_type token;	match_token(token, &(self->token), finsh_token_type_identifier);	strncpy(id, (char*)self->token.string, FINSH_NAME_MAX);	return 0;}/**statement_expr -> ';'	| expr ';'*/static struct finsh_node* proc_expr_statement(struct finsh_parser* self){	enum finsh_token_type token;	struct finsh_node* expr;	expr = NULL;	next_token(token, &(self->token));	if ( token != finsh_token_type_semicolon )	{		finsh_token_replay(&(self->token));		expr = proc_expr(self);		match_token(token, &(self->token), finsh_token_type_semicolon);	}	return expr;}/**expr -> expr_assign*/static struct finsh_node* proc_expr(struct finsh_parser* self){	return proc_assign_expr(self);}/**expr_assign -> expr_inclusive_or	| expr_unary ASSIGN expr_assign*/static struct finsh_node* proc_assign_expr(struct finsh_parser* self){	enum finsh_token_type token;	struct finsh_node* or;	struct finsh_node* assign;	or = proc_inclusive_or_expr(self);	next_token(token, &(self->token));	if (token == finsh_token_type_assign)	{		assign = proc_assign_expr(self);		return make_sys_node(FINSH_NODE_SYS_ASSIGN, or, assign);	}	else finsh_token_replay(&(self->token));	return or;}/**expr_inclusive_or -> expr_exclusive_or	| expr_inclusive_or '|' expr_exclusive_or*/static struct finsh_node* proc_inclusive_or_expr(struct finsh_parser* self){	enum finsh_token_type token;	struct finsh_node* xor;	struct finsh_node* xor_new;	xor = proc_exclusive_or_expr(self);	next_token(token, &(self->token));	while ( token == finsh_token_type_or )	{		xor_new = proc_exclusive_or_expr(self);				if (xor_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);		else xor = make_sys_node(FINSH_NODE_SYS_OR, xor, xor_new);		next_token(token, &(self->token));	}	finsh_token_replay(&(self->token));	return xor;}/**expr_exclusive_or -> expr_and	| expr_exclusive '^' expr_and*/static struct finsh_node* proc_exclusive_or_expr(struct finsh_parser* self){	enum finsh_token_type token;	struct finsh_node* and;	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);		if (and_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);		else and = make_sys_node(FINSH_NODE_SYS_XOR, and, and_new);		next_token(token, &(self->token));	}	finsh_token_replay(&(self->token));	return and;

⌨️ 快捷键说明

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