From: Ulya Trofimovich Date: Thu, 10 Nov 2016 11:24:35 +0000 (+0000) Subject: Limited skeleton lifespan to the time of DFA construction. X-Git-Tag: 1.0~39^2~232 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c560d865efcea1f3ed2b280debfde613b401ce8a;p=re2c Limited skeleton lifespan to the time of DFA construction. There's no need to pull the whole skeleton up to code generation phase: skeleton itself is used only for string generation and tracing undefined control flow, both things are done after DFA construction and before any optimizations. By the time code generation starts skeleton is obsolete: its structure is no longer in sync with DFA and it shouldn't be used. Code generation only needs some attributes (key size and default rule index), which can be explicitely stored in DFA. --- diff --git a/re2c/src/codegen/emit_action.cc b/re2c/src/codegen/emit_action.cc index d959d453..4fce6b5d 100644 --- a/re2c/src/codegen/emit_action.cc +++ b/re2c/src/codegen/emit_action.cc @@ -219,7 +219,7 @@ void emit_rule(OutputFile &o, uint32_t ind, const DFA &dfa, size_t rule_idx) gen_fintags(o, ind, dfa, rule); if (opts->target == opt_t::SKELETON) { - emit_action(*dfa.skeleton, o, ind, rule_idx); + emit_action(o, ind, dfa.name, dfa.key_size, dfa.def_rule, rule_idx); } else { const std::string &cond = info->newcond; if (!cond.empty() && dfa.cond != cond) { diff --git a/re2c/src/codegen/emit_dfa.cc b/re2c/src/codegen/emit_dfa.cc index 06222822..3172a7c9 100644 --- a/re2c/src/codegen/emit_dfa.cc +++ b/re2c/src/codegen/emit_dfa.cc @@ -181,11 +181,11 @@ void DFA::emit(Output & output, uint32_t& ind, bool isLastCond, bool& bPrologBra if (opts->target == opt_t::SKELETON) { if (output.skeletons.insert (name).second) { - emit_start(*skeleton, o, max_fill, need_backup, + emit_start(o, max_fill, name, key_size, def_rule, need_backup, need_accept, oldstyle_ctxmarker, tagnames, tagvars); uint32_t i = 2; emit_body (o, i, used_labels, initial_label); - emit_end(*skeleton, o, need_backup, oldstyle_ctxmarker); + emit_end(o, name, need_backup, oldstyle_ctxmarker); } } else if (opts->target == opt_t::DOT) { emit_dot(o, isLastCond, ob.types); diff --git a/re2c/src/ir/adfa/adfa.cc b/re2c/src/ir/adfa/adfa.cc index c9c0d899..efcfef54 100644 --- a/re2c/src/ir/adfa/adfa.cc +++ b/re2c/src/ir/adfa/adfa.cc @@ -18,14 +18,14 @@ namespace re2c DFA::DFA ( const dfa_t &dfa , const std::vector &fill - , Skeleton *skel + , size_t def + , size_t key , const charset_t &charset , const std::string &n , const std::string &c , uint32_t l ) : accepts () - , skeleton (skel) , name (n) , cond (c) , line (l) @@ -41,6 +41,8 @@ DFA::DFA , need_accept (false) , oldstyle_ctxmarker (false) , maxtagver (dfa.maxtagver) + , def_rule (def) + , key_size (key) { const size_t nstates = dfa.states.size(); const size_t nchars = dfa.nchars; @@ -94,7 +96,6 @@ DFA::~DFA() delete s; } - delete skeleton; delete &rules; delete &tags; delete &tcpool; diff --git a/re2c/src/ir/adfa/adfa.h b/re2c/src/ir/adfa/adfa.h index d8b9a2dc..0baae8d2 100644 --- a/re2c/src/ir/adfa/adfa.h +++ b/re2c/src/ir/adfa/adfa.h @@ -18,7 +18,6 @@ namespace re2c { -struct Skeleton; struct Output; struct OutputFile; struct dfa_t; @@ -58,7 +57,6 @@ struct State struct DFA { accept_t accepts; - Skeleton * skeleton; const std::string name; const std::string cond; const uint32_t line; @@ -74,10 +72,13 @@ struct DFA bool need_accept; bool oldstyle_ctxmarker; tagver_t maxtagver; + const size_t def_rule; + const size_t key_size; DFA ( const dfa_t &dfa , const std::vector &fill - , Skeleton *skel + , size_t def + , size_t key , const charset_t &charset , const std::string &n , const std::string &c diff --git a/re2c/src/ir/compile.cc b/re2c/src/ir/compile.cc index fecdc5c9..eb8d7cbb 100644 --- a/re2c/src/ir/compile.cc +++ b/re2c/src/ir/compile.cc @@ -62,10 +62,10 @@ static smart_ptr compile_rules( // skeleton must be constructed after DFA construction // but prior to any other DFA transformations - Skeleton *skeleton = new Skeleton(dfa, cs, defrule, name, cond, line); - warn_undefined_control_flow(*skeleton); + Skeleton skeleton(dfa, cs, defrule, name, cond, line); + warn_undefined_control_flow(skeleton); if (opts->target == opt_t::SKELETON) { - emit_data(*skeleton); + emit_data(skeleton); } cutoff_dead_rules(dfa, defrule, cond); @@ -82,7 +82,7 @@ static smart_ptr compile_rules( fillpoints(dfa, fill); // ADFA stands for 'DFA with actions' - DFA *adfa = new DFA(dfa, fill, skeleton, cs, name, cond, line); + DFA *adfa = new DFA(dfa, fill, defrule, skeleton.sizeof_key, cs, name, cond, line); // see note [reordering DFA states] adfa->reorder(); diff --git a/re2c/src/ir/skeleton/generate_code.cc b/re2c/src/ir/skeleton/generate_code.cc index 87482722..577c462c 100644 --- a/re2c/src/ir/skeleton/generate_code.cc +++ b/re2c/src/ir/skeleton/generate_code.cc @@ -93,16 +93,12 @@ void emit_prolog(OutputFile &o) o.ws("\n"); } -void emit_start(const Skeleton &skel, OutputFile &o, size_t maxfill, - bool backup, bool accept, bool oldstyle_ctxmarker, - const std::set &tagnames, - const std::set &tagvars) +void emit_start(OutputFile &o, size_t maxfill, const std::string &name, + size_t sizeof_key, size_t def, bool backup, bool accept, bool oldstyle_ctxmarker, + const std::set &tagnames, const std::set &tagvars) { - const size_t - sizeof_cunit = opts->encoding.szCodeUnit(), - sizeof_key = skel.sizeof_key; - const size_t norule = skel.rule2key(Rule::NONE); - const std::string &name = skel.name; + const size_t sizeof_cunit = opts->encoding.szCodeUnit(); + const size_t norule = rule2key(Rule::NONE, sizeof_key, def); std::string filename = opts->output_file; if (filename.empty()) { filename = ""; @@ -261,10 +257,8 @@ void emit_start(const Skeleton &skel, OutputFile &o, size_t maxfill, o.ws("\n"); } -void emit_end(const Skeleton &skel, OutputFile &o, bool backup, bool oldstyle_ctxmarker) +void emit_end(OutputFile &o, const std::string &name, bool backup, bool oldstyle_ctxmarker) { - const std::string &name = skel.name; - o.ws("\n").wind(1).ws("}"); o.ws("\n").wind(1).ws("if (status == 0) {"); o.ws("\n").wind(2).ws("if (cursor != eof) {"); @@ -323,11 +317,12 @@ void emit_epilog(OutputFile &o, const std::set &names) o.ws("\n"); } -void emit_action(const Skeleton &skel, OutputFile &o, uint32_t ind, size_t rule) +void emit_action(OutputFile &o, uint32_t ind, const std::string &name, + size_t key, size_t def, size_t rule) { - o.wind(ind).ws("status = action_").wstring(skel.name) + o.wind(ind).ws("status = action_").wstring(name) .ws("(i, keys, input, token, &cursor, ") - .wu64(skel.rule2key(rule)).ws(");\n"); + .wu64(rule2key(rule, key, def)).ws(");\n"); o.wind(ind).ws("continue;\n"); } diff --git a/re2c/src/ir/skeleton/generate_data.cc b/re2c/src/ir/skeleton/generate_data.cc index 5a85d213..a49f864a 100644 --- a/re2c/src/ir/skeleton/generate_data.cc +++ b/re2c/src/ir/skeleton/generate_data.cc @@ -152,7 +152,7 @@ template static cover_size_t cover_one( delete[] buffer; // keys - const key_t match = skel.rule2key(path.match(skel), skel.defrule); + const key_t match = rule2key(path.match(skel), skel.defrule); keygen(cover.keys, width, len, path.len_matching(skel), match); return size; diff --git a/re2c/src/ir/skeleton/skeleton.cc b/re2c/src/ir/skeleton/skeleton.cc index 29bb07dd..bf87743c 100644 --- a/re2c/src/ir/skeleton/skeleton.cc +++ b/re2c/src/ir/skeleton/skeleton.cc @@ -83,14 +83,14 @@ Skeleton::~Skeleton() delete[] nodes; } -size_t Skeleton::rule2key(size_t r) const +size_t rule2key(size_t rule, size_t key, size_t def) { - switch (sizeof_key) { - default: // shouldn't happen - case 8: return rule2key(r, defrule); - case 4: return rule2key(r, defrule); - case 2: return rule2key(r, defrule); - case 1: return rule2key(r, defrule); + switch (key) { + default: assert(false); // shouldn't happen + case 8: return rule2key(rule, def); + case 4: return rule2key(rule, def); + case 2: return rule2key(rule, def); + case 1: return rule2key(rule, def); } } diff --git a/re2c/src/ir/skeleton/skeleton.h b/re2c/src/ir/skeleton/skeleton.h index 53ee6356..cb5d0231 100644 --- a/re2c/src/ir/skeleton/skeleton.h +++ b/re2c/src/ir/skeleton/skeleton.h @@ -64,7 +64,7 @@ struct Skeleton Node *nodes; size_t sizeof_key; - const size_t defrule; + size_t defrule; const std::valarray &rules; const std::valarray &tags; @@ -72,13 +72,10 @@ struct Skeleton const std::string &dfa_name, const std::string &dfa_cond, uint32_t dfa_line); ~Skeleton (); - size_t rule2key(size_t r) const; - template key_t rule2key(size_t r, size_t def) const; - FORBID_COPY(Skeleton); }; -template key_t Skeleton::rule2key(size_t r, size_t def) const +template key_t rule2key(size_t r, size_t def) { if (r == Rule::NONE) { return std::numeric_limits::max(); @@ -90,19 +87,18 @@ template key_t Skeleton::rule2key(size_t r, size_t def) const } } +size_t rule2key(size_t rule, size_t key, size_t def); uint32_t maxpath(const Skeleton &skel); void warn_undefined_control_flow(const Skeleton &skel); void fprint_default_path(FILE *f, const Skeleton &skel, const path_t &p); void emit_data(const Skeleton &skel); void emit_prolog(OutputFile & o); -void emit_start(const Skeleton &skel, OutputFile &o, size_t maxfill, - bool backup, bool accept, bool oldstyle_ctxmarker, - const std::set &tagnames, - const std::set &tagvars); -void emit_end(const Skeleton &skel, OutputFile &o, bool backup, bool oldstyle_ctxmarker); +void emit_start(OutputFile &o, size_t maxfill, const std::string &name, + size_t sizeof_key, size_t def, bool backup, bool accept, bool oldstyle_ctxmarker, + const std::set &tagnames, const std::set &tagvars); +void emit_end(OutputFile &o, const std::string &name, bool backup, bool oldstyle_ctxmarker); void emit_epilog(OutputFile &o, const std::set &names); -void emit_action(const Skeleton &skel, OutputFile &o, uint32_t ind, - size_t rule); +void emit_action(OutputFile &o, uint32_t ind, const std::string &name, size_t key, size_t def, size_t rule); } // namespace re2c