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)(); 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 * The common information
* that both operators and functions shared. * that both operators and functions shared.
@ -34,7 +44,7 @@ struct libab_operator_s {
* Corresponds to token types associated with * Corresponds to token types associated with
* each operator. * each operator.
*/ */
int type; enum libab_operator_variant_e type;
/** /**
* The precedence of the operator. * The precedence of the operator.
*/ */
@ -61,6 +71,7 @@ struct libab_function_s {
struct libab_behavior_s behavior; struct libab_behavior_s behavior;
}; };
typedef enum libab_operator_variant_e libab_operator_variant;
typedef struct libab_behavior_s libab_behavior; typedef struct libab_behavior_s libab_behavior;
typedef struct libab_operator_s libab_operator; typedef struct libab_operator_s libab_operator;
typedef struct libab_function_s libab_function; typedef struct libab_function_s libab_function;

View File

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

View File

@ -49,7 +49,7 @@ libab_result _initialize_behavior(libab* ab, libab_behavior* behavior,
return result; 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]; char op_buffer[8];
libab_result result = LIBAB_SUCCESS; libab_result result = LIBAB_SUCCESS;
libab_table_entry* new_entry; 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) { if(result == LIBAB_SUCCESS) {
_sanitize(op_buffer, op, 8); _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) { 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(result != LIBAB_SUCCESS) {
if(new_entry && new_entry->data_u.op.behavior.type) if(new_entry && new_entry->data_u.op.behavior.type)
libab_parsetype_free_recursive(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); 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) { 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) { 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) { 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) { 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 // Expression-specific utility functions
int _parser_match_is_op(libab_lexer_match* match) { 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_PREFIX ||
match->type == TOKEN_OP_POSTFIX || match->type == TOKEN_OP_POSTFIX ||
match->type == TOKEN_OP_RESERVED; 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]; char op_buffer[8];
_parser_extract_token_buffer(state, op_buffer, 8, match); _parser_extract_token_buffer(state, op_buffer, 8, match);
if(match->type != TOKEN_OP_RESERVED) { 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->associativity = operator->associativity;
data->precedence = operator->precedence; data->precedence = operator->precedence;
} else { } 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 _parser_match_is_postfix_op(struct parser_state* state, libab_lexer_match* match) {
int is_postfix = 0; int is_postfix = 0;
if(match->type == TOKEN_OP_POSTFIX) { libab_operator* operator;
is_postfix = 1; char op_buffer[8];
} else { _parser_extract_token_buffer(state, op_buffer, 8, match);
libab_operator* operator; operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_POSTFIX);
char op_buffer[8]; if(operator) is_postfix = 1;
_parser_extract_token_buffer(state, op_buffer, 8, match);
operator = libab_table_search_operator(state->base_table, op_buffer, TOKEN_OP_POSTFIX);
if(operator) is_postfix = 1;
}
return is_postfix; return is_postfix;
} }
int _parser_match_is_prefix_op(struct parser_state* state, libab_lexer_match* match) { int _parser_match_is_prefix_op(struct parser_state* state, libab_lexer_match* match) {
int is_prefix = 0; int is_prefix = 0;
if(match->type == TOKEN_OP_PREFIX) { libab_operator* operator;
is_prefix = 1; char op_buffer[8];
} else { _parser_extract_token_buffer(state, op_buffer, 8, match);
libab_operator* operator; operator = libab_table_search_operator(state->base_table, op_buffer, OPERATOR_PREFIX);
char op_buffer[8]; if(operator) is_prefix = 1;
_parser_extract_token_buffer(state, op_buffer, 8, match);
operator = libab_table_search_operator(state->base_table, op_buffer, TOKEN_OP_PREFIX);
if(operator) is_prefix = 1;
}
return is_prefix; return is_prefix;
} }
int _parser_match_is_infix_op(struct parser_state* state, libab_lexer_match* match) { int _parser_match_is_infix_op(struct parser_state* state, libab_lexer_match* match) {
int is_infix = 0; int is_infix = 0;
if(match->type == TOKEN_OP_INFIX || match->type == TOKEN_OP_RESERVED) { if(match->type == TOKEN_OP_RESERVED) {
is_infix = 1; is_infix = 1;
} else { } else {
libab_operator* operator; libab_operator* operator;
char op_buffer[8]; char op_buffer[8];
_parser_extract_token_buffer(state, op_buffer, 8, match); _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; if(operator) is_infix = 1;
} }
return is_infix; return is_infix;
@ -946,7 +939,8 @@ libab_result _parse_expression(struct parser_state* state, libab_tree** store_in
_parser_state_step(state); _parser_state_step(state);
new_type = EXPR_OP_POSTFIX; new_type = EXPR_OP_POSTFIX;
} else if(_parser_match_is_infix_op(state, new_token)) { } else if(_parser_match_is_infix_op(state, new_token)) {
new_token->type = TOKEN_OP_INFIX; if(new_token->type == TOKEN_OP)
new_token->type = TOKEN_OP_INFIX;
_parser_find_operator_infix(state, new_token, &operator); _parser_find_operator_infix(state, new_token, &operator);
_parser_state_step(state); _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;\ 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_prefix, OPERATOR_PREFIX)
OP_TYPE_COMPARATOR(_table_compare_infix, TOKEN_OP_INFIX) OP_TYPE_COMPARATOR(_table_compare_infix, OPERATOR_INFIX)
OP_TYPE_COMPARATOR(_table_compare_postfix, TOKEN_OP_POSTFIX) OP_TYPE_COMPARATOR(_table_compare_postfix, OPERATOR_POSTFIX)
libab_operator* libab_table_search_operator(libab_table* table, const char* string, int type) { libab_operator* libab_table_search_operator(libab_table* table, const char* string, int type) {
libab_table_entry* entry = NULL; 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); 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); 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); entry = libab_table_search_filter(table, string, NULL, _table_compare_postfix);
} }
return entry ? &entry->data_u.op : NULL; return entry ? &entry->data_u.op : NULL;