Add support for destructors
This commit is contained in:
parent
69d5b76e1a
commit
42f74c83bf
6 changed files with 725 additions and 481 deletions
|
@ -39,6 +39,8 @@ struct grammar_t {
|
||||||
std::map<std::string, std::string> nonterm_types;
|
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::pair<std::string, std::string>> term_types;
|
||||||
|
|
||||||
|
std::map<symbol_t, std::string> destructors;
|
||||||
|
|
||||||
std::string header_block;
|
std::string header_block;
|
||||||
std::string source_block;
|
std::string source_block;
|
||||||
|
|
||||||
|
|
|
@ -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, ", %s %s", arg.first.c_str(), arg.second.c_str());
|
||||||
std::fprintf(source_file, ") {\n");
|
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, "\twhile (1) {\n");
|
||||||
std::fprintf(source_file, "\t\tswitch (parser->stack[parser->top].state) {\n");
|
std::fprintf(source_file, "\t\tswitch (parser->stack[parser->top].state) {\n");
|
||||||
|
|
||||||
|
|
|
@ -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");
|
std::fprintf(source_file, "\t\t\t");
|
||||||
if (!type.empty())
|
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);
|
std::fprintf(source_file, "%sreduce_%i(", prefix(), rule_id);
|
||||||
|
|
||||||
bool empty = true;
|
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");
|
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());
|
emit_gotos(item.get_lhs());
|
||||||
|
|
|
@ -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");
|
std::fprintf(source_file, "\t\t\t\t");
|
||||||
if (!type.empty())
|
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);
|
std::fprintf(source_file, "%sreduce_%i(", prefix(), rule_id);
|
||||||
|
|
||||||
bool empty = true;
|
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");
|
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());
|
emit_gotos(item.get_lhs());
|
||||||
|
|
1005
src/parse.cpp
1005
src/parse.cpp
File diff suppressed because it is too large
Load diff
171
src/parse.y
171
src/parse.y
|
@ -1,29 +1,92 @@
|
||||||
%type SYMBOL {std::string *} str
|
|
||||||
%type SYMBOL_UC {std::string *} str
|
|
||||||
%type SYMBOL_LC {std::string *} str
|
|
||||||
%type BLOCK {std::string *} str
|
|
||||||
%type SQBLOCK {std::string *} str
|
|
||||||
%type STRING {std::string *} str
|
|
||||||
%type CHAR {char} c
|
|
||||||
|
|
||||||
%type rule {solar::rule_t *}
|
|
||||||
%type rhs {std::pair<std::vector<solar::symbol_t>, std::vector<std::string>> *}
|
|
||||||
%type action {std::string *}
|
|
||||||
%type symbol {solar::symbol_t *}
|
|
||||||
%type term {solar::symbol_t *}
|
|
||||||
%type varname {std::string *}
|
|
||||||
|
|
||||||
|
|
||||||
%header {
|
%header {
|
||||||
#include "grammar.hpp"
|
#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 *}
|
||||||
|
%destructor term free_symbol
|
||||||
|
|
||||||
|
%type varname {std::string *}
|
||||||
|
%destructor varname free_string
|
||||||
|
|
||||||
|
|
||||||
%extra_arg {__attribute__((unused)) solar::grammar_t *} grammar
|
%extra_arg {__attribute__((unused)) solar::grammar_t *} grammar
|
||||||
|
|
||||||
|
|
||||||
grammar |=;
|
grammar |=;
|
||||||
grammar |= grammar directive;
|
grammar |= grammar directive;
|
||||||
|
|
||||||
|
|
||||||
|
directive |= "%type" SYMBOL_LC(nonterm) BLOCK(type) {
|
||||||
|
grammar->nonterm_types.insert(std::make_pair(*nonterm, *type));
|
||||||
|
}
|
||||||
|
|
||||||
|
directive |= "%type" term(term) BLOCK(type) varname(name) {
|
||||||
|
grammar->term_types.insert(std::make_pair(*term, std::make_pair(*type, *name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
directive |= "%destructor" symbol(sym) varname(name) {
|
||||||
|
grammar->destructors.insert(std::make_pair(*sym, *name));
|
||||||
|
}
|
||||||
|
|
||||||
|
directive |= "%source" BLOCK(block) {
|
||||||
|
grammar->source_block = *block;
|
||||||
|
}
|
||||||
|
|
||||||
|
directive |= "%header" BLOCK(block) {
|
||||||
|
grammar->header_block = *block;
|
||||||
|
}
|
||||||
|
|
||||||
|
directive |= "%extra_arg" BLOCK(type) varname(name) {
|
||||||
|
grammar->extra_args.push_back(std::make_pair(*type, *name));
|
||||||
|
}
|
||||||
|
|
||||||
directive |= rule(rule) {
|
directive |= rule(rule) {
|
||||||
if (grammar->rules.empty()) {
|
if (grammar->rules.empty()) {
|
||||||
solar::item_t init("");
|
solar::item_t init("");
|
||||||
|
@ -32,49 +95,12 @@ directive |= rule(rule) {
|
||||||
}
|
}
|
||||||
|
|
||||||
grammar->rules.push_back(*rule);
|
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 |= "%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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
rule |= SYMBOL_LC(lhs) "|=" rhs(rhs) action(action) {
|
rule |= SYMBOL_LC(lhs) "|=" rhs(rhs) action(action) {
|
||||||
auto *ret = new solar::rule_t {solar::item_t(*lhs, rhs->first), rhs->second, *action};
|
auto *ret = new solar::rule_t {solar::item_t(*lhs, rhs->first), rhs->second, *action};
|
||||||
|
|
||||||
delete lhs;
|
|
||||||
delete rhs;
|
delete rhs;
|
||||||
delete action;
|
|
||||||
|
|
||||||
return ret;
|
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 |= rhs(rhs) symbol(sym) {
|
||||||
rhs->first.push_back(*sym);
|
rhs->first.push_back(*sym);
|
||||||
rhs->second.emplace_back();
|
rhs->second.emplace_back();
|
||||||
delete sym;
|
|
||||||
|
|
||||||
return rhs;
|
return rhs;
|
||||||
}
|
}
|
||||||
|
@ -93,9 +118,6 @@ rhs |= rhs(rhs) symbol(sym) '(' varname(var) ')' {
|
||||||
rhs->first.push_back(*sym);
|
rhs->first.push_back(*sym);
|
||||||
rhs->second.push_back(*var);
|
rhs->second.push_back(*var);
|
||||||
|
|
||||||
delete sym;
|
|
||||||
delete var;
|
|
||||||
|
|
||||||
return rhs;
|
return rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,40 +127,21 @@ rhs |= rhs(rhs) STRING(str) {
|
||||||
rhs->second.emplace_back();
|
rhs->second.emplace_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
delete str;
|
|
||||||
|
|
||||||
return rhs;
|
return rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
action |= ';' [new std::string]
|
action |= ';' [new std::string]
|
||||||
|
action |= BLOCK(v) [new std::string(*v)]
|
||||||
action |= BLOCK(v) [v]
|
action |= SQBLOCK(v) [new std::string("\n\treturn " + *v + ";\n")]
|
||||||
|
|
||||||
action |= SQBLOCK(v) {
|
|
||||||
*v = "\n\treturn " + *v + ";\n";
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
symbol |= term(v) [v]
|
symbol |= term(v) [new solar::symbol_t(*v)]
|
||||||
|
symbol |= SYMBOL_LC(v) [new solar::symbol_t(solar::symbol_t::make_nonterm(*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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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))]
|
term |= CHAR(v) [new solar::symbol_t(solar::symbol_t::make_char(v))]
|
||||||
|
|
||||||
|
varname |= SYMBOL_LC(v) [new std::string(*v)]
|
||||||
varname |= SYMBOL_LC(v) [v]
|
varname |= SYMBOL_UC(v) [new std::string(*v)]
|
||||||
varname |= SYMBOL_UC(v) [v]
|
varname |= SYMBOL(v)[new std::string(*v)]
|
||||||
varname |= SYMBOL(v) [v]
|
|
||||||
|
|
Reference in a new issue