Make a single "operator" token, and specialize after parse.

This commit is contained in:
Danila Fedorin 2018-03-17 20:56:25 -07:00
parent 156c02908d
commit 9500a6f9b0
5 changed files with 42 additions and 36 deletions

View File

@ -9,6 +9,16 @@
*/
typedef void(*libab_function_ptr)();
/**
* The variant of the operator that
* has been registered with libabacus.
*/
enum libab_operator_variant_e {
OPERATOR_PREFIX,
OPERATOR_INFIX,
OPERATOR_POSTFIX
};
/**
* The common information
* that both operators and functions shared.
@ -34,7 +44,7 @@ struct libab_operator_s {
* Corresponds to token types associated with
* each operator.
*/
int type;
enum libab_operator_variant_e type;
/**
* The precedence of the operator.
*/
@ -61,6 +71,7 @@ struct libab_function_s {
struct libab_behavior_s behavior;
};
typedef enum libab_operator_variant_e libab_operator_variant;
typedef struct libab_behavior_s libab_behavior;
typedef struct libab_operator_s libab_operator;
typedef struct libab_function_s libab_function;

View File

@ -55,6 +55,7 @@ enum libab_lexer_token_e {
TOKEN_CHAR = 0,
TOKEN_ID,
TOKEN_NUM,
TOKEN_OP,
TOKEN_OP_INFIX,
TOKEN_OP_PREFIX,
TOKEN_OP_POSTFIX,

View File

@ -49,7 +49,7 @@ libab_result _initialize_behavior(libab* ab, libab_behavior* behavior,
return result;
}
libab_result _register_operator(libab* ab, const char* op, int token_type, int precedence, int associativity, const char* type, libab_function_ptr func) {
libab_result _register_operator(libab* ab, const char* op, libab_operator_variant token_type, int precedence, int associativity, const char* type, libab_function_ptr func) {
char op_buffer[8];
libab_result result = LIBAB_SUCCESS;
libab_table_entry* new_entry;
@ -69,7 +69,7 @@ libab_result _register_operator(libab* ab, const char* op, int token_type, int p
if(result == LIBAB_SUCCESS) {
_sanitize(op_buffer, op, 8);
result = libab_convert_lex_result(eval_config_add(&ab->lexer.config, op_buffer, token_type));
result = libab_convert_lex_result(eval_config_add(&ab->lexer.config, op_buffer, TOKEN_OP));
}
if(result == LIBAB_SUCCESS) {
@ -79,7 +79,7 @@ libab_result _register_operator(libab* ab, const char* op, int token_type, int p
if(result != LIBAB_SUCCESS) {
if(new_entry && new_entry->data_u.op.behavior.type)
libab_parsetype_free_recursive(new_entry->data_u.op.behavior.type);
eval_config_remove(&ab->lexer.config, op, token_type);
eval_config_remove(&ab->lexer.config, op, TOKEN_OP);
free(new_entry);
}
@ -87,15 +87,15 @@ libab_result _register_operator(libab* ab, const char* op, int token_type, int p
}
libab_result libab_register_operator_infix(libab* ab, const char* op, int precedence, int associativity, const char* type, libab_function_ptr func) {
return _register_operator(ab, op, TOKEN_OP_INFIX, precedence, associativity, type, func);
return _register_operator(ab, op, OPERATOR_INFIX, precedence, associativity, type, func);
}
libab_result libab_register_operator_prefix(libab* ab, const char* op, const char* type, libab_function_ptr func) {
return _register_operator(ab, op, TOKEN_OP_PREFIX, 0, 0, type, func);
return _register_operator(ab, op, OPERATOR_PREFIX, 0, 0, type, func);
}
libab_result libab_register_operator_postfix(libab* ab, const char* op, const char* type, libab_function_ptr func) {
return _register_operator(ab, op, TOKEN_OP_POSTFIX, 0, 0, type, func);
return _register_operator(ab, op, OPERATOR_POSTFIX, 0, 0, type, func);
}
libab_result libab_register_function(libab* ab, const char* name, const char* type, libab_function_ptr func) {

View File

@ -748,7 +748,8 @@ libab_result _parser_append_op_node(struct parser_state* state, libab_lexer_matc
// Expression-specific utility functions
int _parser_match_is_op(libab_lexer_match* match) {
return match->type == TOKEN_OP_INFIX ||
return match->type == TOKEN_OP ||
match->type == TOKEN_OP_INFIX ||
match->type == TOKEN_OP_PREFIX ||
match->type == TOKEN_OP_POSTFIX ||
match->type == TOKEN_OP_RESERVED;
@ -792,7 +793,7 @@ void _parser_find_operator_infix(struct parser_state* state, libab_lexer_match*
char op_buffer[8];
_parser_extract_token_buffer(state, op_buffer, 8, match);
if(match->type != TOKEN_OP_RESERVED) {
libab_operator* operator = libab_table_search_operator(state->base_table, op_buffer, TOKEN_OP_INFIX);
libab_operator* operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_INFIX);
data->associativity = operator->associativity;
data->precedence = operator->precedence;
} else {
@ -856,41 +857,33 @@ libab_result _parser_expression_tree(struct parser_state* state, ll* source, lib
int _parser_match_is_postfix_op(struct parser_state* state, libab_lexer_match* match) {
int is_postfix = 0;
if(match->type == TOKEN_OP_POSTFIX) {
is_postfix = 1;
} else {
libab_operator* operator;
char op_buffer[8];
_parser_extract_token_buffer(state, op_buffer, 8, match);
operator = libab_table_search_operator(state->base_table, op_buffer, TOKEN_OP_POSTFIX);
operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_POSTFIX);
if(operator) is_postfix = 1;
}
return is_postfix;
}
int _parser_match_is_prefix_op(struct parser_state* state, libab_lexer_match* match) {
int is_prefix = 0;
if(match->type == TOKEN_OP_PREFIX) {
is_prefix = 1;
} else {
libab_operator* operator;
char op_buffer[8];
_parser_extract_token_buffer(state, op_buffer, 8, match);
operator = libab_table_search_operator(state->base_table, op_buffer, TOKEN_OP_PREFIX);
operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_PREFIX);
if(operator) is_prefix = 1;
}
return is_prefix;
}
int _parser_match_is_infix_op(struct parser_state* state, libab_lexer_match* match) {
int is_infix = 0;
if(match->type == TOKEN_OP_INFIX || match->type == TOKEN_OP_RESERVED) {
if(match->type == TOKEN_OP_RESERVED) {
is_infix = 1;
} else {
libab_operator* operator;
char op_buffer[8];
_parser_extract_token_buffer(state, op_buffer, 8, match);
operator = libab_table_search_operator(state->base_table, op_buffer, TOKEN_OP_INFIX);
operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_INFIX);
if(operator) is_infix = 1;
}
return is_infix;
@ -946,6 +939,7 @@ libab_result _parse_expression(struct parser_state* state, libab_tree** store_in
_parser_state_step(state);
new_type = EXPR_OP_POSTFIX;
} else if(_parser_match_is_infix_op(state, new_token)) {
if(new_token->type == TOKEN_OP)
new_token->type = TOKEN_OP_INFIX;
_parser_find_operator_infix(state, new_token, &operator);
_parser_state_step(state);

View File

@ -29,17 +29,17 @@ libab_table_entry* libab_table_search(libab_table* table, const char* string) {
return entry->variant == ENTRY_OP && entry->data_u.op.type == TYPE;\
}
OP_TYPE_COMPARATOR(_table_compare_prefix, TOKEN_OP_PREFIX)
OP_TYPE_COMPARATOR(_table_compare_infix, TOKEN_OP_INFIX)
OP_TYPE_COMPARATOR(_table_compare_postfix, TOKEN_OP_POSTFIX)
OP_TYPE_COMPARATOR(_table_compare_prefix, OPERATOR_PREFIX)
OP_TYPE_COMPARATOR(_table_compare_infix, OPERATOR_INFIX)
OP_TYPE_COMPARATOR(_table_compare_postfix, OPERATOR_POSTFIX)
libab_operator* libab_table_search_operator(libab_table* table, const char* string, int type) {
libab_table_entry* entry = NULL;
if(type == TOKEN_OP_PREFIX) {
if(type == OPERATOR_PREFIX) {
entry = libab_table_search_filter(table, string, NULL, _table_compare_prefix);
} else if(type == TOKEN_OP_INFIX) {
} else if(type == OPERATOR_INFIX) {
entry = libab_table_search_filter(table, string, NULL, _table_compare_infix);
} else if(type == TOKEN_OP_POSTFIX) {
} else if(type == OPERATOR_PREFIX) {
entry = libab_table_search_filter(table, string, NULL, _table_compare_postfix);
}
return entry ? &entry->data_u.op : NULL;