Пример #1
0
        /**
         * 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;
            ProductionPattern pattern;

            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);
        }
Пример #2
0
 /**
  * Checks a production pattern element for completeness. If
  * the element references a production pattern not added to
  * this parser, a parser creation exception will be thrown.
  *
  * @param name           the name of the pattern being checked
  * @param elem           the production pattern element to check
  *
  * @throws ParserCreationException if the element referenced a
  *             pattern not added to this parser
  */
 private void CheckElement(string name,
                           ProductionPatternElement elem)
 {
     if (elem.IsProduction() && GetPattern(elem.Id) == null)
     {
         throw new ParserCreationException(
                   ParserCreationException.ErrorType.INVALID_PRODUCTION,
                   name,
                   "an undefined production pattern id (" + elem.Id +
                   ") is referenced");
     }
 }
Пример #3
0
 /**
  * Adds a production pattern element to this alternative. The
  * multiplicity values in the element will be overridden with
  * the specified values. The element is appended to the end of
  * the element list.
  *
  * @param elem           the production pattern element
  * @param min            the minimum number of occurancies
  * @param max            the maximum number of occurancies, or
  *                       -1 for infinite
  */
 public void AddElement(ProductionPatternElement elem,
                        int min,
                        int max)
 {
     if (elem.IsToken())
     {
         AddToken(elem.Id, min, max);
     }
     else
     {
         AddProduction(elem.Id, min, max);
     }
 }
Пример #4
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;
            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);
        }
Пример #5
0
        /**
         * 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)));
            }
        }
Пример #6
0
        /**
         * Parses a production pattern element. All nodes parsed may
         * or may not be added to the parse tree node specified,
         * depending on the analyzer callbacks.
         *
         * @param node           the production parse tree node
         * @param elem           the production pattern element to parse
         *
         * @throws ParseException if the input couldn't be parsed
         *             correctly
         */
        private void ParseElement(Production node,
                                  ProductionPatternElement elem)
        {
            Node child;

            for (int i = 0; i < elem.MaxCount; i++)
            {
                string pr = Enum.GetName(typeof(SyntaxConstants), elem.GetId());
                if (i < elem.MinCount || IsNext(elem))
                {
                    if (elem.IsToken())
                    {
                        child = NextToken(elem.Id);
                        EnterNode(child);
                        AddNode(node, ExitNode(child));
                        if (ExitNode(child) != null)
                        {
                            production.AddRecursiveProduction("Enter: " + pr + "\n");
                        }
                        production.AddProductionCode(elem.GetId());
                        production.AddProductionState("Enter: " + pr + "\n");
                    }
                    else
                    {
                        pr = pr.Substring(5);
                        production.AddRecursiveProduction("Enter: <" + pr + ">\n");
                        production.AddProductionCode(elem.GetId());
                        production.AddProductionState("Enter: <" + pr + ">\n");
                        child = ParsePattern(GetPattern(elem.Id));
                        AddNode(node, child);
                    }
                }
                else
                {
                    pr = pr.Substring(5);
                    production.AddRecursiveProduction("Enter: NULL <" + pr + ">\n");
                    production.AddProductionState("NULL");
                    production.AddProductionCode(elem.GetId());
                    break;
                }
            }
        }
Пример #7
0
        /**
         * Returns a string representation of a production pattern
         * element.
         *
         * @param elem           the production pattern element
         *
         * @return a detailed string representation of the element
         */
        private string ToString(ProductionPatternElement elem)
        {
            StringBuilder buffer = new StringBuilder();
            int           min    = elem.MinCount;
            int           max    = elem.MaxCount;

            if (min == 0 && max == 1)
            {
                buffer.Append("[");
            }
            if (elem.IsToken())
            {
                buffer.Append(GetTokenDescription(elem.Id));
            }
            else
            {
                buffer.Append(GetPattern(elem.Id).Name);
            }
            if (min == 0 && max == 1)
            {
                buffer.Append("]");
            }
            else if (min == 0 && max == Int32.MaxValue)
            {
                buffer.Append("*");
            }
            else if (min == 1 && max == Int32.MaxValue)
            {
                buffer.Append("+");
            }
            else if (min != 1 || max != 1)
            {
                buffer.Append("{");
                buffer.Append(min);
                buffer.Append(",");
                buffer.Append(max);
                buffer.Append("}");
            }
            return(buffer.ToString());
        }
Пример #8
0
 /**
  * Adds a production pattern element to this alternative. The
  * element is appended to the end of the element list.
  *
  * @param elem           the production pattern element
  */
 public void AddElement(ProductionPatternElement elem)
 {
     elements.Add(elem);
 }