]> granicus.if.org Git - re2c/commitdiff
Assign indices to core TNFA states (those that are final or have transitions on symbols).
authorUlya Trofimovich <skvadrik@gmail.com>
Thu, 14 Feb 2019 12:52:50 +0000 (12:52 +0000)
committerUlya Trofimovich <skvadrik@gmail.com>
Thu, 14 Feb 2019 12:52:50 +0000 (12:52 +0000)
During epsilon closure constructions, many operations only need to be
performed for core states. This allows to save some memory, e.g.
precedence matrix can be indexed by core states.

re2c/src/nfa/nfa.h
re2c/src/nfa/re_to_nfa.cc

index 79dc8232c9b80fce86d717dd3baca8e7683ac80c..0d66387b5237d68fd4d53ec09fd66f3f144a1d90 100644 (file)
@@ -56,6 +56,7 @@ struct nfa_state_t
     uint32_t active     : 1;  // boolean
     uint32_t indeg      : 27; // the rest; we are unlikely to have more than 2^27 states
     uint32_t topord; // state index in fake topological ordering
+    uint32_t coreid; // core state index
 
     void init(size_t r)
     {
@@ -66,6 +67,7 @@ struct nfa_state_t
         active = 0;
         indeg = 0;
         topord = 0;
+        coreid = 0;
     }
 
     void make_alt(size_t r, nfa_state_t *s1, nfa_state_t *s2)
@@ -111,6 +113,7 @@ struct nfa_t
     std::valarray<Rule> &rules;
     std::vector<Tag> &tags;
     nfa_state_t *root;
+    uint32_t ncores;
 
     explicit nfa_t(const RESpec &spec);
     ~nfa_t();
@@ -118,6 +121,8 @@ struct nfa_t
     FORBID_COPY(nfa_t);
 };
 
+static const uint32_t NONCORE = ~0u;
+
 size_t estimate_size(const std::vector<RE*> &res);
 
 } // namespace re2c
index 59b0cb8dcc82b9f4598b6594e44ad21ea5fd5f22..13ccf715ed7d02687df21d4d607cb259a0f2e40c 100644 (file)
@@ -11,6 +11,7 @@ namespace re2c {
 
 static void calc_indegrees(nfa_state_t *);
 static void calc_topord(nfa_state_t *, uint32_t &);
+static void calc_coreid(nfa_state_t *, uint32_t &);
 
 
 /*
@@ -119,6 +120,7 @@ nfa_t::nfa_t(const RESpec &spec)
     , rules(spec.rules)
     , tags(spec.tags)
     , root(NULL)
+    , ncores(0)
 {
     const size_t nre = spec.res.size();
 
@@ -146,6 +148,7 @@ nfa_t::nfa_t(const RESpec &spec)
         calc_topord(root, topord);
         calc_indegrees(root);
     }
+    calc_coreid(root, ncores);
 }
 
 nfa_t::~nfa_t()
@@ -194,6 +197,7 @@ void calc_topord(nfa_state_t *n, uint32_t &topord)
             break;
         case nfa_state_t::RAN:
             calc_topord(n->ran.out, topord);
+            break;
         case nfa_state_t::FIN:
             break;
     }
@@ -201,4 +205,30 @@ void calc_topord(nfa_state_t *n, uint32_t &topord)
     n->topord = topord++;
 }
 
+void calc_coreid(nfa_state_t *n, uint32_t &coreid)
+{
+    if (n->coreid != 0) return;
+    n->coreid = NONCORE;
+
+    switch (n->type) {
+        case nfa_state_t::NIL:
+            calc_coreid(n->nil.out, coreid);
+            break;
+        case nfa_state_t::ALT:
+            calc_coreid(n->alt.out1, coreid);
+            calc_coreid(n->alt.out2, coreid);
+            break;
+        case nfa_state_t::TAG:
+            calc_coreid(n->tag.out, coreid);
+            break;
+        case nfa_state_t::RAN:
+            n->coreid = coreid++;
+            calc_coreid(n->ran.out, coreid);
+            break;
+        case nfa_state_t::FIN:
+            n->coreid = coreid++;
+            break;
+    }
+}
+
 } // namespace re2c