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