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);
}
}
}
else if (end ())
{
- suffix = new path_t (rule);
+ suffix = new path_t (rule, restorectx, ctx);
}
else if (loop < 2)
{
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 ())
{
}
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);
}
}
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 ())
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
{
}
size_t len_matching () const
{
- return rule_pos;
+ return restorectx
+ ? ctx_pos
+ : rule_pos;
}
rule_rank_t match () const
{
{
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)
{
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 ());
}
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;
, arcsets ()
, loop (0)
, rule (rule_rank_t::none ())
+ , restorectx (false)
+ , ctx (false)
, dist (DIST_ERROR)
, suffix (NULL)
{}
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)
{
// 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;