private double ScanNumber() { Debug.Assert(this.CurerntChar == '.' || XmlCharType.IsDigit(this.CurerntChar)); int start = xpathExprIndex - 1; int len = 0; while (XmlCharType.IsDigit(this.CurerntChar)) { NextChar(); len++; } if (this.CurerntChar == '.') { NextChar(); len++; while (XmlCharType.IsDigit(this.CurerntChar)) { NextChar(); len++; } } return(XmlConvert.ToXPathDouble(this.xpathExpr.Substring(start, len))); }
private double ScanNumber() { Debug.Assert(CurrentChar == '.' || XmlCharType.IsDigit(CurrentChar)); var start = _XpathExprIndex - 1; var len = 0; while (XmlCharType.IsDigit(CurrentChar)) { NextChar(); len++; } if (CurrentChar != '.') { return(ToXPathDouble(SourceText.Substring(start, len))); } NextChar(); len++; while (XmlCharType.IsDigit(CurrentChar)) { NextChar(); len++; } return(ToXPathDouble(SourceText.Substring(start, len))); }
public bool NextLex() { SkipSpace(); switch (this.CurerntChar) { 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.CurerntChar); NextChar(); break; case '<': kind = LexKind.Lt; NextChar(); if (this.CurerntChar == '=') { kind = LexKind.Le; NextChar(); } break; case '>': kind = LexKind.Gt; NextChar(); if (this.CurerntChar == '=') { kind = LexKind.Ge; NextChar(); } break; case '!': kind = LexKind.Bang; NextChar(); if (this.CurerntChar == '=') { kind = LexKind.Ne; NextChar(); } break; case '.': kind = LexKind.Dot; NextChar(); if (this.CurerntChar == '.') { kind = LexKind.DotDot; NextChar(); } else if (XmlCharType.IsDigit(this.CurerntChar)) { kind = LexKind.Number; numberValue = ScanFraction(); } break; case '/': kind = LexKind.Slash; NextChar(); if (this.CurerntChar == '/') { kind = LexKind.SlashSlash; NextChar(); } break; case '"': case '\'': this.kind = LexKind.String; this.stringValue = ScanString(); break; default: if (XmlCharType.IsDigit(this.CurerntChar)) { kind = LexKind.Number; numberValue = ScanNumber(); } else if (XmlCharType.IsStartNCNameChar(this.CurerntChar)) { 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.CurerntChar == ':') { NextChar(); // can be "foo:bar" or "foo::" if (this.CurerntChar == ':') // "foo::" { NextChar(); kind = LexKind.Axe; } else // "foo:*", "foo:bar" or "foo: " { this.prefix = this.name; if (this.CurerntChar == '*') { NextChar(); this.name = "*"; } else if (XmlCharType.IsStartNCNameChar(this.CurerntChar)) { this.name = ScanName(); } else { throw new XPathException(Res.Xp_InvalidName, SourceText); } } } else { SkipSpace(); if (this.CurerntChar == ':') { NextChar(); // it can be "foo ::" or just "foo :" if (this.CurerntChar == ':') { NextChar(); kind = LexKind.Axe; } else { throw new XPathException(Res.Xp_InvalidName, SourceText); } } } SkipSpace(); this.canBeFunction = (this.CurerntChar == '('); } else { throw new XPathException(Res.Xp_InvalidToken, SourceText); } break; } return(true); }
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); }
private void SkipSpace() { while (XmlCharType.IsWhiteSpace(CurrentChar) && NextChar()) { } }