//* // * 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 = default(LookAheadSet); LookAheadSet follow = default(LookAheadSet); LookAheadSet overlaps = default(LookAheadSet); // 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); }