protected virtual void AddReachableLabel( Label label )
{
if ( _reachableLabels == null )
{
_reachableLabels = new OrderedHashSet<Label>();
}
/*
[email protected]("addReachableLabel to state "+dfa.decisionNumber+"."+stateNumber+": "+label.getSet().toString(dfa.nfa.grammar));
[email protected]("start of add to state "+dfa.decisionNumber+"."+stateNumber+": " +
"reachableLabels="+reachableLabels.toString());
*/
if ( _reachableLabels.Contains( label ) )
{
// exact label present
return;
}
IIntSet t = label.Set;
IIntSet remainder = t; // remainder starts out as whole set to add
int n = _reachableLabels.Count; // only look at initial elements
// walk the existing list looking for the collision
for ( int i = 0; i < n; i++ )
{
Label rl = _reachableLabels[i];
/*
[email protected]("comparing ["+i+"]: "+label.toString(dfa.nfa.grammar)+" & "+
rl.toString(dfa.nfa.grammar)+"="+
intersection.toString(dfa.nfa.grammar));
*/
if ( !Label.Intersect( label, rl ) )
{
continue;
}
//[email protected](label+" collides with "+rl);
// For any (s_i, t) with s_i&t!=nil replace with (s_i-t, s_i&t)
// (ignoring s_i-t if nil; don't put in list)
// Replace existing s_i with intersection since we
// know that will always be a non nil character class
IIntSet s_i = rl.Set;
IIntSet intersection = s_i.And( t );
_reachableLabels[i] = new Label( intersection );
// Compute s_i-t to see what is in current set and not in incoming
IIntSet existingMinusNewElements = s_i.Subtract( t );
//[email protected](s_i+"-"+t+"="+existingMinusNewElements);
if ( !existingMinusNewElements.IsNil )
{
// found a new character class, add to the end (doesn't affect
// outer loop duration due to n computation a priori.
Label newLabel = new Label( existingMinusNewElements );
_reachableLabels.Add( newLabel );
}
/*
[email protected]("after collision, " +
"reachableLabels="+reachableLabels.toString());
*/
// anything left to add to the reachableLabels?
remainder = t.Subtract( s_i );
if ( remainder.IsNil )
{
break; // nothing left to add to set. done!
}
t = remainder;
}
if ( !remainder.IsNil )
{
/*
[email protected]("before add remainder to state "+dfa.decisionNumber+"."+stateNumber+": " +
"reachableLabels="+reachableLabels.toString());
[email protected]("remainder state "+dfa.decisionNumber+"."+stateNumber+": "+remainder.toString(dfa.nfa.grammar));
*/
Label newLabel = new Label( remainder );
_reachableLabels.Add( newLabel );
}
/*
[email protected]("#END of add to state "+dfa.decisionNumber+"."+stateNumber+": " +
"reachableLabels="+reachableLabels.toString());
*/
}