Exemplo n.º 1
0
        private string ScanName()
        {
            Debug.Assert(XmlCharType.IsStartNcNameChar(CurrentChar));
            var start = _XpathExprIndex - 1;
            var len   = 0;

            while (XmlCharType.IsNcNameChar(CurrentChar))
            {
                NextChar();
                len++;
            }
            return(SourceText.Substring(start, len));
        }
Exemplo n.º 2
0
        public bool NextLex()
        {
            SkipSpace();
            switch (CurrentChar)
            {
            case '\0':
                Kind = LexKind.Eof;
                return(false);

            case ',':
            case '@':
            case '(':
            case ')':
            case '|':
            case '*':
            case '[':
            case ']':
            case '+':
            case '-':
            case '=':
            case '#':
            case '$':
                Kind = (LexKind)Convert.ToInt32(CurrentChar);
                NextChar();
                break;

            case '<':
                Kind = LexKind.Lt;
                NextChar();
                if (CurrentChar == '=')
                {
                    Kind = LexKind.Le;
                    NextChar();
                }
                break;

            case '>':
                Kind = LexKind.Gt;
                NextChar();
                if (CurrentChar == '=')
                {
                    Kind = LexKind.Ge;
                    NextChar();
                }
                break;

            case '!':
                Kind = LexKind.Bang;
                NextChar();
                if (CurrentChar == '=')
                {
                    Kind = LexKind.Ne;
                    NextChar();
                }
                break;

            case '.':
                Kind = LexKind.Dot;
                NextChar();
                if (CurrentChar == '.')
                {
                    Kind = LexKind.DotDot;
                    NextChar();
                }
                else if (XmlCharType.IsDigit(CurrentChar))
                {
                    Kind         = LexKind.Number;
                    _NumberValue = ScanFraction();
                }
                break;

            case '/':
                Kind = LexKind.Slash;
                NextChar();
                if (CurrentChar == '/')
                {
                    Kind = LexKind.SlashSlash;
                    NextChar();
                }
                break;

            case '"':
            case '\'':
                Kind         = LexKind.String;
                _StringValue = ScanString();
                break;

            default:
                if (XmlCharType.IsDigit(CurrentChar))
                {
                    Kind         = LexKind.Number;
                    _NumberValue = ScanNumber();
                }
                else if (XmlCharType.IsStartNcNameChar(CurrentChar))
                {
                    Kind    = LexKind.Name;
                    _Name   = ScanName();
                    _Prefix = string.Empty;
                    // "foo:bar" is one lexem not three because it doesn't allow spaces in between
                    // We should distinct it from "foo::" and need process "foo ::" as well
                    if (CurrentChar == ':')
                    {
                        NextChar();
                        // can be "foo:bar" or "foo::"
                        if (CurrentChar == ':')
                        {
                            // "foo::"
                            NextChar();
                            Kind = LexKind.Axe;
                        }
                        else
                        {
                            // "foo:*", "foo:bar" or "foo: "
                            _Prefix = _Name;
                            if (CurrentChar == '*')
                            {
                                NextChar();
                                _Name = "*";
                            }
                            else if (XmlCharType.IsStartNcNameChar(CurrentChar))
                            {
                                _Name = ScanName();
                            }
                            else
                            {
                                throw new XPathException($"'{SourceText}' has an invalid qualified name.");
                            }
                        }
                    }
                    else
                    {
                        SkipSpace();
                        if (CurrentChar == ':')
                        {
                            NextChar();
                            // it can be "foo ::" or just "foo :"
                            if (CurrentChar == ':')
                            {
                                NextChar();
                                Kind = LexKind.Axe;
                            }
                            else
                            {
                                throw new XPathException($"'{SourceText}' has an invalid qualified name.");
                            }
                        }
                    }
                    SkipSpace();
                    _CanBeFunction = CurrentChar == '(';
                }
                else
                {
                    throw new XPathException($"'{SourceText}' has an invalid token.");
                }
                break;
            }
            return(true);
        }