diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-04-11 02:54:44 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2015-04-11 03:00:00 +0200 |
commit | 42f74c83bf53d60d25408e6afb8aa92ca23e0a16 (patch) | |
tree | 357dc29cf3114a35015f47368e6177247bdc546e | |
parent | 69d5b76e1a56a0e2f537b06b133921b45f490371 (diff) | |
download | solar-42f74c83bf53d60d25408e6afb8aa92ca23e0a16.tar solar-42f74c83bf53d60d25408e6afb8aa92ca23e0a16.zip |
Add support for destructors
-rw-r--r-- | src/grammar.hpp | 2 | ||||
-rw-r--r-- | src/output.cpp | 2 | ||||
-rw-r--r-- | src/output_lr0.cpp | 13 | ||||
-rw-r--r-- | src/output_slr.cpp | 13 | ||||
-rw-r--r-- | src/parse.cpp | 645 | ||||
-rw-r--r-- | src/parse.y | 121 |
6 files changed, 520 insertions, 276 deletions
diff --git a/src/grammar.hpp b/src/grammar.hpp index e603d00..b54b46d 100644 --- a/src/grammar.hpp +++ b/src/grammar.hpp @@ -39,6 +39,8 @@ struct grammar_t { std::map<std::string, std::string> nonterm_types; std::map<symbol_t, std::pair<std::string, std::string>> term_types; + std::map<symbol_t, std::string> destructors; + std::string header_block; std::string source_block; diff --git a/src/output.cpp b/src/output.cpp index 1503c38..fee9267 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -307,6 +307,8 @@ void output_t::emit_source() { std::fprintf(source_file, ", %s %s", arg.first.c_str(), arg.second.c_str()); std::fprintf(source_file, ") {\n"); + std::fprintf(source_file, "\t%ssymbol_value_t result;\n\n", prefix()); + std::fprintf(source_file, "\twhile (1) {\n"); std::fprintf(source_file, "\t\tswitch (parser->stack[parser->top].state) {\n"); diff --git a/src/output_lr0.cpp b/src/output_lr0.cpp index 62c5966..5d0c882 100644 --- a/src/output_lr0.cpp +++ b/src/output_lr0.cpp @@ -63,7 +63,7 @@ void output_lr0_t::emit_state_reduce(const item_t &item, int rule_id) { std::fprintf(source_file, "\t\t\t"); if (!type.empty()) - std::fprintf(source_file, "parser->stack[parser->top].value.symbol_%s = ", item.get_lhs().c_str()); + std::fprintf(source_file, "result.symbol_%s = ", item.get_lhs().c_str()); std::fprintf(source_file, "%sreduce_%i(", prefix(), rule_id); bool empty = true; @@ -90,6 +90,17 @@ void output_lr0_t::emit_state_reduce(const item_t &item, int rule_id) { } std::fprintf(source_file, ");\n"); + + for (unsigned i = 0; i < rhs.size(); i++) { + auto it = generator->get_grammar().destructors.find(rhs[i]); + if (it == generator->get_grammar().destructors.end()) + continue; + + std::fprintf(source_file, "\t\t\t%s(parser->stack[parser->top + %u].value.%s);\n", it->second.c_str(), i, symbol_values[rhs[i]].c_str()); + } + + if (!type.empty()) + std::fprintf(source_file, "\t\t\tparser->stack[parser->top].value.symbol_%s = result.symbol_%s;\n", item.get_lhs().c_str(), item.get_lhs().c_str()); } emit_gotos(item.get_lhs()); diff --git a/src/output_slr.cpp b/src/output_slr.cpp index 1acd951..d2b9817 100644 --- a/src/output_slr.cpp +++ b/src/output_slr.cpp @@ -60,7 +60,7 @@ void output_slr_t::emit_state_reduce_code(const item_t &item, int rule_id) { std::fprintf(source_file, "\t\t\t\t"); if (!type.empty()) - std::fprintf(source_file, "parser->stack[parser->top].value.symbol_%s = ", item.get_lhs().c_str()); + std::fprintf(source_file, "result.symbol_%s = ", item.get_lhs().c_str()); std::fprintf(source_file, "%sreduce_%i(", prefix(), rule_id); bool empty = true; @@ -87,6 +87,17 @@ void output_slr_t::emit_state_reduce_code(const item_t &item, int rule_id) { } std::fprintf(source_file, ");\n"); + + for (unsigned i = 0; i < rhs.size(); i++) { + auto it = generator->get_grammar().destructors.find(rhs[i]); + if (it == generator->get_grammar().destructors.end()) + continue; + + std::fprintf(source_file, "\t\t\t\t%s(parser->stack[parser->top + %u].value.%s);\n", it->second.c_str(), i, symbol_values[rhs[i]].c_str()); + } + + if (!type.empty()) + std::fprintf(source_file, "\t\t\t\tparser->stack[parser->top].value.symbol_%s = result.symbol_%s;\n", item.get_lhs().c_str(), item.get_lhs().c_str()); } emit_gotos(item.get_lhs()); diff --git a/src/parse.cpp b/src/parse.cpp index faf9618..35b6f8f 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -1,5 +1,19 @@ #include "parse.hpp" + +static inline void free_string(std::string *v) { + delete v; +} + +static inline void free_symbol(solar::symbol_t *v) { + delete v; +} + +static inline void free_rule(solar::rule_t *v) { + delete v; +} + + typedef union parse_symbol_value { parse_token_value_t token; std::string * symbol_action; @@ -32,138 +46,116 @@ void parse_free(parse_context_t *parser, void (*free_func)(void *)) { free_func(parser); } -static inline void parse_reduce_3(solar::rule_t * rule, __attribute__((unused)) solar::grammar_t * grammar) { - if (grammar->rules.empty()) { - solar::item_t init(""); - init.get_rhs().push_back(solar::symbol_t::make_nonterm(rule->item.get_lhs().c_str())); - grammar->rules.emplace_back(solar::rule_t {std::move(init), std::vector<std::string>(), std::string()}); - } - - grammar->rules.push_back(*rule); - delete rule; -} - -static inline void parse_reduce_4(std::string * nonterm, std::string * type, __attribute__((unused)) solar::grammar_t * grammar) { +static inline void parse_reduce_3(std::string * nonterm, std::string * type, __attribute__((unused)) solar::grammar_t * grammar) { grammar->nonterm_types.insert(std::make_pair(*nonterm, *type)); - - delete nonterm; - delete type; } -static inline void parse_reduce_5(solar::symbol_t * term, std::string * type, std::string * name, __attribute__((unused)) solar::grammar_t * grammar) { +static inline void parse_reduce_4(solar::symbol_t * term, std::string * type, std::string * name, __attribute__((unused)) solar::grammar_t * grammar) { grammar->term_types.insert(std::make_pair(*term, std::make_pair(*type, *name))); +} - delete term; - delete type; - delete name; +static inline void parse_reduce_5(solar::symbol_t * sym, std::string * name, __attribute__((unused)) solar::grammar_t * grammar) { + grammar->destructors.insert(std::make_pair(*sym, *name)); } static inline void parse_reduce_6(std::string * block, __attribute__((unused)) solar::grammar_t * grammar) { grammar->source_block = *block; - delete block; } static inline void parse_reduce_7(std::string * block, __attribute__((unused)) solar::grammar_t * grammar) { grammar->header_block = *block; - delete block; } static inline void parse_reduce_8(std::string * type, std::string * name, __attribute__((unused)) solar::grammar_t * grammar) { grammar->extra_args.push_back(std::make_pair(*type, *name)); +} + +static inline void parse_reduce_9(solar::rule_t * rule, __attribute__((unused)) solar::grammar_t * grammar) { + if (grammar->rules.empty()) { + solar::item_t init(""); + init.get_rhs().push_back(solar::symbol_t::make_nonterm(rule->item.get_lhs().c_str())); + grammar->rules.emplace_back(solar::rule_t {std::move(init), std::vector<std::string>(), std::string()}); + } - delete type; - delete name; + grammar->rules.push_back(*rule); } -static inline solar::rule_t * parse_reduce_9(std::string * lhs, std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * rhs, std::string * action, __attribute__((unused)) solar::grammar_t * grammar) { +static inline solar::rule_t * parse_reduce_10(std::string * lhs, std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * rhs, std::string * action, __attribute__((unused)) solar::grammar_t * grammar) { auto *ret = new solar::rule_t {solar::item_t(*lhs, rhs->first), rhs->second, *action}; - - delete lhs; delete rhs; - delete action; - return ret; } -static inline std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * parse_reduce_10(__attribute__((unused)) solar::grammar_t * grammar) { +static inline std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * parse_reduce_11(__attribute__((unused)) solar::grammar_t * grammar) { return new std::pair<std::vector<solar::symbol_t>, std::vector<std::string>>(); } -static inline std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * parse_reduce_11(std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * rhs, solar::symbol_t * sym, __attribute__((unused)) solar::grammar_t * grammar) { +static inline std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * parse_reduce_12(std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * rhs, solar::symbol_t * sym, __attribute__((unused)) solar::grammar_t * grammar) { rhs->first.push_back(*sym); rhs->second.emplace_back(); - delete sym; return rhs; } -static inline std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * parse_reduce_12(std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * rhs, solar::symbol_t * sym, std::string * var, __attribute__((unused)) solar::grammar_t * grammar) { +static inline std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * parse_reduce_13(std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * rhs, solar::symbol_t * sym, std::string * var, __attribute__((unused)) solar::grammar_t * grammar) { rhs->first.push_back(*sym); rhs->second.push_back(*var); - delete sym; - delete var; - return rhs; } -static inline std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * parse_reduce_13(std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * rhs, std::string * str, __attribute__((unused)) solar::grammar_t * grammar) { +static inline std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * parse_reduce_14(std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> * rhs, std::string * str, __attribute__((unused)) solar::grammar_t * grammar) { for (char c : *str) { rhs->first.push_back(solar::symbol_t::make_char(c)); rhs->second.emplace_back(); } - delete str; - return rhs; } -static inline std::string * parse_reduce_14(__attribute__((unused)) solar::grammar_t * grammar) { +static inline std::string * parse_reduce_15(__attribute__((unused)) solar::grammar_t * grammar) { return new std::string; } -static inline std::string * parse_reduce_15(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) { - return v; -} - static inline std::string * parse_reduce_16(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) { - *v = "\n\treturn " + *v + ";\n"; - return v; + return new std::string(*v); } -static inline solar::symbol_t * parse_reduce_17(solar::symbol_t * v, __attribute__((unused)) solar::grammar_t * grammar) { - return v; +static inline std::string * parse_reduce_17(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) { + return new std::string("\n\treturn " + *v + ";\n"); } -static inline solar::symbol_t * parse_reduce_18(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) { - solar::symbol_t *ret = new solar::symbol_t(solar::symbol_t::make_nonterm(*v)); - delete v; - return ret; +static inline solar::symbol_t * parse_reduce_18(solar::symbol_t * v, __attribute__((unused)) solar::grammar_t * grammar) { + return new solar::symbol_t(*v); } static inline solar::symbol_t * parse_reduce_19(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) { - solar::symbol_t *ret = new solar::symbol_t(solar::symbol_t::make_term(*v)); - delete v; - return ret; + return new solar::symbol_t(solar::symbol_t::make_nonterm(*v)); } -static inline solar::symbol_t * parse_reduce_20(char v, __attribute__((unused)) solar::grammar_t * grammar) { - return new solar::symbol_t(solar::symbol_t::make_char(v)); +static inline solar::symbol_t * parse_reduce_20(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) { + return new solar::symbol_t(solar::symbol_t::make_term(*v)); } -static inline std::string * parse_reduce_21(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) { - return v; +static inline solar::symbol_t * parse_reduce_21(char v, __attribute__((unused)) solar::grammar_t * grammar) { + return new solar::symbol_t(solar::symbol_t::make_char(v)); } static inline std::string * parse_reduce_22(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) { - return v; + return new std::string(*v); } static inline std::string * parse_reduce_23(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) { - return v; + return new std::string(*v); +} + +static inline std::string * parse_reduce_24(std::string * v, __attribute__((unused)) solar::grammar_t * grammar) { + return new std::string(*v); } static int parse_do_push(parse_context_t *parser, int token, __attribute__((unused)) solar::grammar_t * grammar) { + parse_symbol_value_t result; + while (1) { switch (parser->stack[parser->top].state) { case 0: @@ -203,7 +195,8 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus switch (token) { default: parser->top -= 1; - parse_reduce_3(parser->stack[parser->top + 0].value.symbol_rule, grammar); + parse_reduce_9(parser->stack[parser->top + 0].value.symbol_rule, grammar); + free_rule(parser->stack[parser->top + 0].value.symbol_rule); parser->stack[++parser->top].state = 2; } break; @@ -221,22 +214,26 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 5: switch (token) { - case 'e': + case 'd': parser->stack[++parser->top].state = 7; return 1; - case 'h': + case 'e': parser->stack[++parser->top].state = 8; return 1; - case 's': + case 'h': parser->stack[++parser->top].state = 9; return 1; - case 't': + case 's': parser->stack[++parser->top].state = 10; return 1; + case 't': + parser->stack[++parser->top].state = 11; + return 1; + default: return -1; } @@ -245,7 +242,7 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 6: switch (token) { case '=': - parser->stack[++parser->top].state = 11; + parser->stack[++parser->top].state = 12; return 1; default: @@ -255,8 +252,8 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 7: switch (token) { - case 'x': - parser->stack[++parser->top].state = 12; + case 'e': + parser->stack[++parser->top].state = 13; return 1; default: @@ -266,8 +263,8 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 8: switch (token) { - case 'e': - parser->stack[++parser->top].state = 13; + case 'x': + parser->stack[++parser->top].state = 14; return 1; default: @@ -277,8 +274,8 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 9: switch (token) { - case 'o': - parser->stack[++parser->top].state = 14; + case 'e': + parser->stack[++parser->top].state = 15; return 1; default: @@ -288,8 +285,8 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 10: switch (token) { - case 'y': - parser->stack[++parser->top].state = 15; + case 'o': + parser->stack[++parser->top].state = 16; return 1; default: @@ -299,16 +296,39 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus case 11: switch (token) { + case 'y': + parser->stack[++parser->top].state = 17; + return 1; + default: - parser->stack[parser->top].value.symbol_rhs = parse_reduce_10(grammar); - parser->stack[++parser->top].state = 16; + return -1; } break; case 12: switch (token) { + default: + result.symbol_rhs = parse_reduce_11(grammar); + parser->stack[parser->top].value.symbol_rhs = result.symbol_rhs; + parser->stack[++parser->top].state = 18; + } + break; + + case 13: + switch (token) { + case 's': + parser->stack[++parser->top].state = 19; + return 1; + + default: + return -1; + } + break; + + case 14: + switch (token) { case 't': - parser->stack[++parser->top].state = 17; + parser->stack[++parser->top].state = 20; return 1; default: @@ -316,10 +336,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 13: + case 15: switch (token) { case 'a': - parser->stack[++parser->top].state = 18; + parser->stack[++parser->top].state = 21; return 1; default: @@ -327,10 +347,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 14: + case 16: switch (token) { case 'u': - parser->stack[++parser->top].state = 19; + parser->stack[++parser->top].state = 22; return 1; default: @@ -338,10 +358,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 15: + case 17: switch (token) { case 'p': - parser->stack[++parser->top].state = 20; + parser->stack[++parser->top].state = 23; return 1; default: @@ -349,34 +369,34 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 16: + case 18: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 24; + parser->stack[++parser->top].state = 27; return 1; case TOK_CHAR: - parser->stack[++parser->top].state = 25; + parser->stack[++parser->top].state = 28; return 1; case TOK_SQBLOCK: - parser->stack[++parser->top].state = 26; + parser->stack[++parser->top].state = 29; return 1; case TOK_STRING: - parser->stack[++parser->top].state = 27; + parser->stack[++parser->top].state = 30; return 1; case TOK_SYMBOL_LC: - parser->stack[++parser->top].state = 28; + parser->stack[++parser->top].state = 31; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 29; + parser->stack[++parser->top].state = 32; return 1; case ';': - parser->stack[++parser->top].state = 30; + parser->stack[++parser->top].state = 33; return 1; default: @@ -384,10 +404,21 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 17: + case 19: + switch (token) { + case 't': + parser->stack[++parser->top].state = 34; + return 1; + + default: + return -1; + } + break; + + case 20: switch (token) { case 'r': - parser->stack[++parser->top].state = 31; + parser->stack[++parser->top].state = 35; return 1; default: @@ -395,10 +426,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 18: + case 21: switch (token) { case 'd': - parser->stack[++parser->top].state = 32; + parser->stack[++parser->top].state = 36; return 1; default: @@ -406,10 +437,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 19: + case 22: switch (token) { case 'r': - parser->stack[++parser->top].state = 33; + parser->stack[++parser->top].state = 37; return 1; default: @@ -417,10 +448,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 20: + case 23: switch (token) { case 'e': - parser->stack[++parser->top].state = 34; + parser->stack[++parser->top].state = 38; return 1; default: @@ -428,122 +459,172 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 21: + case 24: switch (token) { default: parser->top -= 5; - parser->stack[parser->top].value.symbol_rule = parse_reduce_9(parser->stack[parser->top + 0].value.token.str, parser->stack[parser->top + 3].value.symbol_rhs, parser->stack[parser->top + 4].value.symbol_action, grammar); + result.symbol_rule = parse_reduce_10(parser->stack[parser->top + 0].value.token.str, parser->stack[parser->top + 3].value.symbol_rhs, parser->stack[parser->top + 4].value.symbol_action, grammar); + free_string(parser->stack[parser->top + 0].value.token.str); + free_string(parser->stack[parser->top + 4].value.symbol_action); + parser->stack[parser->top].value.symbol_rule = result.symbol_rule; parser->stack[++parser->top].state = 3; } break; - case 22: + case 25: switch (token) { case '(': - parser->stack[++parser->top].state = 35; + parser->stack[++parser->top].state = 39; return 1; default: parser->top -= 2; - parser->stack[parser->top].value.symbol_rhs = parse_reduce_11(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, grammar); - parser->stack[++parser->top].state = 16; + result.symbol_rhs = parse_reduce_12(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, grammar); + free_symbol(parser->stack[parser->top + 1].value.symbol_symbol); + parser->stack[parser->top].value.symbol_rhs = result.symbol_rhs; + parser->stack[++parser->top].state = 18; } break; - case 23: + case 26: switch (token) { default: parser->top -= 1; - parser->stack[parser->top].value.symbol_symbol = parse_reduce_17(parser->stack[parser->top + 0].value.symbol_term, grammar); - parser->stack[++parser->top].state = 22; + result.symbol_symbol = parse_reduce_18(parser->stack[parser->top + 0].value.symbol_term, grammar); + free_symbol(parser->stack[parser->top + 0].value.symbol_term); + parser->stack[parser->top].value.symbol_symbol = result.symbol_symbol; + switch (parser->stack[parser->top].state) { + case 18: + parser->stack[++parser->top].state = 25; + break; + + case 66: + parser->stack[++parser->top].state = 68; + break; + + } } break; - case 24: + case 27: switch (token) { default: parser->top -= 1; - parser->stack[parser->top].value.symbol_action = parse_reduce_15(parser->stack[parser->top + 0].value.token.str, grammar); - parser->stack[++parser->top].state = 21; + result.symbol_action = parse_reduce_16(parser->stack[parser->top + 0].value.token.str, grammar); + free_string(parser->stack[parser->top + 0].value.token.str); + parser->stack[parser->top].value.symbol_action = result.symbol_action; + parser->stack[++parser->top].state = 24; } break; - case 25: + case 28: switch (token) { default: parser->top -= 1; - parser->stack[parser->top].value.symbol_term = parse_reduce_20(parser->stack[parser->top + 0].value.token.c, grammar); + result.symbol_term = parse_reduce_21(parser->stack[parser->top + 0].value.token.c, grammar); + parser->stack[parser->top].value.symbol_term = result.symbol_term; switch (parser->stack[parser->top].state) { - case 16: - parser->stack[++parser->top].state = 23; + case 18: + case 66: + parser->stack[++parser->top].state = 26; break; - case 34: - parser->stack[++parser->top].state = 39; + case 38: + parser->stack[++parser->top].state = 44; break; } } break; - case 26: + case 29: switch (token) { default: parser->top -= 1; - parser->stack[parser->top].value.symbol_action = parse_reduce_16(parser->stack[parser->top + 0].value.token.str, grammar); - parser->stack[++parser->top].state = 21; + result.symbol_action = parse_reduce_17(parser->stack[parser->top + 0].value.token.str, grammar); + free_string(parser->stack[parser->top + 0].value.token.str); + parser->stack[parser->top].value.symbol_action = result.symbol_action; + parser->stack[++parser->top].state = 24; } break; - case 27: + case 30: switch (token) { default: parser->top -= 2; - parser->stack[parser->top].value.symbol_rhs = parse_reduce_13(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.token.str, grammar); - parser->stack[++parser->top].state = 16; + result.symbol_rhs = parse_reduce_14(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.token.str, grammar); + free_string(parser->stack[parser->top + 1].value.token.str); + parser->stack[parser->top].value.symbol_rhs = result.symbol_rhs; + parser->stack[++parser->top].state = 18; } break; - case 28: + case 31: switch (token) { default: parser->top -= 1; - parser->stack[parser->top].value.symbol_symbol = parse_reduce_18(parser->stack[parser->top + 0].value.token.str, grammar); - parser->stack[++parser->top].state = 22; + result.symbol_symbol = parse_reduce_19(parser->stack[parser->top + 0].value.token.str, grammar); + free_string(parser->stack[parser->top + 0].value.token.str); + parser->stack[parser->top].value.symbol_symbol = result.symbol_symbol; + switch (parser->stack[parser->top].state) { + case 18: + parser->stack[++parser->top].state = 25; + break; + + case 66: + parser->stack[++parser->top].state = 68; + break; + + } } break; - case 29: + case 32: switch (token) { default: parser->top -= 1; - parser->stack[parser->top].value.symbol_term = parse_reduce_19(parser->stack[parser->top + 0].value.token.str, grammar); + result.symbol_term = parse_reduce_20(parser->stack[parser->top + 0].value.token.str, grammar); + free_string(parser->stack[parser->top + 0].value.token.str); + parser->stack[parser->top].value.symbol_term = result.symbol_term; switch (parser->stack[parser->top].state) { - case 16: - parser->stack[++parser->top].state = 23; + case 18: + case 66: + parser->stack[++parser->top].state = 26; break; - case 34: - parser->stack[++parser->top].state = 39; + case 38: + parser->stack[++parser->top].state = 44; break; } } break; - case 30: + case 33: switch (token) { default: parser->top -= 1; - parser->stack[parser->top].value.symbol_action = parse_reduce_14(grammar); - parser->stack[++parser->top].state = 21; + result.symbol_action = parse_reduce_15(grammar); + parser->stack[parser->top].value.symbol_action = result.symbol_action; + parser->stack[++parser->top].state = 24; } break; - case 31: + case 34: + switch (token) { + case 'r': + parser->stack[++parser->top].state = 40; + return 1; + + default: + return -1; + } + break; + + case 35: switch (token) { case 'a': - parser->stack[++parser->top].state = 36; + parser->stack[++parser->top].state = 41; return 1; default: @@ -551,10 +632,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 32: + case 36: switch (token) { case 'e': - parser->stack[++parser->top].state = 37; + parser->stack[++parser->top].state = 42; return 1; default: @@ -562,10 +643,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 33: + case 37: switch (token) { case 'c': - parser->stack[++parser->top].state = 38; + parser->stack[++parser->top].state = 43; return 1; default: @@ -573,18 +654,18 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 34: + case 38: switch (token) { case TOK_CHAR: - parser->stack[++parser->top].state = 25; + parser->stack[++parser->top].state = 28; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 29; + parser->stack[++parser->top].state = 32; return 1; case TOK_SYMBOL_LC: - parser->stack[++parser->top].state = 40; + parser->stack[++parser->top].state = 45; return 1; default: @@ -592,18 +673,18 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 35: + case 39: switch (token) { case TOK_SYMBOL: - parser->stack[++parser->top].state = 42; + parser->stack[++parser->top].state = 47; return 1; case TOK_SYMBOL_LC: - parser->stack[++parser->top].state = 43; + parser->stack[++parser->top].state = 48; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 44; + parser->stack[++parser->top].state = 49; return 1; default: @@ -611,10 +692,21 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 36: + case 40: + switch (token) { + case 'u': + parser->stack[++parser->top].state = 50; + return 1; + + default: + return -1; + } + break; + + case 41: switch (token) { case '_': - parser->stack[++parser->top].state = 45; + parser->stack[++parser->top].state = 51; return 1; default: @@ -622,10 +714,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 37: + case 42: switch (token) { case 'r': - parser->stack[++parser->top].state = 46; + parser->stack[++parser->top].state = 52; return 1; default: @@ -633,10 +725,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 38: + case 43: switch (token) { case 'e': - parser->stack[++parser->top].state = 47; + parser->stack[++parser->top].state = 53; return 1; default: @@ -644,10 +736,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 39: + case 44: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 48; + parser->stack[++parser->top].state = 54; return 1; default: @@ -655,10 +747,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 40: + case 45: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 49; + parser->stack[++parser->top].state = 55; return 1; default: @@ -666,10 +758,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 41: + case 46: switch (token) { case ')': - parser->stack[++parser->top].state = 50; + parser->stack[++parser->top].state = 56; return 1; default: @@ -677,76 +769,105 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 42: + case 47: switch (token) { default: parser->top -= 1; - parser->stack[parser->top].value.symbol_varname = parse_reduce_23(parser->stack[parser->top + 0].value.token.str, grammar); + result.symbol_varname = parse_reduce_24(parser->stack[parser->top + 0].value.token.str, grammar); + free_string(parser->stack[parser->top + 0].value.token.str); + parser->stack[parser->top].value.symbol_varname = result.symbol_varname; switch (parser->stack[parser->top].state) { - case 35: - parser->stack[++parser->top].state = 41; + case 39: + parser->stack[++parser->top].state = 46; break; - case 48: - parser->stack[++parser->top].state = 54; + case 54: + parser->stack[++parser->top].state = 61; break; - case 57: - parser->stack[++parser->top].state = 58; + case 67: + parser->stack[++parser->top].state = 69; + break; + + case 68: + parser->stack[++parser->top].state = 70; break; } } break; - case 43: + case 48: switch (token) { default: parser->top -= 1; - parser->stack[parser->top].value.symbol_varname = parse_reduce_21(parser->stack[parser->top + 0].value.token.str, grammar); + result.symbol_varname = parse_reduce_22(parser->stack[parser->top + 0].value.token.str, grammar); + free_string(parser->stack[parser->top + 0].value.token.str); + parser->stack[parser->top].value.symbol_varname = result.symbol_varname; switch (parser->stack[parser->top].state) { - case 35: - parser->stack[++parser->top].state = 41; + case 39: + parser->stack[++parser->top].state = 46; + break; + + case 54: + parser->stack[++parser->top].state = 61; break; - case 48: - parser->stack[++parser->top].state = 54; + case 67: + parser->stack[++parser->top].state = 69; break; - case 57: - parser->stack[++parser->top].state = 58; + case 68: + parser->stack[++parser->top].state = 70; break; } } break; - case 44: + case 49: switch (token) { default: parser->top -= 1; - parser->stack[parser->top].value.symbol_varname = parse_reduce_22(parser->stack[parser->top + 0].value.token.str, grammar); + result.symbol_varname = parse_reduce_23(parser->stack[parser->top + 0].value.token.str, grammar); + free_string(parser->stack[parser->top + 0].value.token.str); + parser->stack[parser->top].value.symbol_varname = result.symbol_varname; switch (parser->stack[parser->top].state) { - case 35: - parser->stack[++parser->top].state = 41; + case 39: + parser->stack[++parser->top].state = 46; + break; + + case 54: + parser->stack[++parser->top].state = 61; break; - case 48: - parser->stack[++parser->top].state = 54; + case 67: + parser->stack[++parser->top].state = 69; break; - case 57: - parser->stack[++parser->top].state = 58; + case 68: + parser->stack[++parser->top].state = 70; break; } } break; - case 45: + case 50: + switch (token) { + case 'c': + parser->stack[++parser->top].state = 57; + return 1; + + default: + return -1; + } + break; + + case 51: switch (token) { case 'a': - parser->stack[++parser->top].state = 51; + parser->stack[++parser->top].state = 58; return 1; default: @@ -754,10 +875,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 46: + case 52: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 52; + parser->stack[++parser->top].state = 59; return 1; default: @@ -765,10 +886,10 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 47: + case 53: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 53; + parser->stack[++parser->top].state = 60; return 1; default: @@ -776,18 +897,18 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 48: + case 54: switch (token) { case TOK_SYMBOL: - parser->stack[++parser->top].state = 42; + parser->stack[++parser->top].state = 47; return 1; case TOK_SYMBOL_LC: - parser->stack[++parser->top].state = 43; + parser->stack[++parser->top].state = 48; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 44; + parser->stack[++parser->top].state = 49; return 1; default: @@ -795,28 +916,44 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 49: + case 55: switch (token) { default: parser->top -= 7; - parse_reduce_4(parser->stack[parser->top + 5].value.token.str, parser->stack[parser->top + 6].value.token.str, grammar); + parse_reduce_3(parser->stack[parser->top + 5].value.token.str, parser->stack[parser->top + 6].value.token.str, grammar); + free_string(parser->stack[parser->top + 5].value.token.str); + free_string(parser->stack[parser->top + 6].value.token.str); parser->stack[++parser->top].state = 2; } break; - case 50: + case 56: switch (token) { default: parser->top -= 5; - parser->stack[parser->top].value.symbol_rhs = parse_reduce_12(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, parser->stack[parser->top + 3].value.symbol_varname, grammar); - parser->stack[++parser->top].state = 16; + result.symbol_rhs = parse_reduce_13(parser->stack[parser->top + 0].value.symbol_rhs, parser->stack[parser->top + 1].value.symbol_symbol, parser->stack[parser->top + 3].value.symbol_varname, grammar); + free_symbol(parser->stack[parser->top + 1].value.symbol_symbol); + free_string(parser->stack[parser->top + 3].value.symbol_varname); + parser->stack[parser->top].value.symbol_rhs = result.symbol_rhs; + parser->stack[++parser->top].state = 18; } break; - case 51: + case 57: + switch (token) { + case 't': + parser->stack[++parser->top].state = 62; + return 1; + + default: + return -1; + } + break; + + case 58: switch (token) { case 'r': - parser->stack[++parser->top].state = 55; + parser->stack[++parser->top].state = 63; return 1; default: @@ -824,37 +961,53 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 52: + case 59: switch (token) { default: parser->top -= 8; parse_reduce_7(parser->stack[parser->top + 7].value.token.str, grammar); + free_string(parser->stack[parser->top + 7].value.token.str); parser->stack[++parser->top].state = 2; } break; - case 53: + case 60: switch (token) { default: parser->top -= 8; parse_reduce_6(parser->stack[parser->top + 7].value.token.str, grammar); + free_string(parser->stack[parser->top + 7].value.token.str); parser->stack[++parser->top].state = 2; } break; - case 54: + case 61: switch (token) { default: parser->top -= 8; - parse_reduce_5(parser->stack[parser->top + 5].value.symbol_term, parser->stack[parser->top + 6].value.token.str, parser->stack[parser->top + 7].value.symbol_varname, grammar); + parse_reduce_4(parser->stack[parser->top + 5].value.symbol_term, parser->stack[parser->top + 6].value.token.str, parser->stack[parser->top + 7].value.symbol_varname, grammar); + free_symbol(parser->stack[parser->top + 5].value.symbol_term); + free_string(parser->stack[parser->top + 6].value.token.str); + free_string(parser->stack[parser->top + 7].value.symbol_varname); parser->stack[++parser->top].state = 2; } break; - case 55: + case 62: + switch (token) { + case 'o': + parser->stack[++parser->top].state = 64; + return 1; + + default: + return -1; + } + break; + + case 63: switch (token) { case 'g': - parser->stack[++parser->top].state = 56; + parser->stack[++parser->top].state = 65; return 1; default: @@ -862,10 +1015,21 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 56: + case 64: + switch (token) { + case 'r': + parser->stack[++parser->top].state = 66; + return 1; + + default: + return -1; + } + break; + + case 65: switch (token) { case TOK_BLOCK: - parser->stack[++parser->top].state = 57; + parser->stack[++parser->top].state = 67; return 1; default: @@ -873,18 +1037,37 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 57: + case 66: + switch (token) { + case TOK_CHAR: + parser->stack[++parser->top].state = 28; + return 1; + + case TOK_SYMBOL_LC: + parser->stack[++parser->top].state = 31; + return 1; + + case TOK_SYMBOL_UC: + parser->stack[++parser->top].state = 32; + return 1; + + default: + return -1; + } + break; + + case 67: switch (token) { case TOK_SYMBOL: - parser->stack[++parser->top].state = 42; + parser->stack[++parser->top].state = 47; return 1; case TOK_SYMBOL_LC: - parser->stack[++parser->top].state = 43; + parser->stack[++parser->top].state = 48; return 1; case TOK_SYMBOL_UC: - parser->stack[++parser->top].state = 44; + parser->stack[++parser->top].state = 49; return 1; default: @@ -892,11 +1075,43 @@ static int parse_do_push(parse_context_t *parser, int token, __attribute__((unus } break; - case 58: + case 68: + switch (token) { + case TOK_SYMBOL: + parser->stack[++parser->top].state = 47; + return 1; + + case TOK_SYMBOL_LC: + parser->stack[++parser->top].state = 48; + return 1; + + case TOK_SYMBOL_UC: + parser->stack[++parser->top].state = 49; + return 1; + + default: + return -1; + } + break; + + case 69: switch (token) { default: parser->top -= 12; parse_reduce_8(parser->stack[parser->top + 10].value.token.str, parser->stack[parser->top + 11].value.symbol_varname, grammar); + free_string(parser->stack[parser->top + 10].value.token.str); + free_string(parser->stack[parser->top + 11].value.symbol_varname); + parser->stack[++parser->top].state = 2; + } + break; + + case 70: + switch (token) { + default: + parser->top -= 13; + parse_reduce_5(parser->stack[parser->top + 11].value.symbol_symbol, parser->stack[parser->top + 12].value.symbol_varname, grammar); + free_symbol(parser->stack[parser->top + 11].value.symbol_symbol); + free_string(parser->stack[parser->top + 12].value.symbol_varname); parser->stack[++parser->top].state = 2; } break; diff --git a/src/parse.y b/src/parse.y index ed946e0..dba747e 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1,22 +1,60 @@ +%header { +#include "grammar.hpp" +} + +%source { +static inline void free_string(std::string *v) { + delete v; +} + +static inline void free_symbol(solar::symbol_t *v) { + delete v; +} + +static inline void free_rule(solar::rule_t *v) { + delete v; +} +} + + %type SYMBOL {std::string *} str +%destructor SYMBOL free_string + %type SYMBOL_UC {std::string *} str +%destructor SYMBOL_UC free_string + %type SYMBOL_LC {std::string *} str +%destructor SYMBOL_LC free_string + %type BLOCK {std::string *} str +%destructor BLOCK free_string + %type SQBLOCK {std::string *} str +%destructor SQBLOCK free_string + %type STRING {std::string *} str +%destructor STRING free_string + %type CHAR {char} c + %type rule {solar::rule_t *} +%destructor rule free_rule + %type rhs {std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> *} + %type action {std::string *} +%destructor action free_string + %type symbol {solar::symbol_t *} +%destructor symbol free_symbol + %type term {solar::symbol_t *} -%type varname {std::string *} +%destructor term free_symbol +%type varname {std::string *} +%destructor varname free_string -%header { -#include "grammar.hpp" -} %extra_arg {__attribute__((unused)) solar::grammar_t *} grammar @@ -24,57 +62,45 @@ grammar |=; grammar |= grammar directive; -directive |= rule(rule) { - if (grammar->rules.empty()) { - solar::item_t init(""); - init.get_rhs().push_back(solar::symbol_t::make_nonterm(rule->item.get_lhs().c_str())); - grammar->rules.emplace_back(solar::rule_t {std::move(init), std::vector<std::string>(), std::string()}); - } - - grammar->rules.push_back(*rule); - delete rule; -} directive |= "%type" SYMBOL_LC(nonterm) BLOCK(type) { grammar->nonterm_types.insert(std::make_pair(*nonterm, *type)); - - delete nonterm; - delete type; } directive |= "%type" term(term) BLOCK(type) varname(name) { grammar->term_types.insert(std::make_pair(*term, std::make_pair(*type, *name))); +} - delete term; - delete type; - delete name; +directive |= "%destructor" symbol(sym) varname(name) { + grammar->destructors.insert(std::make_pair(*sym, *name)); } directive |= "%source" BLOCK(block) { grammar->source_block = *block; - delete block; } directive |= "%header" BLOCK(block) { grammar->header_block = *block; - delete block; } directive |= "%extra_arg" BLOCK(type) varname(name) { grammar->extra_args.push_back(std::make_pair(*type, *name)); +} - delete type; - delete name; +directive |= rule(rule) { + if (grammar->rules.empty()) { + solar::item_t init(""); + init.get_rhs().push_back(solar::symbol_t::make_nonterm(rule->item.get_lhs().c_str())); + grammar->rules.emplace_back(solar::rule_t {std::move(init), std::vector<std::string>(), std::string()}); + } + + grammar->rules.push_back(*rule); } rule |= SYMBOL_LC(lhs) "|=" rhs(rhs) action(action) { auto *ret = new solar::rule_t {solar::item_t(*lhs, rhs->first), rhs->second, *action}; - - delete lhs; delete rhs; - delete action; - return ret; } @@ -84,7 +110,6 @@ rhs |= [new std::pair<std::vector<solar::symbol_t>, std::vector<std::string>>()] rhs |= rhs(rhs) symbol(sym) { rhs->first.push_back(*sym); rhs->second.emplace_back(); - delete sym; return rhs; } @@ -93,9 +118,6 @@ rhs |= rhs(rhs) symbol(sym) '(' varname(var) ')' { rhs->first.push_back(*sym); rhs->second.push_back(*var); - delete sym; - delete var; - return rhs; } @@ -105,40 +127,21 @@ rhs |= rhs(rhs) STRING(str) { rhs->second.emplace_back(); } - delete str; - return rhs; } action |= ';' [new std::string] +action |= BLOCK(v) [new std::string(*v)] +action |= SQBLOCK(v) [new std::string("\n\treturn " + *v + ";\n")] -action |= BLOCK(v) [v] -action |= SQBLOCK(v) { - *v = "\n\treturn " + *v + ";\n"; - return v; -} - - -symbol |= term(v) [v] - -symbol |= SYMBOL_LC(v) { - solar::symbol_t *ret = new solar::symbol_t(solar::symbol_t::make_nonterm(*v)); - delete v; - return ret; -} - - -term |= SYMBOL_UC(v) { - solar::symbol_t *ret = new solar::symbol_t(solar::symbol_t::make_term(*v)); - delete v; - return ret; -} +symbol |= term(v) [new solar::symbol_t(*v)] +symbol |= SYMBOL_LC(v) [new solar::symbol_t(solar::symbol_t::make_nonterm(*v))] +term |= SYMBOL_UC(v) [new solar::symbol_t(solar::symbol_t::make_term(*v))] term |= CHAR(v) [new solar::symbol_t(solar::symbol_t::make_char(v))] - -varname |= SYMBOL_LC(v) [v] -varname |= SYMBOL_UC(v) [v] -varname |= SYMBOL(v) [v] +varname |= SYMBOL_LC(v) [new std::string(*v)] +varname |= SYMBOL_UC(v) [new std::string(*v)] +varname |= SYMBOL(v)[new std::string(*v)] |