Ejemplo n.º 1
0
        public void NextLex()
        {
            prevLexEnd = curIndex;
            prevKind   = kind;
            SkipSpace();
            lexStart = curIndex;

            switch (curChar)
            {
            case '\0':
                kind = LexKind.Eof;
                return;

            case '(':
            case ')':
            case '[':
            case ']':
            case '@':
            case ',':
            case '$':
            case '}':
                kind = (LexKind)curChar;
                NextChar();
                break;

            case '.':
                NextChar();
                if (curChar == '.')
                {
                    kind = LexKind.DotDot;
                    NextChar();
                }
                else if (IsAsciiDigit(curChar))
                {
                    SetSourceIndex(lexStart);
                    goto case '0';
                }
                else
                {
                    kind = LexKind.Dot;
                }
                break;

            case ':':
                NextChar();
                if (curChar == ':')
                {
                    kind = LexKind.ColonColon;
                    NextChar();
                }
                else
                {
                    kind = LexKind.Unknown;
                }
                break;

            case '*':
                kind = LexKind.Star;
                NextChar();
                CheckOperator(true);
                break;

            case '/':
                NextChar();
                if (curChar == '/')
                {
                    kind = LexKind.SlashSlash;
                    NextChar();
                }
                else
                {
                    kind = LexKind.Slash;
                }
                break;

            case '|':
                kind = LexKind.Union;
                NextChar();
                break;

            case '+':
                kind = LexKind.Plus;
                NextChar();
                break;

            case '-':
                kind = LexKind.Minus;
                NextChar();
                break;

            case '=':
                kind = LexKind.Eq;
                NextChar();
                break;

            case '!':
                NextChar();
                if (curChar == '=')
                {
                    kind = LexKind.Ne;
                    NextChar();
                }
                else
                {
                    kind = LexKind.Unknown;
                }
                break;

            case '<':
                NextChar();
                if (curChar == '=')
                {
                    kind = LexKind.Le;
                    NextChar();
                }
                else
                {
                    kind = LexKind.Lt;
                }
                break;

            case '>':
                NextChar();
                if (curChar == '=')
                {
                    kind = LexKind.Ge;
                    NextChar();
                }
                else
                {
                    kind = LexKind.Gt;
                }
                break;

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

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                kind = LexKind.Number;
                ScanNumber();
                break;

            default:
                if (xmlCharType.IsStartNCNameSingleChar(curChar)
#if XML10_FIFTH_EDITION
                    || xmlCharType.IsNCNameHighSurrogateChar(curChar)
#endif
                    )
                {
                    kind               = LexKind.Name;
                    this.name          = ScanNCName();
                    this.prefix        = string.Empty;
                    this.canBeFunction = false;
                    this.axis          = XPathAxis.Unknown;
                    bool colonColon      = false;
                    int  saveSourceIndex = curIndex;

                    // "foo:bar" or "foo:*" -- one lexeme (no spaces allowed)
                    // "foo::" or "foo ::"  -- two lexemes, reported as one (AxisName)
                    // "foo:?" or "foo :?"  -- lexeme "foo" reported
                    if (curChar == ':')
                    {
                        NextChar();
                        if (curChar == ':')         // "foo::" -> OperatorName, AxisName
                        {
                            NextChar();
                            colonColon = true;
                            SetSourceIndex(saveSourceIndex);
                        }
                        else                        // "foo:bar", "foo:*" or "foo:?"
                        {
                            if (curChar == '*')
                            {
                                NextChar();
                                this.prefix = this.name;
                                this.name   = "*";
                            }
                            else if (xmlCharType.IsStartNCNameSingleChar(curChar)
#if XML10_FIFTH_EDITION
                                     || xmlCharType.IsNCNameHighSurrogateChar(curChar)
#endif
                                     )
                            {
                                this.prefix = this.name;
                                this.name   = ScanNCName();
                                // Look ahead for '(' to determine whether QName can be a FunctionName
                                saveSourceIndex = curIndex;
                                SkipSpace();
                                this.canBeFunction = (curChar == '(');
                                SetSourceIndex(saveSourceIndex);
                            }
                            else                    // "foo:?" -> OperatorName, NameTest
                            // Return "foo" and leave ":" to be reported later as an unknown lexeme
                            {
                                SetSourceIndex(saveSourceIndex);
                            }
                        }
                    }
                    else
                    {
                        SkipSpace();
                        if (curChar == ':')         // "foo ::" or "foo :?"
                        {
                            NextChar();
                            if (curChar == ':')
                            {
                                NextChar();
                                colonColon = true;
                            }
                            SetSourceIndex(saveSourceIndex);
                        }
                        else
                        {
                            this.canBeFunction = (curChar == '(');
                        }
                    }
                    if (!CheckOperator(false) && colonColon)
                    {
                        this.axis = CheckAxis();
                    }
                }
                else
                {
                    kind = LexKind.Unknown;
                    NextChar();
                }
                break;
            }
        }
Ejemplo n.º 2
0
        public bool NextLex()
        {
            SkipSpace();
            switch (this.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(this.CurrentChar, CultureInfo.InvariantCulture);
                NextChar();
                break;

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

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

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

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

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

            case '"':
            case '\'':
                this.kind        = LexKind.String;
                this.stringValue = ScanString();
                break;

            default:
                if (XmlCharType.IsDigit(this.CurrentChar))
                {
                    kind        = LexKind.Number;
                    numberValue = ScanNumber();
                }
                else if (xmlCharType.IsStartNCNameSingleChar(this.CurrentChar)
#if XML10_FIFTH_EDITION
                         || xmlCharType.IsNCNameHighSurrogateChar(this.CurerntChar)
#endif
                         )
                {
                    kind        = LexKind.Name;
                    this.name   = ScanName();
                    this.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 (this.CurrentChar == ':')
                    {
                        NextChar();
                        // can be "foo:bar" or "foo::"
                        if (this.CurrentChar == ':')
                        {       // "foo::"
                            NextChar();
                            kind = LexKind.Axe;
                        }
                        else
                        {                              // "foo:*", "foo:bar" or "foo: "
                            this.prefix = this.name;
                            if (this.CurrentChar == '*')
                            {
                                NextChar();
                                this.name = "*";
                            }
                            else if (xmlCharType.IsStartNCNameSingleChar(this.CurrentChar)
#if XML10_FIFTH_EDITION
                                     || xmlCharType.IsNCNameHighSurrogateChar(this.CurerntChar)
#endif
                                     )
                            {
                                this.name = ScanName();
                            }
                            else
                            {
                                throw XPathException.Create(SR.Xp_InvalidName, SourceText);
                            }
                        }
                    }
                    else
                    {
                        SkipSpace();
                        if (this.CurrentChar == ':')
                        {
                            NextChar();
                            // it can be "foo ::" or just "foo :"
                            if (this.CurrentChar == ':')
                            {
                                NextChar();
                                kind = LexKind.Axe;
                            }
                            else
                            {
                                throw XPathException.Create(SR.Xp_InvalidName, SourceText);
                            }
                        }
                    }
                    SkipSpace();
                    this.canBeFunction = (this.CurrentChar == '(');
                }
                else
                {
                    throw XPathException.Create(SR.Xp_InvalidToken, SourceText);
                }
                break;
            }
            return(true);
        }