]> granicus.if.org Git - re2c/commitdiff
Support trailing context with '--skeleton'.
authorUlya Trofimovich <skvadrik@gmail.com>
Mon, 5 Oct 2015 14:44:50 +0000 (15:44 +0100)
committerUlya Trofimovich <skvadrik@gmail.com>
Mon, 5 Oct 2015 14:44:50 +0000 (15:44 +0100)
Trialing contexts are currently broken (overlapping trailing contexts
cannot be tracked with a single 'YYCTXMARKER'). For now, re2c with
'--skeleton' mimics this incorrect behaviour: information about context
is lost by the time DFA is constructed, so skeleton has no way to
figure out the right order of things.

re2c/src/codegen/skeleton/generate_data.cc
re2c/src/codegen/skeleton/path.h
re2c/src/codegen/skeleton/skeleton.cc
re2c/src/codegen/skeleton/skeleton.h

index 6e039f924a354e5d9a621b10c04ddad1095b55cf..0985514ad16a134722f37ccd0462093c712cddf2 100644 (file)
@@ -111,7 +111,7 @@ template <typename cunit_t, typename key_t>
                for (arcs_t::iterator i = arcs.begin (); i != arcs.end (); ++i)
                {
                        multipath_t new_prefix = prefix;
-                       new_prefix.extend (i->first->rule, &i->second);
+                       new_prefix.extend (i->first->rule, i->first->restorectx, i->first->ctx, &i->second);
                        i->first->permutate<cunit_t, key_t> (new_prefix, input, keys);
                }
        }
@@ -152,7 +152,7 @@ template <typename cunit_t, typename key_t>
        }
        else if (end ())
        {
-               suffix = new path_t (rule);
+               suffix = new path_t (rule, restorectx, ctx);
        }
        else if (loop < 2)
        {
@@ -160,7 +160,7 @@ template <typename cunit_t, typename key_t>
                for (arcs_t::iterator i = arcs.begin (); i != arcs.end (); ++i)
                {
                        multipath_t new_prefix = prefix;
-                       new_prefix.extend (i->first->rule, &i->second);
+                       new_prefix.extend (i->first->rule, i->first->restorectx, i->first->ctx, &i->second);
                        size = size + i->first->cover<cunit_t, key_t> (new_prefix, input, keys);
                        if (size.overflow ())
                        {
@@ -168,7 +168,7 @@ template <typename cunit_t, typename key_t>
                        }
                        if (i->first->suffix != NULL && suffix == NULL)
                        {
-                               suffix = new path_t (rule);
+                               suffix = new path_t (rule, restorectx, ctx);
                                suffix->append (i->second[0], i->first->suffix);
                        }
                }
@@ -179,7 +179,7 @@ template <typename cunit_t, typename key_t>
 template <typename cunit_t, typename key_t>
        void Skeleton::generate_paths_cunit_key (FILE * input, FILE * keys)
 {
-       multipath_t prefix (nodes->rule);
+       multipath_t prefix (nodes->rule, nodes->restorectx, nodes->ctx);
        if (nodes->sizeof_permutate (Node::permuts_t (1u), Node::permuts_t (0u)).overflow ())
        {
                if (nodes->cover<cunit_t, key_t> (prefix, input, keys).overflow ())
index c30471d4da83a67fd48580456067f11cd4d9fef5..dc54fd9e6bd495ccb8c7821a30e0a0d416cd016b 100644 (file)
@@ -13,14 +13,22 @@ template <typename arc_t>
 class generic_path_t
 {
        std::vector<arc_t> arcs;
+
        rule_rank_t rule;
+       bool restorectx;
        size_t rule_pos;
 
+       bool ctx;
+       size_t ctx_pos;
+
 public:
-       explicit generic_path_t (rule_rank_t r)
+       explicit generic_path_t (rule_rank_t r, bool rc, bool c)
                : arcs ()
                , rule (r)
+               , restorectx (rc)
                , rule_pos (0)
+               , ctx (c)
+               , ctx_pos (0)
        {}
        size_t len () const
        {
@@ -28,7 +36,9 @@ public:
        }
        size_t len_matching () const
        {
-               return rule_pos;
+               return restorectx
+                       ? ctx_pos
+                       : rule_pos;
        }
        rule_rank_t match () const
        {
@@ -38,14 +48,20 @@ public:
        {
                return arcs[i];
        }
-       void extend (rule_rank_t r, const arc_t & a)
+       void extend (rule_rank_t r, bool rc, bool c, const arc_t & a)
        {
                arcs.push_back (a);
                if (!r.is_none ())
                {
                        rule = r;
+                       restorectx = rc;
                        rule_pos = arcs.size ();
                }
+               if (c)
+               {
+                       ctx = true;
+                       ctx_pos = arcs.size ();
+               }
        }
        void append (const arc_t & a, const generic_path_t<arc_t> * p)
        {
@@ -53,8 +69,14 @@ public:
                if (!p->rule.is_none ())
                {
                        rule = p->rule;
+                       restorectx = p->restorectx;
                        rule_pos = arcs.size () + p->rule_pos;
                }
+               if (p->ctx)
+               {
+                       ctx = true;
+                       ctx_pos = arcs.size () + p->ctx_pos;
+               }
                arcs.insert (arcs.end (), p->arcs.begin (), p->arcs.end ());
        }
 
@@ -67,17 +89,29 @@ public:
 template <typename arc1_t, typename arc2_t>
        size_t len_matching (const generic_path_t<arc1_t> & prefix, const generic_path_t<arc2_t> & suffix)
 {
-       return suffix.rule.is_none ()
+       const bool none = suffix.rule.is_none ();
+       bool restorectx = none
+               ? prefix.restorectx
+               : suffix.restorectx;
+       const size_t rule_pos = none
                ? prefix.rule_pos
                : prefix.arcs.size () + suffix.rule_pos;
+
+       const size_t ctx_pos = suffix.ctx
+               ? prefix.arcs.size () + suffix.ctx_pos
+               : prefix.ctx_pos;
+
+       return restorectx
+               ? ctx_pos
+               : rule_pos;
 }
 
 template <typename arc1_t, typename arc2_t>
        rule_rank_t match (const generic_path_t<arc1_t> & prefix, const generic_path_t<arc2_t> & suffix)
 {
-       return suffix.match ().is_none ()
-               ? prefix.match ()
-               : suffix.match ();
+       return suffix.rule.is_none ()
+               ? prefix.rule
+               : suffix.rule;
 }
 
 typedef generic_path_t<uint32_t> path_t;
index e87e572a4ab3eac22805be1cabed8c3672ac6b7f..e4bedcad69da31f8bdbde079d8e4e3747fab754b 100644 (file)
@@ -12,6 +12,8 @@ Node::Node ()
        , arcsets ()
        , loop (0)
        , rule (rule_rank_t::none ())
+       , restorectx (false)
+       , ctx (false)
        , dist (DIST_ERROR)
        , suffix (NULL)
 {}
@@ -22,8 +24,11 @@ void Node::init (const State * s, const s2n_map & s2n)
        if (is_accepting)
        {
                rule = s->rule->rank;
+               restorectx = s->rule->ctx->fixedLength () != 0;
        }
 
+       ctx = s && s->isPreCtxt;
+
        const bool is_final = !s || (s->go.nSpans == 1 && !s->go.span[0].to);
        if (!is_final)
        {
index 4439a27da398986eee976bc4bda9298421160eee..50ddd227fbc06717098386e880a87c7030e3dbaf 100644 (file)
@@ -47,6 +47,11 @@ struct Node
 
        // rule number for corresponding DFA state (if any)
        rule_rank_t rule;
+       // whether this rule must rollback input position to the beginnig of trailing context
+       bool restorectx;
+
+       // start of trailing context
+       bool ctx;
 
        // maximal distance to end node (assuming one iteration per loop)
        static const uint32_t DIST_ERROR;