]> granicus.if.org Git - re2c/commitdiff
Count contexts after deduplication.
authorUlya Trofimovich <skvadrik@gmail.com>
Sat, 30 Apr 2016 15:35:40 +0000 (16:35 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Sat, 30 Apr 2016 16:01:28 +0000 (17:01 +0100)
re2c/src/ir/adfa/adfa.cc
re2c/src/ir/adfa/adfa.h
re2c/src/ir/adfa/prepare.cc
re2c/src/ir/compile.cc
re2c/src/ir/dfa/context_deduplication.cc
re2c/src/ir/dfa/dfa.h

index 414e1d6d672e3789986034761e377952ab6fbf83..8ab2539aa9a1f3b92200032f63b11e7cb3c443a0 100644 (file)
@@ -24,7 +24,7 @@ DFA::DFA
        , const std::string &n
        , const std::string &c
        , uint32_t l
-       , bool base_ctx
+       , size_t used_tags
        )
        : accepts ()
        , skeleton (skel)
@@ -41,9 +41,23 @@ DFA::DFA
        // statistics
        , max_fill (0)
        , need_backup (false)
-       , need_backupctx (opts->contexts)
+
+       // determine if 'YYCTXMARKER' or 'YYBACKUPCTX'/'YYRESTORECTX' pair is used
+       , need_backupctx (used_tags > 0 || opts->contexts)
        , need_accept (false)
-       , base_ctxmarker (base_ctx)
+
+       // Non-trailing contexts imply the existence of base context marker
+       // that points at the beginning of lexeme. First, it is a feature
+       // of re2c API. Second, it simplifies implementation (otherwise
+       // it would be hard to mix generic API and fixed-length contexts).
+       //
+       // The only case without base context marker is when:
+       //     - only trailing contexts are allowed
+       //     - they don't overlap (one marker is enough for all of them)
+       //     - with generic API fixed-length contexts are forbidden
+       // Note that in this case, if generic API is used, fixed-length
+       // contexts are forbidden (which may cause additional overlaps).
+       , base_ctxmarker (used_tags > 1 || opts->contexts)
 {
        const size_t nstates = dfa.states.size();
        const size_t nchars = dfa.nchars;
index 4816cb18792d61ef725c841e2396831de218c82d..eb60ba9e3f7713106da51375771b3576817a991e 100644 (file)
@@ -87,7 +87,7 @@ public:
                , const std::string &n
                , const std::string &c
                , uint32_t l
-               , bool base_ctx
+               , size_t used_tags
                );
        ~DFA ();
        void reorder();
index 050fd2abd1b29fd53ff4d71c0f123f484807fc48..ee9dff2125812f600857374c24fa1394ee458623 100644 (file)
@@ -194,14 +194,6 @@ void DFA::calc_stats ()
        // determine if 'YYMARKER' or 'YYBACKUP'/'YYRESTORE' pair is used
        need_backup = accepts.size () > 0;
 
-       // determine if 'YYCTXMARKER' or 'YYBACKUPCTX'/'YYRESTORECTX' pair is used
-       for (State * s = head; s; s = s->next) {
-               if (!s->ctxs.empty()) {
-                       need_backupctx = true;
-                       break;
-               }
-       }
-
        // determine if 'yyaccept' variable is used
        need_accept = accepts.size () > 1;
 }
index effc28e67e0ba2db7316bf240d079b3ec0c35b84..0a4e4bc0e4b81ab93ce583aac14a69bfe10a710c 100644 (file)
@@ -72,25 +72,12 @@ static smart_ptr<DFA> compile_rules(
        std::vector<size_t> fallback;
        fallback_states(dfa, fallback);
 
-       // Non-trailing contexts imply the existence of base context marker
-       // that points at the beginning of lexeme. First, it is a feature
-       // of re2c API. Second, it simplifies implementation (otherwise
-       // it would be hard to mix generic API and fixed-length contexts).
-       //
-       // The only case without base context marker is when:
-       //     - only trailing contexts are allowed
-       //     - they don't overlap (one marker is enough for all of them)
-       //     - with generic API fixed-length contexts are forbidden
-       // Note that in this case, if generic API is used, fixed-length
-       // contexts are forbidden (which may cause additional overlaps).
-       const bool multiple_ctxmarkers = deduplicate_contexts(dfa, fallback);
-       const bool base_ctxmarker
-               = multiple_ctxmarkers
-               || opts->contexts;
+       // try to minimize the number of tag variables
+       const size_t used_tags = deduplicate_contexts(dfa, fallback);
 
        // ADFA stands for 'DFA with actions'
        DFA *adfa = new DFA(dfa, fill, fallback, skeleton, cs,
-               name, cond, line, base_ctxmarker);
+               name, cond, line, used_tags);
 
        // see note [reordering DFA states]
        adfa->reorder();
index db9f1a70b9c58e25cdf738d3a2d0ef4f8cdb1f88..96098857f30b67227fefadfcc370fae456e435ba 100644 (file)
@@ -44,13 +44,12 @@ static void calc_live(
        }
 }
 
-bool deduplicate_contexts(
-       const dfa_t &dfa,
+size_t deduplicate_contexts(dfa_t &dfa,
        const std::vector<size_t> &fallback)
 {
        const size_t nctxs = dfa.contexts.size();
        if (nctxs < 2) {
-               return false;
+               return nctxs;
        }
 
        std::set<size_t> fbctxs;
@@ -124,32 +123,13 @@ bool deduplicate_contexts(
                        head[0] = c;
                }
        }
-       const bool multiple_contexts = head[0] != END;
-
-/*
-       std::vector<size_t> c2c;
-       std::vector<std::vector<size_t> > part;
+       size_t ncontexts = 0;
        for (size_t i = 0; i < nctxs; ++i) {
-               size_t j;
-               for (j = 0; j < partn.size(); ++j) {
-                       std::vector<size_t> &p = part[j];
-                       size_t k;
-                       for (k = 0; k < p.size(); ++k) {
-                               if (xxx[i * nctxs + p[k]]) {
-                                       break;
-                               }
-                       }
-                       if (k == p.size()) {
-                               break;
-                       }
+               if (part[i] == i) {
+                       ++ncontexts;
                }
-               if (j == part.size()) {
-                       part.push_back(std::vector<size_t>());
-               }
-               part[j].push_back(i);
-               c2c[i] = part[j][0];
        }
-*/
+
        for (size_t i = 0; i < nstates; ++i) {
                dfa_state_t *s = dfa.states[i];
                std::set<size_t> ctxs;
@@ -162,7 +142,7 @@ bool deduplicate_contexts(
                dfa.contexts[i].uniqname = dfa.contexts[part[i]].uniqname;
        }
 
-       return multiple_contexts;
+       return ncontexts;
 }
 
 
index 494b43af7f0eb0c6025f96808cbb46bcdd840020..2f1e720c729a152863cbd22c411447c73ef531f4 100644 (file)
@@ -63,7 +63,7 @@ void check_context_selfoverlap(ord_hash_set_t &kernels,
 void minimization(dfa_t &dfa);
 void fillpoints(const dfa_t &dfa, std::vector<size_t> &fill);
 void fallback_states(const dfa_t &dfa, std::vector<size_t> &fallback);
-bool deduplicate_contexts(const dfa_t &dfa, const std::vector<size_t> &fallback);
+size_t deduplicate_contexts(dfa_t &dfa, const std::vector<size_t> &fallback);
 
 } // namespace re2c