Example #1
0
        /// <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);
        }
Example #2
0
        /**
         * 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;
            LookAheadSet temp;

            // 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; i++)
            {
                temp = FindLookAhead(pattern[i],
                                     length,
                                     0,
                                     stack,
                                     filter);
                result.AddAll(temp);
            }
            stack.Pop();

            return(result);
        }
Example #3
0
        /// <summary>
        /// Returns a look-ahead set with all conflicts between
        /// alternatives in a production pattern.
        /// </summary>
        /// <param name="pattern">The production pattern</param>
        /// <param name="maxLength">The maximum token sequence length</param>
        /// <returns>A look-ahead set with the conflicts found</returns>
        /// <exception cref="ParserCreationException">
        /// If an inherent ambiguity was found among the look-ahead sets
        /// </exception>
        private LookAheadSet FindConflicts(
            ProductionPattern pattern,
            int maxLength)
        {
            LookAheadSet result = new LookAheadSet(maxLength);
            LookAheadSet set1;
            LookAheadSet set2;

            for (int i = 0; i < pattern.Count; i++)
            {
                set1 = pattern[i].LookAhead;
                for (int j = 0; j < i; j++)
                {
                    set2 = pattern[j].LookAhead;
                    result.AddAll(set1.CreateIntersection(set2));
                }
            }

            if (result.IsRepetitive)
            {
                this.ThrowAmbiguityException(pattern.Name, null, result);
            }

            return(result);
        }
Example #4
0
        /**
         * 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;
            int          length = 0;
            int          i;

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

            return(result);
        }
Example #5
0
        /**
         * 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;
            Sequence     second;

            // Handle special cases
            if (Size() <= 0)
            {
                return(set);
            }
            else if (set.Size() <= 0)
            {
                return(this);
            }

            // Create combinations
            for (int i = 0; i < elements.Count; i++)
            {
                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; j++)
                    {
                        second = (Sequence)set.elements[j];
                        result.Add(first.Concat(maxLength, second));
                    }
                }
            }
            return(result);
        }
Example #6
0
        /// <summary>
        /// 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.
        /// </summary>
        /// <param name="set">The set to combine with</param>
        /// <returns>
        /// A new look-ahead set containing the combination
        /// </returns>
        public LookAheadSet CreateCombination(LookAheadSet set)
        {
            LookAheadSet result = new LookAheadSet(this.maxLength);

            // Handle special cases
            if (this.Size <= 0)
            {
                return(set);
            }
            else if (set.Size <= 0)
            {
                return(this);
            }

            // Create combinations
            foreach (var first in this.elements)
            {
                if (first.Length >= this.maxLength)
                {
                    result.Add(first);
                }
                else if (first.Length <= 0)
                {
                    result.AddAll(set);
                }
                else
                {
                    foreach (var second in set.elements)
                    {
                        result.Add(first.Concat(this.maxLength, second));
                    }
                }
            }

            return(result);
        }
Example #7
0
        /**
         * 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;
            Sequence      second;

            // Handle special cases
            if (this.Size() <= 0) {
                return set;
            } else if (set.Size() <= 0) {
                return this;
            }

            // Create combinations
            for (int i = 0; i < elements.Count; i++) {
                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; j++) {
                        second = (Sequence) set.elements[j];
                        result.Add(first.Concat(maxLength, second));
                    }
                }
            }
            return result;
        }
Example #8
0
        /**
         * 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;
            LookAheadSet result;

            LookAheadSet[] alternatives;
            LookAheadSet   conflicts;
            LookAheadSet   previous = new LookAheadSet(0);
            int            length   = 1;
            int            i;
            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; 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++;
                stack.Clear();
                stack.Push(pattern.Name, length);
                conflicts.AddAll(previous);
                for (i = 0; i < pattern.Count; 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 (pattern.DefaultAlternative != alt)
                        {
                            result = alternatives[i].CreateIntersection(conflicts);
                            ThrowAmbiguityException(pattern.Name,
                                                    null,
                                                    result);
                        }
                    }
                }
                previous  = conflicts;
                conflicts = FindConflicts(pattern, length);
            }

            // Resolve conflicts inside rules
            for (i = 0; i < pattern.Count; i++)
            {
                CalculateLookAhead(pattern[i], 0);
            }
        }
        /**
         * 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;
            int           length = 0;
            int           i;

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

            return result;
        }
        /**
         * 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;
            LookAheadSet  set2;

            for (int i = 0; i < pattern.Count; i++) {
                set1 = pattern[i].LookAhead;
                for (int j = 0; j < i; j++) {
                    set2 = pattern[j].LookAhead;
                    result.AddAll(set1.CreateIntersection(set2));
                }
            }
            if (result.IsRepetitive()) {
                ThrowAmbiguityException(pattern.Name, null, result);
            }
            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;
            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. 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;
            LookAheadSet  temp;

            // 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; i++) {
                temp = FindLookAhead(pattern[i],
                                     length,
                                     0,
                                     stack,
                                     filter);
                result.AddAll(temp);
            }
            stack.Pop();

            return result;
        }
        /**
         * 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;
            LookAheadSet                  result;
            LookAheadSet[]                alternatives;
            LookAheadSet                  conflicts;
            LookAheadSet                  previous = new LookAheadSet(0);
            int                           length = 1;
            int                           i;
            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; 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++;
                stack.Clear();
                stack.Push(pattern.Name, length);
                conflicts.AddAll(previous);
                for (i = 0; i < pattern.Count; 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 (pattern.DefaultAlternative != alt) {
                            result = alternatives[i].CreateIntersection(conflicts);
                            ThrowAmbiguityException(pattern.Name,
                                                    null,
                                                    result);
                        }
                    }
                }
                previous = conflicts;
                conflicts = FindConflicts(pattern, length);
            }

            // Resolve conflicts inside rules
            for (i = 0; i < pattern.Count; i++) {
                CalculateLookAhead(pattern[i], 0);
            }
        }