//*
        // * Removes all the token sequences from a specified set. Only
        // * sequences already in this set will be removed.
        // *
        // * @param set the set to remove from
        //

        public void RemoveAll(LookAheadSet @set)
        {
            for (int i = 0; i <= @set.elements.Count - 1; i++)
            {
                Remove((Sequence)@set.elements[i]);
            }
        }
        //*
        // * Creates a new look-ahead set filter. The filter will contain
        // * all sequences from this set, possibly left trimmed by each one
        // * of the sequences in the specified set.
        // *
        // * @param set the look-ahead set to trim with
        // *
        // * @return a new look-ahead set filter
        //

        public LookAheadSet CreateFilter(LookAheadSet @set)
        {
            LookAheadSet result = new LookAheadSet(maxLength);
            Sequence     first  = default(Sequence);
            Sequence     second = default(Sequence);

            // Handle special cases
            if (this.Size() <= 0 || @set.Size() <= 0)
            {
                return(this);
            }
            for (int i = 0; i <= elements.Count - 1; i++)
            {
                // Create combinations
                first = (Sequence)elements[i];
                for (int j = 0; j <= @set.elements.Count - 1; j++)
                {
                    second = (Sequence)@set.elements[j];
                    if (first.StartsWith(second))
                    {
                        result.Add(first.Subsequence(second.Length()));
                    }
                }
            }
            return(result);
        }
        //*
        // * Checks if another look-ahead set has an overlapping token
        // * sequence. An overlapping token sequence is a token sequence
        // * that is identical to another sequence, but for the length.
        // * I.e. one of the two sequences may be longer than the other.
        // *
        // * @param set the look-ahead set to check
        // *
        // * @return true if there is some token sequence that overlaps, or
        // * false otherwise
        //

        public bool IsOverlap(LookAheadSet @set)
        {
            for (int i = 0; i <= elements.Count - 1; i++)
            {
                if (@set.IsOverlap((Sequence)elements[i]))
                {
                    return(true);
                }
            }
            return(false);
        }
        //*
        // * Returns a look-ahead set with all conflicts between two
        // * look-ahead sets.
        // *
        // * @param pattern the pattern name being analyzed
        // * @param location the pattern location
        // * @param set1 the first look-ahead set
        // * @param set2 the second look-ahead set
        // *
        // * @return a look-ahead set with the conflicts found
        // *
        // * @throws ParserCreationException if an inherent ambiguity was
        // * found among the look-ahead sets
        //

        private LookAheadSet FindConflicts(string pattern, string location, LookAheadSet set1, LookAheadSet set2)
        {
            LookAheadSet result = default(LookAheadSet);

            result = set1.CreateIntersection(set2);
            if (result.IsRepetitive())
            {
                ThrowAmbiguityException(pattern, location, result);
            }
            return(result);
        }
        //*
        // * Checks if some token sequence is present in both this set
        // * and a specified one.
        // *
        // * @param set the look-ahead set to compare with
        // *
        // * @return true if the look-ahead sets intersect, or
        // * false otherwise
        //

        public bool Intersects(LookAheadSet @set)
        {
            for (int i = 0; i <= elements.Count - 1; i++)
            {
                if (@set.Contains((Sequence)elements[i]))
                {
                    return(true);
                }
            }
            return(false);
        }
        //*
        // * Calculates the look-aheads needed for the specified pattern
        // * alternative. This method attempts to resolve any conflicts in
        // * optional elements by recalculating look-aheads for referenced
        // * productions.
        // *
        // * @param alt the production pattern alternative
        // * @param pos the pattern element position
        // *
        // * @throws ParserCreationException if the look-ahead set couldn't
        // * be determined due to inherent ambiguities
        //

        private void CalculateLookAhead(ProductionPatternAlternative alt, int pos)
        {
            ProductionPattern        pattern   = default(ProductionPattern);
            ProductionPatternElement elem      = default(ProductionPatternElement);
            LookAheadSet             first     = default(LookAheadSet);
            LookAheadSet             follow    = default(LookAheadSet);
            LookAheadSet             conflicts = default(LookAheadSet);
            LookAheadSet             previous  = new LookAheadSet(0);
            string location = null;
            int    length   = 1;

            // Check trivial cases
            if (pos >= alt.Count)
            {
                return;
            }

            // Check for non-optional element
            pattern = alt.Pattern;
            elem    = alt[pos];
            if (elem.MinCount == elem.MaxCount)
            {
                CalculateLookAhead(alt, pos + 1);
                return;
            }

            // Calculate simple look-aheads
            first  = FindLookAhead(elem, 1, new CallStack(), null);
            follow = FindLookAhead(alt, 1, pos + 1, new CallStack(), null);

            // Resolve conflicts
            location  = "at position " + (pos + 1);
            conflicts = FindConflicts(pattern.Name, location, first, follow);
            while (conflicts.Size() > 0)
            {
                length += 1;
                conflicts.AddAll(previous);
                first          = FindLookAhead(elem, length, new CallStack(), conflicts);
                follow         = FindLookAhead(alt, length, pos + 1, new CallStack(), conflicts);
                first          = first.CreateCombination(follow);
                elem.LookAhead = first;
                if (first.Intersects(conflicts))
                {
                    first = first.CreateIntersection(conflicts);
                    ThrowAmbiguityException(pattern.Name, location, first);
                }
                previous  = conflicts;
                conflicts = FindConflicts(pattern.Name, location, first, follow);
            }

            // Check remaining elements
            CalculateLookAhead(alt, pos + 1);
        }
        //*
        // * Checks if the next tokens match a production pattern. The
        // * pattern look-ahead set will be used if existing, otherwise
        // * this method returns false.
        // *
        // * @param pattern the pattern to check
        // *
        // * @return true if the next tokens match, or
        // * false otherwise
        //

        private bool IsNext(ProductionPattern pattern)
        {
            LookAheadSet @set = pattern.LookAhead;

            if (@set == null)
            {
                return(false);
            }
            else
            {
                return(@set.IsNext(this));
            }
        }
        //*
        // * Checks if the next tokens match a production pattern
        // * alternative. The pattern alternative look-ahead set will be
        // * used if existing, otherwise this method returns false.
        // *
        // * @param alt the pattern alternative to check
        // *
        // * @return true if the next tokens match, or
        // * false otherwise
        //

        private bool IsNext(ProductionPatternAlternative alt)
        {
            LookAheadSet @set = alt.LookAhead;

            if (@set == null)
            {
                return(false);
            }
            else
            {
                return(@set.IsNext(this));
            }
        }
        //*
        // * Creates a new look-ahead set with overlaps from another. All
        // * token sequences in this set that overlaps with the other set
        // * will be added to the new look-ahead set.
        // *
        // * @param set the look-ahead set to check with
        // *
        // * @return a new look-ahead set containing the overlaps
        //

        public LookAheadSet CreateOverlaps(LookAheadSet @set)
        {
            LookAheadSet result = new LookAheadSet(maxLength);
            Sequence     seq    = default(Sequence);

            for (int i = 0; i <= elements.Count - 1; i++)
            {
                seq = (Sequence)elements[i];
                if (@set.IsOverlap(seq))
                {
                    result.Add(seq);
                }
            }
            return(result);
        }
        //*
        // * Throws a parser creation exception for an ambiguity. The
        // * specified look-ahead set contains the token conflicts to be
        // * reported.
        // *
        // * @param pattern the production pattern name
        // * @param location the production pattern location, or null
        // * @param set the look-ahead set with conflicts
        // *
        // * @throws ParserCreationException always thrown by this method
        //

        private void ThrowAmbiguityException(string pattern, string location, LookAheadSet @set)
        {
            ArrayList list = new ArrayList();

            int[] initials = null;

            // Find next token descriptions
            initials = @set.GetInitialTokens();
            for (int i = 0; i <= initials.Length - 1; i++)
            {
                list.Add(GetTokenDescription(initials[i]));
            }

            // Create exception
            throw new ParserCreationException(ParserCreationException.ErrorType.INHERENT_AMBIGUITY, pattern, location, list);
        }
        //*
        // * Creates a new look-ahead set that is the result of reading
        // * the specified token. The new look-ahead set will contain
        // * the rest of all the token sequences that started with the
        // * specified token.
        // *
        // * @param token the token to read
        // *
        // * @return a new look-ahead set containing the remaining tokens
        //

        public LookAheadSet CreateNextSet(int token)
        {
            LookAheadSet result = new LookAheadSet(maxLength - 1);
            Sequence     seq    = default(Sequence);
            object       value  = null;

            for (int i = 0; i <= elements.Count - 1; i++)
            {
                seq   = (Sequence)elements[i];
                value = seq.GetToken(0);
                if (value != null && token == (int)value)
                {
                    result.Add(seq.Subsequence(1));
                }
            }
            return(result);
        }
        //*
        // * Checks if the next tokens match a production pattern
        // * element. If the element has a look-ahead set it will be
        // * used, otherwise the look-ahead set of the referenced
        // * production or token will be used.
        // *
        // * @param elem the pattern element to check
        // *
        // * @return true if the next tokens match, or
        // * false otherwise
        //

        private bool IsNext(ProductionPatternElement elem)
        {
            LookAheadSet @set = elem.LookAhead;

            if (@set != null)
            {
                return(@set.IsNext(this));
            }
            else if (elem.IsToken())
            {
                return(elem.IsMatch(PeekToken(0)));
            }
            else
            {
                return(IsNext(GetPattern(elem.Id)));
            }
        }
        //*
        // * Creates a new identical look-ahead set, except for the
        // * repeat flag being set in each token sequence.
        // *
        // * @return a new repetitive look-ahead set
        //

        public LookAheadSet CreateRepetitive()
        {
            LookAheadSet result = new LookAheadSet(maxLength);
            Sequence     seq    = default(Sequence);

            for (int i = 0; i <= elements.Count - 1; i++)
            {
                seq = (Sequence)elements[i];
                if (seq.IsRepetitive())
                {
                    result.Add(seq);
                }
                else
                {
                    result.Add(new Sequence(true, seq));
                }
            }
            return(result);
        }
Example #14
0
        //*
        // * Returns a string representation of a production pattern.
        // *
        // * @param prod the production pattern
        // *
        // * @return a detailed string representation of the pattern
        //

        private string ToString(ProductionPattern prod)
        {
            StringBuilder buffer = new StringBuilder();
            StringBuilder indent = new StringBuilder();
            LookAheadSet  @set   = default(LookAheadSet);
            int           i      = 0;

            buffer.Append(prod.Name);
            buffer.Append(" (");
            buffer.Append(prod.Id);
            buffer.Append(") ");
            for (i = 0; i <= buffer.Length - 1; i++)
            {
                indent.Append(" ");
            }
            buffer.Append("= ");
            indent.Append("| ");
            for (i = 0; i <= prod.Count - 1; i++)
            {
                if (i > 0)
                {
                    buffer.Append(indent);
                }
                buffer.Append(ToString(prod[i]));
                buffer.Append("" + Convert.ToChar(10) + "");
            }
            for (i = 0; i <= prod.Count - 1; i++)
            {
                @set = prod[i].LookAhead;
                if (@set.GetMaxLength() > 1)
                {
                    buffer.Append("Using ");
                    buffer.Append(@set.GetMaxLength());
                    buffer.Append(" token look-ahead for alternative ");
                    buffer.Append(i + 1);
                    buffer.Append(": ");
                    buffer.Append(@set.ToString(m_tokenizer));
                    buffer.Append("" + Convert.ToChar(10) + "");
                }
            }
            return(buffer.ToString());
        }
        //*
        // * 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);
        }
        //*
        // * Returns a look-ahead set with all conflics between
        // * alternatives in a production pattern.
        // *
        // * @param pattern the production pattern
        // * @param maxLength the maximum token sequence length
        // *
        // * @return a look-ahead set with the conflicts found
        // *
        // * @throws ParserCreationException if an inherent ambiguity was
        // * found among the look-ahead sets
        //

        private LookAheadSet FindConflicts(ProductionPattern pattern, int maxLength)
        {
            LookAheadSet result = new LookAheadSet(maxLength);
            LookAheadSet set1   = default(LookAheadSet);
            LookAheadSet set2   = default(LookAheadSet);

            for (int i = 0; i <= pattern.Count - 1; i++)
            {
                set1 = pattern[i].LookAhead;
                for (int j = 0; j <= i - 1; j++)
                {
                    set2 = pattern[j].LookAhead;
                    result.AddAll(set1.CreateIntersection(set2));
                }
            }
            if (result.IsRepetitive())
            {
                ThrowAmbiguityException(pattern.Name, null, result);
            }
            return(result);
        }
        //*
        // * Creates a new look-ahead set that is the intersection of
        // * this set with another set. The token sequences in the net
        // * set will only have the repeat flag set if it was set in
        // * both the identical token sequences.
        // *
        // * @param set the set to intersect with
        // *
        // * @return a new look-ahead set containing the intersection
        //

        public LookAheadSet CreateIntersection(LookAheadSet @set)
        {
            LookAheadSet result = new LookAheadSet(maxLength);
            Sequence     seq1   = default(Sequence);
            Sequence     seq2   = default(Sequence);

            for (int i = 0; i <= elements.Count - 1; i++)
            {
                seq1 = (Sequence)elements[i];
                seq2 = @set.FindSequence(seq1);
                if (seq2 != null && seq1.IsRepetitive())
                {
                    result.Add(seq2);
                }
                else if (seq2 != null)
                {
                    result.Add(seq1);
                }
            }
            return(result);
        }
        //*
        // * 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 = default(LookAheadSet);
            LookAheadSet first  = default(LookAheadSet);
            LookAheadSet follow = default(LookAheadSet);
            int          max    = 0;

            // 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 - 1; i++)
            {
                first = first.CreateOverlaps(filter);
                if (first.Size() <= 0 || first.GetMinLength() >= length)
                {
                    break;                     // TODO: might not be correct. Was : Exit For
                }
                follow = FindLookAhead(elem, length, 0, stack, filter.CreateFilter(first));
                first  = first.CreateCombination(follow);
                result.AddAll(first);
            }

            return(result);
        }
        //*
        // * Returns the union of all alternative look-ahead sets in a
        // * production pattern.
        // *
        // * @param pattern the production pattern
        // *
        // * @return a unified look-ahead set
        //

        private LookAheadSet FindUnion(ProductionPattern pattern)
        {
            LookAheadSet result = default(LookAheadSet);
            int          length = 0;
            int          i      = 0;

            for (i = 0; i <= pattern.Count - 1; i++)
            {
                result = pattern[i].LookAhead;
                if (result.GetMaxLength() > length)
                {
                    length = result.GetMaxLength();
                }
            }
            result = new LookAheadSet(length);
            for (i = 0; i <= pattern.Count - 1; i++)
            {
                result.AddAll(pattern[i].LookAhead);
            }

            return(result);
        }
        //*
        // * Finds the look-ahead set for a production pattern element. The
        // * maximum look-ahead length must be specified. This method does
        // * NOT take the element repeat into consideration when creating
        // * the look-ahead set. 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 dummy a parameter to distinguish the method
        // * @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, int dummy, CallStack stack, LookAheadSet filter)
        {
            LookAheadSet      result  = default(LookAheadSet);
            ProductionPattern pattern = default(ProductionPattern);

            if (elem.IsToken())
            {
                result = new LookAheadSet(length);
                result.Add(elem.Id);
            }
            else
            {
                pattern = GetPattern(elem.Id);
                result  = FindLookAhead(pattern, length, stack, filter);
                if (stack.Contains(pattern.Name))
                {
                    result = result.CreateRepetitive();
                }
            }

            return(result);
        }
        //*
        // * Creates a new look-ahead set that is the combination of
        // * this set with another set. The combination is created by
        // * creating new token sequences that consist of appending all
        // * elements from the specified set onto all elements in this
        // * set. This is sometimes referred to as the cartesian
        // * product.
        // *
        // * @param set the set to combine with
        // *
        // * @return a new look-ahead set containing the combination
        //

        public LookAheadSet CreateCombination(LookAheadSet @set)
        {
            LookAheadSet result = new LookAheadSet(maxLength);
            Sequence     first  = default(Sequence);
            Sequence     second = default(Sequence);

            // Handle special cases
            if (this.Size() <= 0)
            {
                return(@set);
            }
            else if (@set.Size() <= 0)
            {
                return(this);
            }
            for (int i = 0; i <= elements.Count - 1; i++)
            {
                // Create combinations
                first = (Sequence)elements[i];
                if (first.Length() >= maxLength)
                {
                    result.Add(first);
                }
                else if (first.Length() <= 0)
                {
                    result.AddAll(@set);
                }
                else
                {
                    for (int j = 0; j <= @set.elements.Count - 1; j++)
                    {
                        second = (Sequence)@set.elements[j];
                        result.Add(first.Concat(maxLength, second));
                    }
                }
            }
            return(result);
        }
        //*
        // * Finds the look-ahead set for a production pattern. The 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 pattern the production pattern
        // * @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 production pattern
        // *
        // * @throws ParserCreationException if an infinite loop was found
        // * in the grammar
        //

        private LookAheadSet FindLookAhead(ProductionPattern pattern, int length, CallStack stack, LookAheadSet filter)
        {
            LookAheadSet result = default(LookAheadSet);
            LookAheadSet temp   = default(LookAheadSet);

            // Check for infinite loop
            if (stack.Contains(pattern.Name, length))
            {
                throw new ParserCreationException(ParserCreationException.ErrorType.INFINITE_LOOP, pattern.Name, (string)null);
            }

            // Find pattern look-ahead
            stack.Push(pattern.Name, length);
            result = new LookAheadSet(length);
            for (int i = 0; i <= pattern.Count - 1; i++)
            {
                temp = FindLookAhead(pattern[i], length, 0, stack, filter);
                result.AddAll(temp);
            }
            stack.Pop();

            return(result);
        }
        //*
        // * Throws a parse exception that matches the specified look-ahead
        // * set. This method will take into account any initial matching
        // * tokens in the look-ahead set.
        // *
        // * @param set the look-ahead set to match
        // *
        // * @throws ParseException always thrown by this method
        //

        private void ThrowParseException(LookAheadSet @set)
        {
            Token     token = default(Token);
            ArrayList list  = new ArrayList();

            int[] initials = null;

            // Read tokens until mismatch
            while (@set.IsNext(this, 1))
            {
                @set = @set.CreateNextSet(NextToken().Id);
            }

            // Find next token descriptions
            initials = @set.GetInitialTokens();
            for (int i = 0; i <= initials.Length - 1; i++)
            {
                list.Add(GetTokenDescription(initials[i]));
            }

            // Create exception
            token = NextToken();
            throw new ParseException(ParseException.ErrorType.UNEXPECTED_TOKEN, token.ToShortString(), list, token.StartLine, token.StartColumn);
        }
        //*
        // * Calculates the look-ahead needed for the specified production
        // * pattern. This method attempts to resolve any conflicts and
        // * stores the results in the pattern look-ahead object.
        // *
        // * @param pattern the production pattern
        // *
        // * @throws ParserCreationException if the look-ahead set couldn't
        // * be determined due to inherent ambiguities
        //

        private void CalculateLookAhead(ProductionPattern pattern)
        {
            ProductionPatternAlternative alt = default(ProductionPatternAlternative);
            LookAheadSet result = default(LookAheadSet);

            LookAheadSet[] alternatives = null;
            LookAheadSet   conflicts    = default(LookAheadSet);
            LookAheadSet   previous     = new LookAheadSet(0);
            int            length       = 1;
            int            i            = 0;
            CallStack      stack        = new CallStack();

            // Calculate simple look-ahead
            stack.Push(pattern.Name, 1);
            result       = new LookAheadSet(1);
            alternatives = new LookAheadSet[pattern.Count];
            for (i = 0; i <= pattern.Count - 1; i++)
            {
                alt             = pattern[i];
                alternatives[i] = FindLookAhead(alt, 1, 0, stack, null);
                alt.LookAhead   = alternatives[i];
                result.AddAll(alternatives[i]);
            }
            if (pattern.LookAhead == null)
            {
                pattern.LookAhead = result;
            }
            conflicts = FindConflicts(pattern, 1);

            // Resolve conflicts
            while (conflicts.Size() > 0)
            {
                length += 1;
                stack.Clear();
                stack.Push(pattern.Name, length);
                conflicts.AddAll(previous);
                for (i = 0; i <= pattern.Count - 1; i++)
                {
                    alt = pattern[i];
                    if (alternatives[i].Intersects(conflicts))
                    {
                        alternatives[i] = FindLookAhead(alt, length, 0, stack, conflicts);
                        alt.LookAhead   = alternatives[i];
                    }
                    if (alternatives[i].Intersects(conflicts))
                    {
                        if (pattern.DefaultAlternative == null)
                        {
                            pattern.DefaultAlternative = alt;
                        }
                        else if (!object.ReferenceEquals(pattern.DefaultAlternative, alt))
                        {
                            result = alternatives[i].CreateIntersection(conflicts);
                            ThrowAmbiguityException(pattern.Name, null, result);
                        }
                    }
                }
                previous  = conflicts;
                conflicts = FindConflicts(pattern, length);
            }
            for (i = 0; i <= pattern.Count - 1; i++)
            {
                // Resolve conflicts inside rules
                CalculateLookAhead(pattern[i], 0);
            }
        }
        //*
        // * Creates a duplicate look-ahead set, possibly with a
        // * different maximum length.
        // *
        // * @param maxLength the maximum token sequence length
        // * @param set the look-ahead set to copy
        //

        public LookAheadSet(int maxLength, LookAheadSet @set)
            : this(maxLength)
        {
            AddAll(@set);
        }