IIntSet IIntSet.And(IIntSet a) { return And(a); }
IIntSet IIntSet.Complement(IIntSet elements) { return Complement(elements); }
/** Add label uniquely and disjointly; intersection with * another set or int/char forces breaking up the set(s). * * Example, if reachable list of labels is [a..z, {k,9}, 0..9], * the disjoint list will be [{a..j,l..z}, k, 9, 0..8]. * * As we add NFA configurations to a DFA state, we might as well track * the set of all possible transition labels to make the DFA conversion * more efficient. W/o the reachable labels, we'd need to check the * whole vocabulary space (could be 0..\uFFFF)! The problem is that * labels can be sets, which may overlap with int labels or other sets. * As we need a deterministic set of transitions from any * state in the DFA, we must make the reachable labels set disjoint. * This operation amounts to finding the character classes for this * DFA state whereas with tools like flex, that need to generate a * homogeneous DFA, must compute char classes across all states. * We are going to generate DFAs with heterogeneous states so we * only care that the set of transitions out of a single state are * unique. :) * * The idea for adding a new set, t, is to look for overlap with the * elements of existing list s. Upon overlap, replace * existing set s[i] with two new disjoint sets, s[i]-t and s[i]&t. * (if s[i]-t is nil, don't add). The remainder is t-s[i], which is * what you want to add to the set minus what was already there. The * remainder must then be compared against the i+1..n elements in s * looking for another collision. Each collision results in a smaller * and smaller remainder. Stop when you run out of s elements or * remainder goes to nil. If remainder is non nil when you run out of * s elements, then add remainder to the end. * * Single element labels are treated as sets to make the code uniform. */ 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()); */ }
IIntSet IIntSet.AddAll(IIntSet set) { return AddAll(set); }
IIntSet IIntSet.And(IIntSet a) { return(And(a)); }
IIntSet IIntSet.Or(IIntSet a) { return(Or(a)); }
public virtual Antlr4.Runtime.Misc.IntervalSet AddAll(IIntSet set) { if (set == null) { return this; } if (!(set is Antlr4.Runtime.Misc.IntervalSet)) { throw new ArgumentException("can't add non IntSet (" + set.GetType().FullName + ") to IntervalSet" ); } Antlr4.Runtime.Misc.IntervalSet other = (Antlr4.Runtime.Misc.IntervalSet)set; // walk set and add each interval int n = other.intervals.Count; for (int i = 0; i < n; i++) { Interval I = other.intervals[i]; this.Add(I.a, I.b); } return this; }
/// <summary> /// <inheritDoc/> /// /// </summary> public virtual Antlr4.Runtime.Misc.IntervalSet And(IIntSet other) { if (other == null) { //|| !(other instanceof IntervalSet) ) { return(null); } // nothing in common with null set IList <Interval> myIntervals = this.intervals; IList <Interval> theirIntervals = ((Antlr4.Runtime.Misc.IntervalSet)other).intervals; Antlr4.Runtime.Misc.IntervalSet intersection = null; int mySize = myIntervals.Count; int theirSize = theirIntervals.Count; int i = 0; int j = 0; // iterate down both interval lists looking for nondisjoint intervals while (i < mySize && j < theirSize) { Interval mine = myIntervals[i]; Interval theirs = theirIntervals[j]; //System.out.println("mine="+mine+" and theirs="+theirs); if (mine.StartsBeforeDisjoint(theirs)) { // move this iterator looking for interval that might overlap i++; } else { if (theirs.StartsBeforeDisjoint(mine)) { // move other iterator looking for interval that might overlap j++; } else { if (mine.ProperlyContains(theirs)) { // overlap, add intersection, get next theirs if (intersection == null) { intersection = new Antlr4.Runtime.Misc.IntervalSet(); } intersection.Add(mine.Intersection(theirs)); j++; } else { if (theirs.ProperlyContains(mine)) { // overlap, add intersection, get next mine if (intersection == null) { intersection = new Antlr4.Runtime.Misc.IntervalSet(); } intersection.Add(mine.Intersection(theirs)); i++; } else { if (!mine.Disjoint(theirs)) { // overlap, add intersection if (intersection == null) { intersection = new Antlr4.Runtime.Misc.IntervalSet(); } intersection.Add(mine.Intersection(theirs)); // Move the iterator of lower range [a..b], but not // the upper range as it may contain elements that will collide // with the next iterator. So, if mine=[0..115] and // theirs=[115..200], then intersection is 115 and move mine // but not theirs as theirs may collide with the next range // in thisIter. // move both iterators to next ranges if (mine.StartsAfterNonDisjoint(theirs)) { j++; } else { if (theirs.StartsAfterNonDisjoint(mine)) { i++; } } } } } } } } if (intersection == null) { return(new Antlr4.Runtime.Misc.IntervalSet()); } return(intersection); }
public virtual Antlr4.Runtime.Misc.IntervalSet Subtract(IIntSet a) { if (a == null || a.IsNil) { return new Antlr4.Runtime.Misc.IntervalSet(this); } if (a is Antlr4.Runtime.Misc.IntervalSet) { return Subtract(this, (Antlr4.Runtime.Misc.IntervalSet)a); } Antlr4.Runtime.Misc.IntervalSet other = new Antlr4.Runtime.Misc.IntervalSet(); other.AddAll(a); return Subtract(this, other); }
/** For lexer grammars, return everything in unicode not in set. * For parser and tree grammars, return everything in token space * from MIN_TOKEN_TYPE to last valid token type or char value. */ public virtual IIntSet Complement( IIntSet set ) { //[email protected]("complement "+set.toString(this)); //[email protected]("vocabulary "+getTokenTypes().toString(this)); IIntSet c = set.Complement( TokenTypes ); //[email protected]("result="+c.toString(this)); return c; }
/// <summary> /// <inheritDoc/> /// /// </summary> public virtual Antlr4.Runtime.Misc.IntervalSet Complement(IIntSet vocabulary) { if (vocabulary == null || vocabulary.IsNil) { return null; } // nothing in common with null set Antlr4.Runtime.Misc.IntervalSet vocabularyIS; if (vocabulary is Antlr4.Runtime.Misc.IntervalSet) { vocabularyIS = (Antlr4.Runtime.Misc.IntervalSet)vocabulary; } else { vocabularyIS = new Antlr4.Runtime.Misc.IntervalSet(); vocabularyIS.AddAll(vocabulary); } return vocabularyIS.Subtract(this); }
public virtual Antlr4.Runtime.Misc.IntervalSet AddAll(IIntSet set) { if (set == null) { return this; } if (set is Antlr4.Runtime.Misc.IntervalSet) { Antlr4.Runtime.Misc.IntervalSet other = (Antlr4.Runtime.Misc.IntervalSet)set; // walk set and add each interval int n = other.intervals.Count; for (int i = 0; i < n; i++) { Interval I = other.intervals[i]; this.Add(I.a, I.b); } } else { foreach (int value in set.ToList()) { Add(value); } } return this; }
/** return a new set containing all elements in this but not in other. * Intervals may have to be broken up when ranges in this overlap * with ranges in other. other is assumed to be a subset of this; * anything that is in other but not in this will be ignored. * * Keep around, but 10-20-2005, I decided to make complement work w/o * subtract and so then subtract can simply be a&~b */ public IIntSet Subtract(IIntSet other) { if (other == null || !(other is IntervalSet)) { return(null); // nothing in common with null set } IntervalSet diff = new IntervalSet(); // iterate down both interval lists var thisIter = this.intervals.GetEnumerator(); var otherIter = ((IntervalSet)other).intervals.GetEnumerator(); Interval mine = null; Interval theirs = null; if (thisIter.MoveNext()) { mine = (Interval)thisIter.Current; } if (otherIter.MoveNext()) { theirs = (Interval)otherIter.Current; } while (mine != null) { //[email protected]("mine="+mine+", theirs="+theirs); // CASE 1: nothing in theirs removes a chunk from mine if (theirs == null || mine.disjoint(theirs)) { // SUBCASE 1a: finished traversing theirs; keep adding mine now if (theirs == null) { // add everything in mine to difference since theirs done diff.add(mine); mine = null; if (thisIter.MoveNext()) { mine = (Interval)thisIter.Current; } } else { // SUBCASE 1b: mine is completely to the left of theirs // so we can add to difference; move mine, but not theirs if (mine.startsBeforeDisjoint(theirs)) { diff.add(mine); mine = null; if (thisIter.MoveNext()) { mine = (Interval)thisIter.Current; } } // SUBCASE 1c: theirs is completely to the left of mine else { // keep looking in theirs theirs = null; if (otherIter.MoveNext()) { theirs = (Interval)otherIter.Current; } } } } else { // CASE 2: theirs breaks mine into two chunks if (mine.properlyContains(theirs)) { // must add two intervals: stuff to left and stuff to right diff.add(mine.a, theirs.a - 1); // don't actually add stuff to right yet as next 'theirs' // might overlap with it // The stuff to the right might overlap with next "theirs". // so it is considered next Interval right = new Interval(theirs.b + 1, mine.b); mine = right; // move theirs forward theirs = null; if (otherIter.MoveNext()) { theirs = (Interval)otherIter.Current; } } // CASE 3: theirs covers mine; nothing to add to diff else if (theirs.properlyContains(mine)) { // nothing to add, theirs forces removal totally of mine // just move mine looking for an overlapping interval mine = null; if (thisIter.MoveNext()) { mine = (Interval)thisIter.Current; } } // CASE 4: non proper overlap else { // overlap, but not properly contained diff.add(mine.differenceNotProperlyContained(theirs)); // update iterators bool moveTheirs = true; if (mine.startsBeforeNonDisjoint(theirs) || theirs.b > mine.b) { // uh oh, right of theirs extends past right of mine // therefore could overlap with next of mine so don't // move theirs iterator yet moveTheirs = false; } // always move mine mine = null; if (thisIter.MoveNext()) { mine = (Interval)thisIter.Current; } if (moveTheirs) { theirs = null; if (otherIter.MoveNext()) { theirs = (Interval)otherIter.Current; } } } } } return(diff); }
IIntSet IIntSet.Or(IIntSet a) { return Or(a); }
/// <summary> /// Given the set of possible values (rather than, say UNICODE or MAXINT), /// return a new set containing all elements in vocabulary, but not in /// this. /// </summary> /// <remarks> /// Given the set of possible values (rather than, say UNICODE or MAXINT), /// return a new set containing all elements in vocabulary, but not in /// this. The computation is (vocabulary - this). /// 'this' is assumed to be either a subset or equal to vocabulary. /// </remarks> public virtual Antlr4.Runtime.Misc.IntervalSet Complement(IIntSet vocabulary) { if (vocabulary == null) { return null; } // nothing in common with null set if (!(vocabulary is Antlr4.Runtime.Misc.IntervalSet)) { throw new ArgumentException("can't complement with non IntervalSet (" + vocabulary .GetType().FullName + ")"); } Antlr4.Runtime.Misc.IntervalSet vocabularyIS = ((Antlr4.Runtime.Misc.IntervalSet) vocabulary); int maxElement = vocabularyIS.GetMaxElement(); Antlr4.Runtime.Misc.IntervalSet compl = new Antlr4.Runtime.Misc.IntervalSet(); int n = intervals.Count; if (n == 0) { return compl; } Interval first = intervals[0]; // add a range from 0 to first.a constrained to vocab if (first.a > 0) { Antlr4.Runtime.Misc.IntervalSet s = Antlr4.Runtime.Misc.IntervalSet.Of(0, first.a - 1); Antlr4.Runtime.Misc.IntervalSet a = s.And(vocabularyIS); compl.AddAll(a); } for (int i = 1; i < n; i++) { // from 2nd interval .. nth Interval previous = intervals[i - 1]; Interval current = intervals[i]; Antlr4.Runtime.Misc.IntervalSet s = Antlr4.Runtime.Misc.IntervalSet.Of(previous.b + 1, current.a - 1); Antlr4.Runtime.Misc.IntervalSet a = s.And(vocabularyIS); compl.AddAll(a); } Interval last = intervals[n - 1]; // add a range from last.b to maxElement constrained to vocab if (last.b < maxElement) { Antlr4.Runtime.Misc.IntervalSet s = Antlr4.Runtime.Misc.IntervalSet.Of(last.b + 1 , maxElement); Antlr4.Runtime.Misc.IntervalSet a = s.And(vocabularyIS); compl.AddAll(a); } return compl; }
IIntSet IIntSet.Subtract(IIntSet a) { return Subtract(a); }
/// <summary>Compute this-other via this&~other.</summary> /// <remarks> /// Compute this-other via this&~other. /// Return a new set containing all elements in this but not in other. /// other is assumed to be a subset of this; /// anything that is in other but not in this will be ignored. /// </remarks> public virtual Antlr4.Runtime.Misc.IntervalSet Subtract(IIntSet other) { // assume the whole unicode range here for the complement // because it doesn't matter. Anything beyond the max of this' set // will be ignored since we are doing this & ~other. The intersection // will be empty. The only problem would be when this' set max value // goes beyond MAX_CHAR_VALUE, but hopefully the constant MAX_CHAR_VALUE // will prevent this. return this.And(((Antlr4.Runtime.Misc.IntervalSet)other).Complement(CompleteCharSet )); }
IIntSet IIntSet.AddAll(IIntSet set) { return(AddAll(set)); }
public virtual Antlr4.Runtime.Misc.IntervalSet Or(IIntSet a) { Antlr4.Runtime.Misc.IntervalSet o = new Antlr4.Runtime.Misc.IntervalSet(); o.AddAll(this); o.AddAll(a); return o; }
IIntSet IIntSet.Complement(IIntSet elements) { return(Complement(elements)); }
/// <summary>Return a new set with the intersection of this set with other.</summary> /// <remarks> /// Return a new set with the intersection of this set with other. Because /// the intervals are sorted, we can use an iterator for each list and /// just walk them together. This is roughly O(min(n,m)) for interval /// list lengths n and m. /// </remarks> public virtual Antlr4.Runtime.Misc.IntervalSet And(IIntSet other) { if (other == null) { //|| !(other instanceof IntervalSet) ) { return null; } // nothing in common with null set IList<Interval> myIntervals = this.intervals; IList<Interval> theirIntervals = ((Antlr4.Runtime.Misc.IntervalSet)other).intervals; Antlr4.Runtime.Misc.IntervalSet intersection = null; int mySize = myIntervals.Count; int theirSize = theirIntervals.Count; int i = 0; int j = 0; // iterate down both interval lists looking for nondisjoint intervals while (i < mySize && j < theirSize) { Interval mine = myIntervals[i]; Interval theirs = theirIntervals[j]; //System.out.println("mine="+mine+" and theirs="+theirs); if (mine.StartsBeforeDisjoint(theirs)) { // move this iterator looking for interval that might overlap i++; } else { if (theirs.StartsBeforeDisjoint(mine)) { // move other iterator looking for interval that might overlap j++; } else { if (mine.ProperlyContains(theirs)) { // overlap, add intersection, get next theirs if (intersection == null) { intersection = new Antlr4.Runtime.Misc.IntervalSet(); } intersection.Add(mine.Intersection(theirs)); j++; } else { if (theirs.ProperlyContains(mine)) { // overlap, add intersection, get next mine if (intersection == null) { intersection = new Antlr4.Runtime.Misc.IntervalSet(); } intersection.Add(mine.Intersection(theirs)); i++; } else { if (!mine.Disjoint(theirs)) { // overlap, add intersection if (intersection == null) { intersection = new Antlr4.Runtime.Misc.IntervalSet(); } intersection.Add(mine.Intersection(theirs)); // Move the iterator of lower range [a..b], but not // the upper range as it may contain elements that will collide // with the next iterator. So, if mine=[0..115] and // theirs=[115..200], then intersection is 115 and move mine // but not theirs as theirs may collide with the next range // in thisIter. // move both iterators to next ranges if (mine.StartsAfterNonDisjoint(theirs)) { j++; } else { if (theirs.StartsAfterNonDisjoint(mine)) { i++; } } } } } } } } if (intersection == null) { return new Antlr4.Runtime.Misc.IntervalSet(); } return intersection; }
IIntSet IIntSet.Subtract(IIntSet a) { return(Subtract(a)); }
/// <summary> /// <inheritDoc/> /// /// </summary> public virtual erl.Oracle.TnsNames.Antlr4.Runtime.Misc.IntervalSet Complement(IIntSet vocabulary) { if (vocabulary == null || vocabulary.IsNil) { return(null); } // nothing in common with null set erl.Oracle.TnsNames.Antlr4.Runtime.Misc.IntervalSet vocabularyIS; if (vocabulary is erl.Oracle.TnsNames.Antlr4.Runtime.Misc.IntervalSet) { vocabularyIS = (erl.Oracle.TnsNames.Antlr4.Runtime.Misc.IntervalSet)vocabulary; } else { vocabularyIS = new erl.Oracle.TnsNames.Antlr4.Runtime.Misc.IntervalSet(); vocabularyIS.AddAll(vocabulary); } return(vocabularyIS.Subtract(this)); }