コード例 #1
0
        //*
        // * 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);
        }
コード例 #2
0
        //*
        // * 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);
        }
コード例 #3
0
        //*
        // * 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);
        }