示例#1
0
 /**
  * Checks a production pattern for completeness. If some rule
  * in the pattern referenced an production pattern not added
  * to this parser, a parser creation exception will be thrown.
  *
  * @param pattern        the production pattern to check
  *
  * @throws ParserCreationException if the pattern referenced a
  *             pattern not added to this parser
  */
 private void CheckPattern(ProductionPattern pattern)
 {
     for (int i = 0; i < pattern.Count; i++)
     {
         CheckAlternative(pattern.Name, pattern[i]);
     }
 }
        /**
         * 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);
        }
        /**
         * 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));
            }
        }
示例#4
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;
            int           i;

            buffer.Append(prod.Name);
            buffer.Append(" (");
            buffer.Append(prod.Id);
            buffer.Append(") ");
            for (i = 0; i < buffer.Length; i++)
            {
                indent.Append(" ");
            }
            buffer.Append("= ");
            indent.Append("| ");
            for (i = 0; i < prod.Count; i++)
            {
                if (i > 0)
                {
                    buffer.Append(indent);
                }
                buffer.Append(ToString(prod[i]));
                buffer.Append("\n");
            }
            for (i = 0; i < prod.Count; 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(tokenizer));
                    buffer.Append("\n");
                }
            }
            return(buffer.ToString());
        }
        /**
         * Parses a production pattern. A parse tree node may or may
         * not be created depending on the analyzer callbacks.
         *
         * @param pattern        the production pattern to parse
         *
         * @return the parse tree node created, or null
         *
         * @throws ParseException if the input couldn't be parsed
         *             correctly
         */
        private Node ParsePattern(ProductionPattern pattern)
        {
            ProductionPatternAlternative alt;
            ProductionPatternAlternative defaultAlt;

            defaultAlt = pattern.DefaultAlternative;
            for (int i = 0; i < pattern.Count; i++)
            {
                alt = pattern[i];
                if (defaultAlt != alt && IsNext(alt))
                {
                    return(ParseAlternative(alt));
                }
            }
            if (defaultAlt == null || !IsNext(defaultAlt))
            {
                ThrowParseException(FindUnion(pattern));
            }
            return(ParseAlternative(defaultAlt));
        }
        /**
         * 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);
        }
示例#8
0
 /**
  * Adds a new production pattern to the parser. The first pattern
  * added is assumed to be the starting point in the grammar. The
  * patterns added may be validated to some extent.
  *
  * @param pattern        the pattern to add
  *
  * @throws ParserCreationException if the pattern couldn't be
  *             added correctly to the parser
  */
 public virtual void AddPattern(ProductionPattern pattern)
 {
     if (pattern.Count <= 0)
     {
         throw new ParserCreationException(
                   ParserCreationException.ErrorType.INVALID_PRODUCTION,
                   pattern.Name,
                   "no production alternatives are present (must have at " +
                   "least one)");
     }
     if (patternIds.ContainsKey(pattern.Id))
     {
         throw new ParserCreationException(
                   ParserCreationException.ErrorType.INVALID_PRODUCTION,
                   pattern.Name,
                   "another pattern with the same id (" + pattern.Id +
                   ") has already been added");
     }
     patterns.Add(pattern);
     patternIds.Add(pattern.Id, pattern);
     SetInitialized(false);
 }
        /**
         * Adds a new production pattern to the parser. The pattern
         * will be added last in the list. The first pattern added is
         * assumed to be the starting point in the grammar. The
         * pattern will be validated against the grammar type to some
         * extent.
         *
         * @param pattern        the pattern to add
         *
         * @throws ParserCreationException if the pattern couldn't be
         *             added correctly to the parser
         */
        public override void AddPattern(ProductionPattern pattern)
        {
            // Check for empty matches
            if (pattern.IsMatchingEmpty())
            {
                throw new ParserCreationException(
                          ParserCreationException.ErrorType.INVALID_PRODUCTION,
                          pattern.Name,
                          "zero elements can be matched (minimum is one)");
            }

            // Check for left-recusive patterns
            if (pattern.IsLeftRecursive())
            {
                throw new ParserCreationException(
                          ParserCreationException.ErrorType.INVALID_PRODUCTION,
                          pattern.Name,
                          "left recursive patterns are not allowed");
            }

            // Add pattern
            base.AddPattern(pattern);
        }
示例#10
0
 /**
  * Creates a new production node.
  *
  * @param pattern        the production pattern
  */
 public Production(ProductionPattern pattern)
 {
     this.pattern  = pattern;
     this.children = new ArrayList();
 }
示例#11
0
 /**
  * Changes the production pattern containing this alternative.
  * This method should only be called by the production pattern
  * class.
  *
  * @param pattern        the new production pattern
  */
 internal void SetPattern(ProductionPattern pattern)
 {
     this.pattern = pattern;
 }
        /**
         * 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);
            }
        }
示例#13
0
 /**
  * Factory method to create a new production node. This method
  * can be overridden to provide other production implementations
  * than the default one.
  *
  * @param pattern        the production pattern
  *
  * @return the new production node
  *
  *
  */
 protected virtual Production NewProduction(ProductionPattern pattern)
 {
     return(analyzer.NewProduction(pattern));
 }
示例#14
0
 /**
  * Factory method to create a new production node. This method
  * can be overridden to provide other production implementations
  * than the default one.
  *
  * @param pattern        the production pattern
  *
  * @return the new production node
  *
  */
 public virtual Production NewProduction(ProductionPattern pattern)
 {
     return(new Production(pattern));
 }