//*
        // * 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 = default(Node);

            for (int i = 0; i <= elem.MaxCount - 1; i++)
            {
                if (i < elem.MinCount || IsNext(elem))
                {
                    if (elem.IsToken())
                    {
                        child = NextToken(elem.Id);
                        EnterNode(child);
                        AddNode(node, ExitNode(child));
                    }
                    else
                    {
                        child = ParsePattern(GetPattern(elem.Id));
                        AddNode(node, child);
                    }
                }
                else
                {
                    break;                     // TODO: might not be correct. Was : Exit For
                }
            }
        }
        //*
        // * 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);
            }
        }
        //*
        // * 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)));
            }
        }
Ejemplo n.º 4
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());
        }
        //*
        // * 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);
        }