📄 finsh_parser.c
字号:
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 + -