/// <summary> /// Finds the look-ahead set for a production pattern element. The /// maximum look-ahead length must be specified. This method takes /// the element repeats into consideration when creating the /// look-ahead set, but does NOT include an empty sequence even if /// the minimum count is zero (0). It is also possible to specify a /// look-ahead set filter, which will make sure that unnecessary /// token sequences will be avoided. /// </summary> /// <param name="elem">The production pattern element</param> /// <param name="length">The maximum look-ahead length</param> /// <param name="stack">The call stack used for loop detection</param> /// <param name="filter">The look-ahead set filter</param> /// <returns>The look-ahead set for the pattern element</returns> /// <exception cref="ParserCreationException"> /// If an infinite loop was found in the grammar /// </exception> private LookAheadSet FindLookAhead( ProductionPatternElement elem, int length, CallStack stack, LookAheadSet filter) { LookAheadSet result; LookAheadSet first; LookAheadSet follow; int max; // Find initial element look-ahead first = this.FindLookAhead(elem, length, 0, stack, filter); result = new LookAheadSet(length); result.AddAll(first); if (filter == null || !filter.IsOverlap(result)) { return(result); } // Handle element repetitions if (elem.MaxCount == int.MaxValue) { first = first.CreateRepetitive(); } max = elem.MaxCount; if (length < max) { max = length; } for (int i = 1; i < max; i++) { first = first.CreateOverlaps(filter); if (first.Size <= 0 || first.MinLength >= length) { break; } follow = this.FindLookAhead( elem, length, 0, stack, filter.CreateFilter(first)); first = first.CreateCombination(follow); result.AddAll(first); } return(result); }
/// <summary> /// Finds the look-ahead set for a production pattern alternative. /// The pattern position and maximum look-ahead length must be /// specified. It is also possible to specify a look-ahead set /// filter, which will make sure that unnecessary token sequences /// will be avoided. /// </summary> /// <param name="alt">The production pattern alternative</param> /// <param name="length">The maximum look-ahead length</param> /// <param name="pos">The pattern element position</param> /// <param name="stack">The call stack used for loop detection</param> /// <param name="filter">The look-ahead set filter</param> /// <returns> /// The look-ahead set for the pattern alternative /// </returns> /// <exception cref="ParserCreationException"> /// If an infinite loop was found in the grammar /// </exception> private LookAheadSet FindLookAhead( ProductionPatternAlternative alt, int length, int pos, CallStack stack, LookAheadSet filter) { LookAheadSet first; LookAheadSet follow; LookAheadSet overlaps; // Check trivial cases if (length <= 0 || pos >= alt.Count) { return(new LookAheadSet(0)); } // Find look-ahead for this element first = this.FindLookAhead(alt[pos], length, stack, filter); if (alt[pos].MinCount == 0) { first.AddEmpty(); } // Find remaining look-ahead if (filter == null) { length -= first.MinLength; if (length > 0) { follow = this.FindLookAhead(alt, length, pos + 1, stack, null); first = first.CreateCombination(follow); } } else if (filter.IsOverlap(first)) { overlaps = first.CreateOverlaps(filter); length -= overlaps.MinLength; filter = filter.CreateFilter(overlaps); follow = this.FindLookAhead(alt, length, pos + 1, stack, filter); first.RemoveAll(overlaps); first.AddAll(overlaps.CreateCombination(follow)); } return(first); }
/** * Finds the look-ahead set for a production pattern element. The * maximum look-ahead length must be specified. This method takes * the element repeats into consideration when creating the * look-ahead set, but does NOT include an empty sequence even if * the minimum count is zero (0). It is also possible to specify a * look-ahead set filter, which will make sure that unnecessary * token sequences will be avoided. * * @param elem the production pattern element * @param length the maximum look-ahead length * @param stack the call stack used for loop detection * @param filter the look-ahead set filter * * @return the look-ahead set for the pattern element * * @throws ParserCreationException if an infinite loop was found * in the grammar */ private LookAheadSet FindLookAhead(ProductionPatternElement elem, int length, CallStack stack, LookAheadSet filter) { LookAheadSet result; LookAheadSet first; LookAheadSet follow; int max; // Find initial element look-ahead first = FindLookAhead(elem, length, 0, stack, filter); result = new LookAheadSet(length); result.AddAll(first); if (filter == null || !filter.IsOverlap(result)) { return result; } // Handle element repetitions if (elem.MaxCount == Int32.MaxValue) { first = first.CreateRepetitive(); } max = elem.MaxCount; if (length < max) { max = length; } for (int i = 1; i < max; i++) { first = first.CreateOverlaps(filter); if (first.Size() <= 0 || first.GetMinLength() >= length) { break; } follow = FindLookAhead(elem, length, 0, stack, filter.CreateFilter(first)); first = first.CreateCombination(follow); result.AddAll(first); } return result; }
/** * Finds the look-ahead set for a production pattern alternative. * The pattern position and maximum look-ahead length must be * specified. It is also possible to specify a look-ahead set * filter, which will make sure that unnecessary token sequences * will be avoided. * * @param alt the production pattern alternative * @param length the maximum look-ahead length * @param pos the pattern element position * @param stack the call stack used for loop detection * @param filter the look-ahead set filter * * @return the look-ahead set for the pattern alternative * * @throws ParserCreationException if an infinite loop was found * in the grammar */ private LookAheadSet FindLookAhead(ProductionPatternAlternative alt, int length, int pos, CallStack stack, LookAheadSet filter) { LookAheadSet first; LookAheadSet follow; LookAheadSet overlaps; // Check trivial cases if (length <= 0 || pos >= alt.Count) { return new LookAheadSet(0); } // Find look-ahead for this element first = FindLookAhead(alt[pos], length, stack, filter); if (alt[pos].MinCount == 0) { first.AddEmpty(); } // Find remaining look-ahead if (filter == null) { length -= first.GetMinLength(); if (length > 0) { follow = FindLookAhead(alt, length, pos + 1, stack, null); first = first.CreateCombination(follow); } } else if (filter.IsOverlap(first)) { overlaps = first.CreateOverlaps(filter); length -= overlaps.GetMinLength(); filter = filter.CreateFilter(overlaps); follow = FindLookAhead(alt, length, pos + 1, stack, filter); first.RemoveAll(overlaps); first.AddAll(overlaps.CreateCombination(follow)); } return first; }