]> granicus.if.org Git - re2c/commitdiff
Limited skeleton lifespan to the time of DFA construction.
authorUlya Trofimovich <skvadrik@gmail.com>
Thu, 10 Nov 2016 11:24:35 +0000 (11:24 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Thu, 10 Nov 2016 11:24:35 +0000 (11:24 +0000)
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.

re2c/src/codegen/emit_action.cc
re2c/src/codegen/emit_dfa.cc
re2c/src/ir/adfa/adfa.cc
re2c/src/ir/adfa/adfa.h
re2c/src/ir/compile.cc
re2c/src/ir/skeleton/generate_code.cc
re2c/src/ir/skeleton/generate_data.cc
re2c/src/ir/skeleton/skeleton.cc
re2c/src/ir/skeleton/skeleton.h

index d959d453f99ba65545af3e315ab3403246243ee6..4fce6b5da86f58dba1ad86e84aad23c97f728123 100644 (file)
@@ -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) {
index 06222822e186c4222c7952c182d5a881435cba4c..3172a7c9f4b0eee0f978ad6ef5a375813aa1f93b 100644 (file)
@@ -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);
index c9c0d899fe1dc769ea5421849c15084f11a6d5cb..efcfef5417df10b20237c129ff35d4098074b7ae 100644 (file)
@@ -18,14 +18,14 @@ namespace re2c
 DFA::DFA
        ( const dfa_t &dfa
        , const std::vector<size_t> &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;
index d8b9a2dc41db023d03e0acd965b1e9db79500398..0baae8d281bce66cfe19d4c7996b9a6f7f20888d 100644 (file)
@@ -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<size_t> &fill
-               , Skeleton *skel
+               , size_t def
+               , size_t key
                , const charset_t &charset
                , const std::string &n
                , const std::string &c
index fecdc5c9c56c92126634519657af858018899c7f..eb8d7cbbbdedb3dbfa40ecf63e8ac123fa6768d8 100644 (file)
@@ -62,10 +62,10 @@ static smart_ptr<DFA> 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<DFA> 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();
index 8748272213bded4acb7b9906b20cc4668886a2f3..577c462cde34559cd6a767940be751a6ce766d7f 100644 (file)
@@ -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<std::string> &tagnames,
-       const std::set<std::string> &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<std::string> &tagnames, const std::set<std::string> &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 = "<stdout>";
@@ -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<std::string> &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");
 }
 
index 5a85d2132aed625b766fd3ad3f02d15726080511..a49f864afa5b36047d33deabb114c0e680c6816b 100644 (file)
@@ -152,7 +152,7 @@ template<typename cunit_t, typename key_t> static cover_size_t cover_one(
        delete[] buffer;
 
        // keys
-       const key_t match = skel.rule2key<key_t>(path.match(skel), skel.defrule);
+       const key_t match = rule2key<key_t>(path.match(skel), skel.defrule);
        keygen<key_t>(cover.keys, width, len, path.len_matching(skel), match);
 
        return size;
index 29bb07dd605a70d8ebd1b0a62b80bdb52452298f..bf87743cd171f4d6ea3d929f263fd7ef93ed7857 100644 (file)
@@ -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<uint64_t>(r, defrule);
-               case 4: return rule2key<uint32_t>(r, defrule);
-               case 2: return rule2key<uint16_t>(r, defrule);
-               case 1: return rule2key<uint8_t>(r, defrule);
+       switch (key) {
+               default: assert(false); // shouldn't happen
+               case 8: return rule2key<uint64_t>(rule, def);
+               case 4: return rule2key<uint32_t>(rule, def);
+               case 2: return rule2key<uint16_t>(rule, def);
+               case 1: return rule2key<uint8_t>(rule, def);
        }
 }
 
index 53ee6356e566e4dbad3306f9c389ed619ce88a26..cb5d0231a4e4f3eed1d0df80045a208fc6a5b063 100644 (file)
@@ -64,7 +64,7 @@ struct Skeleton
        Node *nodes;
 
        size_t sizeof_key;
-       const size_t defrule;
+       size_t defrule;
        const std::valarray<Rule> &rules;
        const std::valarray<Tag> &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<typename key_t> key_t rule2key(size_t r, size_t def) const;
-
        FORBID_COPY(Skeleton);
 };
 
-template<typename key_t> key_t Skeleton::rule2key(size_t r, size_t def) const
+template<typename key_t> key_t rule2key(size_t r, size_t def)
 {
        if (r == Rule::NONE) {
                return std::numeric_limits<key_t>::max();
@@ -90,19 +87,18 @@ template<typename key_t> 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<std::string> &tagnames,
-       const std::set<std::string> &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<std::string> &tagnames, const std::set<std::string> &tagvars);
+void emit_end(OutputFile &o, const std::string &name, bool backup, bool oldstyle_ctxmarker);
 void emit_epilog(OutputFile &o, const std::set<std::string> &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