Example #1
0
        /*
         *   StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest Predicate*
         *   ChildOrAttributeAxisSpecifier ::= @ ? | ('child' | 'attribute') '::'
         */
        private QilNode ParseStepPattern()
        {
            QilNode   opnd;
            XPathAxis axis;

            switch (scanner.Kind)
            {
            case LexKind.Dot:
            case LexKind.DotDot:
                throw scanner.CreateException(Res.XPath_InvalidAxisInPattern);

            case LexKind.At:                               //>> '@'
                axis = XPathAxis.Attribute;
                scanner.NextLex();
                break;

            case LexKind.Axis:                             //>> AxisName '::'
                axis = XPathParser.GetAxis(scanner.Name, scanner);
                if (axis != XPathAxis.Child && axis != XPathAxis.Attribute)
                {
                    throw scanner.CreateException(Res.XPath_InvalidAxisInPattern);
                }
                scanner.NextLex();
                break;

            case LexKind.Name:
            case LexKind.Star:
                // NodeTest must start with Name or '*'
                axis = XPathAxis.Child;
                break;

            default:
                throw scanner.CreateException(Res.XPath_UnexpectedToken, scanner.RawValue);
            }

            XPathNodeType nodeType;
            string        nodePrefix, nodeName;

            XPathParser.InternalParseNodeTest(scanner, axis, out nodeType, out nodePrefix, out nodeName);
            opnd = ptrnBuilder.Axis(axis, nodeType, nodePrefix, nodeName);

            while (scanner.Kind == LexKind.LBracket)
            {
                opnd = ptrnBuilder.Predicate(opnd, ParsePredicate(opnd), /*reverseStep:*/ false);
            }
            return(opnd);
        }
        /*
         *   StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest Predicate*
         *   ChildOrAttributeAxisSpecifier ::= @ ? | ('child' | 'attribute') '::'
         */
        private QilNode ParseStepPattern()
        {
            QilNode   opnd;
            XPathAxis axis;

            switch (_scanner.Kind)
            {
            case LexKind.Dot:
            case LexKind.DotDot:
                throw _scanner.CreateException(SR.XPath_InvalidAxisInPattern);

            case LexKind.At:
                axis = XPathAxis.Attribute;
                _scanner.NextLex();
                break;

            case LexKind.Axis:
                axis = _scanner.Axis;
                if (axis != XPathAxis.Child && axis != XPathAxis.Attribute)
                {
                    throw _scanner.CreateException(SR.XPath_InvalidAxisInPattern);
                }
                _scanner.NextLex();      // Skip '::'
                _scanner.NextLex();
                break;

            case LexKind.Name:
            case LexKind.Star:
                // NodeTest must start with Name or '*'
                axis = XPathAxis.Child;
                break;

            default:
                throw _scanner.CreateException(SR.XPath_UnexpectedToken, _scanner.RawValue);
            }

            XPathNodeType nodeType;
            string        nodePrefix, nodeName;

            XPathParser.InternalParseNodeTest(_scanner, axis, out nodeType, out nodePrefix, out nodeName);
            opnd = _ptrnBuilder.Axis(axis, nodeType, nodePrefix, nodeName);

            XPathPatternBuilder xpathPatternBuilder = _ptrnBuilder as XPathPatternBuilder;

            if (xpathPatternBuilder != null)
            {
                //for XPathPatternBuilder, get all predicates and then build them
                List <QilNode> predicates = new List <QilNode>();
                while (_scanner.Kind == LexKind.LBracket)
                {
                    predicates.Add(ParsePredicate(opnd));
                }
                if (predicates.Count > 0)
                {
                    opnd = xpathPatternBuilder.BuildPredicates(opnd, predicates);
                }
            }
            else
            {
                while (_scanner.Kind == LexKind.LBracket)
                {
                    opnd = _ptrnBuilder.Predicate(opnd, ParsePredicate(opnd), /*reverseStep:*/ false);
                }
            }
            return(opnd);
        }