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)); }
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); }