internal void Clear() { this.number = double.NaN; this.prefix = string.Empty; this.name = string.Empty; this.tokenID = XPathTokenID.Unknown; }
private void TokenizeNumber() { XPathTokenID id = XPathTokenID.Integer; // Read all the digits for (; XPathCharTypes.IsDigit(this.ch); AdvanceChar()) { ; } if (this.ch == '.') { AdvanceChar(); if (XPathCharTypes.IsDigit(this.ch)) { id = XPathTokenID.Decimal; // Read all the digits after the decimal point for (; XPathCharTypes.IsDigit(this.ch); AdvanceChar()) { ; } } } PutbackChar(); // The converted double double d = QueryValueModel.Double(CurrentSubstring()); // flip the sign if we're negative token.Set(id, d); }
private void TokenizeNumber() { XPathTokenID integer = XPathTokenID.Integer; while (XPathCharTypes.IsDigit(this.ch)) { this.AdvanceChar(); } if (this.ch == '.') { this.AdvanceChar(); if (XPathCharTypes.IsDigit(this.ch)) { integer = XPathTokenID.Decimal; while (XPathCharTypes.IsDigit(this.ch)) { this.AdvanceChar(); } } } this.PutbackChar(); double number = QueryValueModel.Double(this.CurrentSubstring()); this.token.Set(integer, number); }
private XPathExprList ParseAbsolutePath() { XPathExprList path = null; XPathToken token = this.NextToken(); if (token != null) { XPathTokenID tokenID = token.TokenID; if (tokenID == XPathTokenID.Slash) { path = new XPathExprList(); path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root))); } else if (tokenID == XPathTokenID.DblSlash) { path = new XPathExprList(); path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.Child, NodeQName.Empty, QueryNodeType.Root))); path.Add(new XPathStepExpr(new NodeSelectCriteria(QueryAxisType.DescendantOrSelf, NodeQName.Empty, QueryNodeType.All))); } else { this.PushToken(token); } } if (path != null) { this.ParseRelativePath(path); } return(path); }
internal void Set(XPathTokenID id, string name) { Fx.Assert(null != name, ""); this.Clear(); this.tokenID = id; this.name = name; }
private XPathToken NextToken(XPathTokenID id, QueryCompileError error) { XPathToken token = this.NextToken(id); if (token == null) { this.ThrowError(error); } return token; }
private XPathToken NextToken(XPathTokenID id, QueryCompileError error) { XPathToken token = this.NextToken(id); if (token == null) { this.ThrowError(error); } return(token); }
internal XPathLexer(string xpath, bool resolveKeywords) { this.resolveKeywords = resolveKeywords; this.xpath = string.Copy(xpath); this.xpathLength = this.xpath.Length; this.tokenStart = 0; this.currChar = 0; this.ch = '\0'; this.previousID = XPathTokenID.Unknown; this.token = new XPathToken(); this.ConsumeWhitespace(); }
private XPathToken NextTokenClass(XPathTokenID tokenClass) { XPathToken token = this.NextToken(); if (token != null) { if ((token.TokenID & tokenClass) != XPathTokenID.Unknown) { return token; } this.readToken = token; } return null; }
private XPathToken NextToken(XPathTokenID id) { XPathToken token = this.NextToken(); if (token != null) { if (id == token.TokenID) { return token; } this.readToken = token; } return null; }
private XPathTokenID GetAxisName(XPathParser.QName qname) { if (qname.Prefix.Length != 0) { this.ThrowError(QueryCompileError.InvalidAxisSpecifier, qname.Prefix + ":" + qname.Name); } XPathTokenID namedType = this.GetNamedType(qname.Name); if (this.resolveKeywords && ((namedType & XPathTokenID.Axis) == XPathTokenID.Unknown)) { this.ThrowError(QueryCompileError.UnsupportedAxis, qname.Name); } return(namedType); }
private XPathTokenID GetNamedOperator(XPathParser.QName qname) { if (qname.Prefix.Length != 0) { this.ThrowError(QueryCompileError.InvalidOperatorName, qname.Prefix + ":" + qname.Name); } XPathTokenID namedType = this.GetNamedType(qname.Name); if (this.resolveKeywords && ((namedType & XPathTokenID.NamedOperator) == XPathTokenID.Unknown)) { this.ThrowError(QueryCompileError.UnsupportedOperator, this.previousID.ToString() + "->" + qname.Name); } return(namedType); }
private XPathTokenID GetNodeTypeOrFunction(XPathParser.QName qname) { XPathTokenID namedType = this.GetNamedType(qname.Name); if ((namedType & XPathTokenID.NodeType) == XPathTokenID.Unknown) { return(XPathTokenID.Function); } if (qname.Prefix.Length > 0) { this.ThrowError(QueryCompileError.InvalidNodeType, qname.Prefix + ":" + qname.Name); } return(namedType); }
private XPathToken NextTokenClass(XPathTokenID tokenClass) { XPathToken token = this.NextToken(); if (token != null) { if ((token.TokenID & tokenClass) != XPathTokenID.Unknown) { return(token); } this.readToken = token; } return(null); }
private XPathToken NextToken(XPathTokenID id) { XPathToken token = this.NextToken(); if (token != null) { if (id == token.TokenID) { return(token); } this.readToken = token; } return(null); }
XPathToken NextToken(XPathTokenID id) { XPathToken token = this.NextToken(); if (null != token) { if (id == token.TokenID) { return token; } this.readToken = token; } return null; }
XPathToken NextTokenClass(XPathTokenID tokenClass) { XPathToken token = this.NextToken(); if (null != token) { if (0 != (token.TokenID & tokenClass)) { return(token); } this.readToken = token; } return(null); }
private XPathTokenID GetNodeTypeOrFunction(XPathParser.QName qname) { XPathTokenID id = GetNamedType(qname.Name); // If it's not a node type, it's lexed as a function if ((id & XPathTokenID.NodeType) == 0) { id = XPathTokenID.Function; } else if (qname.Prefix.Length > 0) { // Node types don't have prefixes ThrowError(QueryCompileError.InvalidNodeType, qname.Prefix + ":" + qname.Name); } return(id); }
private XPathTokenID GetNamedOperator(XPathParser.QName qname) { // Named operators can't have prefixes if (qname.Prefix.Length != 0) { ThrowError(QueryCompileError.InvalidOperatorName, qname.Prefix + ":" + qname.Name); } // Make sure the type is 'NamedOperator' XPathTokenID id = GetNamedType(qname.Name); if (this.resolveKeywords && (id & XPathTokenID.NamedOperator) == 0) { ThrowError(QueryCompileError.UnsupportedOperator, this.previousID.ToString() + "->" + qname.Name); } return(id); }
private XPathTokenID GetAxisName(XPathParser.QName qname) { // Axes can't have prefixes if (qname.Prefix.Length != 0) { ThrowError(QueryCompileError.InvalidAxisSpecifier, qname.Prefix + ":" + qname.Name); } // Make sure the type is 'Axis' XPathTokenID id = GetNamedType(qname.Name); if (this.resolveKeywords && (id & XPathTokenID.Axis) == 0) { ThrowError(QueryCompileError.UnsupportedAxis, qname.Name); } return(id); }
private XPathExpr ParseMultiplicativeExpression() { XPathExpr left = this.ParseUnaryExpression(); if (left != null) { MathOperator none; do { none = MathOperator.None; XPathToken token = this.NextToken(); if (token != null) { XPathTokenID tokenID = token.TokenID; if (tokenID == XPathTokenID.Multiply) { none = MathOperator.Multiply; } else if (tokenID == XPathTokenID.Mod) { none = MathOperator.Mod; } else if (tokenID == XPathTokenID.Div) { none = MathOperator.Div; } else { this.PushToken(token); } if (none != MathOperator.None) { XPathExpr right = this.ParseUnaryExpression(); if (right == null) { this.ThrowError(QueryCompileError.InvalidExpression); } left = new XPathMathExpr(none, left, right); } } }while (none != MathOperator.None); } return(left); }
internal XPathLexer(string xpath, bool resolveKeywords) { this.resolveKeywords = resolveKeywords; // Hold on to a copy of the string so it can't be changed out from under us this.xpath = string.Copy(xpath); this.xpathLength = this.xpath.Length; // Start at the beginning this.tokenStart = 0; this.currChar = 0; this.ch = char.MinValue; this.previousID = XPathTokenID.Unknown; // We will not create new tokens, we will simply change the old one. // This will be the only XPathToken instance created by the lexer // The 'next token' data can be more quickly communicated to the parser if they both hold a reference to the data. this.token = new XPathToken(); // Strip leading whitespace ConsumeWhitespace(); }
internal XPathToken() { this.tokenID = XPathTokenID.Unknown; }
private void TokenizeQName() { while (XPathCharTypes.IsNCName(this.PeekChar())) { this.AdvanceChar(); } string prefix = this.CurrentSubstring(); XPathTokenID unknown = XPathTokenID.Unknown; XPathParser.QName qname = new XPathParser.QName("", ""); if ((this.PeekChar() == ':') && (this.PeekChar(2) != ':')) { this.AdvanceChar(); this.ConsumeToken(); this.AdvanceChar(); if (XPathCharTypes.IsNCNameStart(this.ch)) { while (XPathCharTypes.IsNCName(this.PeekChar())) { this.AdvanceChar(); } unknown = XPathTokenID.NameTest; qname = new XPathParser.QName(prefix, this.CurrentSubstring()); } else if (this.ch == '*') { unknown = XPathTokenID.NameWildcard; qname = new XPathParser.QName(prefix, QueryDataModel.Wildcard); } else { this.ThrowError(QueryCompileError.InvalidNCName, (this.ch == '\0') ? "" : this.CurrentSubstring()); } } else { unknown = XPathTokenID.NameTest; qname = new XPathParser.QName(string.Empty, prefix); } this.ConsumeWhitespace(); if (this.IsSpecialPrev()) { this.token.Set(this.GetNamedOperator(qname)); } else if (qname.Prefix.Length == 0) { if (this.PeekChar() == '(') { unknown = this.GetNodeTypeOrFunction(qname); if (unknown != XPathTokenID.Function) { this.token.Set(unknown); } else { this.token.Set(unknown, qname); } } else if ((this.PeekChar() == ':') && (this.PeekChar(2) == ':')) { this.token.Set(this.GetAxisName(qname)); } else { this.token.Set(unknown, qname); } } else { if (this.PeekChar() == '(') { unknown = XPathTokenID.Function; } this.token.Set(unknown, qname); } }
internal void Set(XPathTokenID id) { this.Clear(); this.tokenID = id; }
internal bool MoveNext() { this.previousID = this.token.TokenID; if (!this.AdvanceChar()) { return(false); } if (XPathCharTypes.IsNCNameStart(this.ch)) { this.TokenizeQName(); } else if (XPathCharTypes.IsDigit(this.ch)) { this.TokenizeNumber(); } else { switch (this.ch) { case '!': if (this.PeekChar() != '=') { this.ThrowError(QueryCompileError.UnsupportedOperator, this.CurrentSubstring()); } else { this.AdvanceChar(); this.token.Set(XPathTokenID.Neq); } goto Label_03FB; case '"': this.TokenizeLiteral('"'); goto Label_03FB; case '$': { XPathParser.QName qName = this.GetQName(); if ((qName.Prefix.Length == 0) && (qName.Name.Length == 0)) { this.AdvanceChar(); this.ThrowError(QueryCompileError.InvalidVariable, (this.ch == '\0') ? string.Empty : this.CurrentSubstring()); } this.token.Set(XPathTokenID.Variable, qName); goto Label_03FB; } case '\'': this.TokenizeLiteral('\''); goto Label_03FB; case '(': this.token.Set(XPathTokenID.LParen); goto Label_03FB; case ')': this.token.Set(XPathTokenID.RParen); goto Label_03FB; case '*': if (!this.IsSpecialPrev()) { this.token.Set(XPathTokenID.Wildcard, new XPathParser.QName(string.Empty, QueryDataModel.Wildcard)); } else { this.token.Set(XPathTokenID.Multiply); } goto Label_03FB; case '+': this.token.Set(XPathTokenID.Plus); goto Label_03FB; case ',': this.token.Set(XPathTokenID.Comma); goto Label_03FB; case '-': this.token.Set(XPathTokenID.Minus); goto Label_03FB; case '.': if (this.PeekChar() != '.') { if (XPathCharTypes.IsDigit(this.PeekChar())) { this.TokenizeNumber(); } else { this.token.Set(XPathTokenID.Period); } } else { this.AdvanceChar(); this.token.Set(XPathTokenID.DblPeriod); } goto Label_03FB; case '/': if (this.PeekChar() != '/') { this.token.Set(XPathTokenID.Slash); } else { this.AdvanceChar(); this.token.Set(XPathTokenID.DblSlash); } goto Label_03FB; case ':': if (this.PeekChar() != ':') { this.ThrowError(QueryCompileError.UnexpectedToken, this.CurrentSubstring()); } else { this.AdvanceChar(); this.token.Set(XPathTokenID.DblColon); } goto Label_03FB; case '<': if (this.PeekChar() != '=') { this.token.Set(XPathTokenID.Lt); } else { this.AdvanceChar(); this.token.Set(XPathTokenID.Lte); } goto Label_03FB; case '=': this.token.Set(XPathTokenID.Eq); goto Label_03FB; case '>': if (this.PeekChar() != '=') { this.token.Set(XPathTokenID.Gt); } else { this.AdvanceChar(); this.token.Set(XPathTokenID.Gte); } goto Label_03FB; case '@': this.token.Set(XPathTokenID.AtSign); goto Label_03FB; case '[': this.token.Set(XPathTokenID.LBracket); goto Label_03FB; case ']': this.token.Set(XPathTokenID.RBracket); goto Label_03FB; case '|': this.token.Set(XPathTokenID.Pipe); goto Label_03FB; } this.token.Set(XPathTokenID.Unknown); } Label_03FB: this.ConsumeWhitespace(); return(true); }
internal void Set(XPathTokenID id, double number) { this.Set(id); this.number = number; }
internal void Set(XPathTokenID id, string name) { this.Clear(); this.tokenID = id; this.name = name; }
internal void Set(XPathTokenID id, XPathParser.QName qname) { this.Set(id, qname.Name); this.prefix = qname.Prefix; }
// Move to the next token // This updates the values in the token instance and returns true if successful. internal bool MoveNext() { // Hold onto the ID of the last token. // It will be needed by some of the special cases. this.previousID = this.token.TokenID; // If there are no more characters, we can't get another token. if (!AdvanceChar()) { return false; } if (XPathCharTypes.IsNCNameStart(this.ch)) { // Extract a QName if we've got the start of an NCName TokenizeQName(); } else if (XPathCharTypes.IsDigit(this.ch)) { // Extract a number TokenizeNumber(); } else { // Everything else is a single/double character token, or a variable. switch (this.ch) { case '(': token.Set(XPathTokenID.LParen); break; case ')': token.Set(XPathTokenID.RParen); break; case '[': token.Set(XPathTokenID.LBracket); break; case ']': token.Set(XPathTokenID.RBracket); break; case '.': // Watch for a double period if (PeekChar() == '.') { AdvanceChar(); token.Set(XPathTokenID.DblPeriod); } else { // Check if the period is the start of a number if (XPathCharTypes.IsDigit(PeekChar())) { TokenizeNumber(); } else { token.Set(XPathTokenID.Period); } } break; case '@': token.Set(XPathTokenID.AtSign); break; case ',': token.Set(XPathTokenID.Comma); break; case ':': // Only a double colon is permitted. // The single colon part of the QName is consumed in TokenizeQName if it is valid if (PeekChar() == ':') { AdvanceChar(); token.Set(XPathTokenID.DblColon); } else { ThrowError(QueryCompileError.UnexpectedToken, CurrentSubstring()); } break; case '/': // Check for a double slash if (PeekChar() == '/') { AdvanceChar(); token.Set(XPathTokenID.DblSlash); } else { token.Set(XPathTokenID.Slash); } break; case '|': token.Set(XPathTokenID.Pipe); break; case '+': token.Set(XPathTokenID.Plus); break; case '-': token.Set(XPathTokenID.Minus); break; case '=': token.Set(XPathTokenID.Eq); break; case '!': // This can only be the start of a '!=' // 'not' is a negation in XPath if (PeekChar() == '=') { AdvanceChar(); token.Set(XPathTokenID.Neq); } else { ThrowError(QueryCompileError.UnsupportedOperator, CurrentSubstring()); } break; case '<': // Watch for '<=' if (PeekChar() == '=') { AdvanceChar(); token.Set(XPathTokenID.Lte); } else { token.Set(XPathTokenID.Lt); } break; case '>': // Watch for '>=' if (PeekChar() == '=') { AdvanceChar(); token.Set(XPathTokenID.Gte); } else { token.Set(XPathTokenID.Gt); } break; case '*': // Check if we're supposed to parse a '*' as a multiply if (IsSpecialPrev()) { token.Set(XPathTokenID.Multiply); } else { token.Set(XPathTokenID.Wildcard, new XPathParser.QName(string.Empty, QueryDataModel.Wildcard)); } break; case '$': // Make sure '$' was followed by something that counts as a variable name XPathParser.QName qname = GetQName(); if (qname.Prefix.Length == 0 && qname.Name.Length == 0) { AdvanceChar(); ThrowError(QueryCompileError.InvalidVariable, this.ch == char.MinValue ? string.Empty : CurrentSubstring()); } token.Set(XPathTokenID.Variable, qname); break; case '\"': TokenizeLiteral('\"'); break; case '\'': TokenizeLiteral('\''); break; default: // Unrecognized character token.Set(XPathTokenID.Unknown); break; } } // Whitespace can mark the end of a token, but is not part of the XPath syntax ConsumeWhitespace(); return true; }
internal bool MoveNext() { this.previousID = this.token.TokenID; if (!this.AdvanceChar()) { return false; } if (XPathCharTypes.IsNCNameStart(this.ch)) { this.TokenizeQName(); } else if (XPathCharTypes.IsDigit(this.ch)) { this.TokenizeNumber(); } else { switch (this.ch) { case '!': if (this.PeekChar() != '=') { this.ThrowError(QueryCompileError.UnsupportedOperator, this.CurrentSubstring()); } else { this.AdvanceChar(); this.token.Set(XPathTokenID.Neq); } goto Label_03FB; case '"': this.TokenizeLiteral('"'); goto Label_03FB; case '$': { XPathParser.QName qName = this.GetQName(); if ((qName.Prefix.Length == 0) && (qName.Name.Length == 0)) { this.AdvanceChar(); this.ThrowError(QueryCompileError.InvalidVariable, (this.ch == '\0') ? string.Empty : this.CurrentSubstring()); } this.token.Set(XPathTokenID.Variable, qName); goto Label_03FB; } case '\'': this.TokenizeLiteral('\''); goto Label_03FB; case '(': this.token.Set(XPathTokenID.LParen); goto Label_03FB; case ')': this.token.Set(XPathTokenID.RParen); goto Label_03FB; case '*': if (!this.IsSpecialPrev()) { this.token.Set(XPathTokenID.Wildcard, new XPathParser.QName(string.Empty, QueryDataModel.Wildcard)); } else { this.token.Set(XPathTokenID.Multiply); } goto Label_03FB; case '+': this.token.Set(XPathTokenID.Plus); goto Label_03FB; case ',': this.token.Set(XPathTokenID.Comma); goto Label_03FB; case '-': this.token.Set(XPathTokenID.Minus); goto Label_03FB; case '.': if (this.PeekChar() != '.') { if (XPathCharTypes.IsDigit(this.PeekChar())) { this.TokenizeNumber(); } else { this.token.Set(XPathTokenID.Period); } } else { this.AdvanceChar(); this.token.Set(XPathTokenID.DblPeriod); } goto Label_03FB; case '/': if (this.PeekChar() != '/') { this.token.Set(XPathTokenID.Slash); } else { this.AdvanceChar(); this.token.Set(XPathTokenID.DblSlash); } goto Label_03FB; case ':': if (this.PeekChar() != ':') { this.ThrowError(QueryCompileError.UnexpectedToken, this.CurrentSubstring()); } else { this.AdvanceChar(); this.token.Set(XPathTokenID.DblColon); } goto Label_03FB; case '<': if (this.PeekChar() != '=') { this.token.Set(XPathTokenID.Lt); } else { this.AdvanceChar(); this.token.Set(XPathTokenID.Lte); } goto Label_03FB; case '=': this.token.Set(XPathTokenID.Eq); goto Label_03FB; case '>': if (this.PeekChar() != '=') { this.token.Set(XPathTokenID.Gt); } else { this.AdvanceChar(); this.token.Set(XPathTokenID.Gte); } goto Label_03FB; case '@': this.token.Set(XPathTokenID.AtSign); goto Label_03FB; case '[': this.token.Set(XPathTokenID.LBracket); goto Label_03FB; case ']': this.token.Set(XPathTokenID.RBracket); goto Label_03FB; case '|': this.token.Set(XPathTokenID.Pipe); goto Label_03FB; } this.token.Set(XPathTokenID.Unknown); } Label_03FB: this.ConsumeWhitespace(); return true; }
// Move to the next token // This updates the values in the token instance and returns true if successful. internal bool MoveNext() { // Hold onto the ID of the last token. // It will be needed by some of the special cases. this.previousID = this.token.TokenID; // If there are no more characters, we can't get another token. if (!AdvanceChar()) { return(false); } if (XPathCharTypes.IsNCNameStart(this.ch)) { // Extract a QName if we've got the start of an NCName TokenizeQName(); } else if (XPathCharTypes.IsDigit(this.ch)) { // Extract a number TokenizeNumber(); } else { // Everything else is a single/double character token, or a variable. switch (this.ch) { case '(': token.Set(XPathTokenID.LParen); break; case ')': token.Set(XPathTokenID.RParen); break; case '[': token.Set(XPathTokenID.LBracket); break; case ']': token.Set(XPathTokenID.RBracket); break; case '.': // Watch for a double period if (PeekChar() == '.') { AdvanceChar(); token.Set(XPathTokenID.DblPeriod); } else { // Check if the period is the start of a number if (XPathCharTypes.IsDigit(PeekChar())) { TokenizeNumber(); } else { token.Set(XPathTokenID.Period); } } break; case '@': token.Set(XPathTokenID.AtSign); break; case ',': token.Set(XPathTokenID.Comma); break; case ':': // Only a double colon is permitted. // The single colon part of the QName is consumed in TokenizeQName if it is valid if (PeekChar() == ':') { AdvanceChar(); token.Set(XPathTokenID.DblColon); } else { ThrowError(QueryCompileError.UnexpectedToken, CurrentSubstring()); } break; case '/': // Check for a double slash if (PeekChar() == '/') { AdvanceChar(); token.Set(XPathTokenID.DblSlash); } else { token.Set(XPathTokenID.Slash); } break; case '|': token.Set(XPathTokenID.Pipe); break; case '+': token.Set(XPathTokenID.Plus); break; case '-': token.Set(XPathTokenID.Minus); break; case '=': token.Set(XPathTokenID.Eq); break; case '!': // This can only be the start of a '!=' // 'not' is a negation in XPath if (PeekChar() == '=') { AdvanceChar(); token.Set(XPathTokenID.Neq); } else { ThrowError(QueryCompileError.UnsupportedOperator, CurrentSubstring()); } break; case '<': // Watch for '<=' if (PeekChar() == '=') { AdvanceChar(); token.Set(XPathTokenID.Lte); } else { token.Set(XPathTokenID.Lt); } break; case '>': // Watch for '>=' if (PeekChar() == '=') { AdvanceChar(); token.Set(XPathTokenID.Gte); } else { token.Set(XPathTokenID.Gt); } break; case '*': // Check if we're supposed to parse a '*' as a multiply if (IsSpecialPrev()) { token.Set(XPathTokenID.Multiply); } else { token.Set(XPathTokenID.Wildcard, new XPathParser.QName(string.Empty, QueryDataModel.Wildcard)); } break; case '$': // Make sure '$' was followed by something that counts as a variable name XPathParser.QName qname = GetQName(); if (qname.Prefix.Length == 0 && qname.Name.Length == 0) { AdvanceChar(); ThrowError(QueryCompileError.InvalidVariable, this.ch == char.MinValue ? string.Empty : CurrentSubstring()); } token.Set(XPathTokenID.Variable, qname); break; case '\"': TokenizeLiteral('\"'); break; case '\'': TokenizeLiteral('\''); break; default: // Unrecognized character token.Set(XPathTokenID.Unknown); break; } } // Whitespace can mark the end of a token, but is not part of the XPath syntax ConsumeWhitespace(); return(true); }
private void TokenizeQName() { for (; XPathCharTypes.IsNCName(PeekChar()); AdvanceChar()) { ; } string name1 = this.CurrentSubstring(); XPathTokenID id = XPathTokenID.Unknown; XPathParser.QName qname = new XPathParser.QName("", ""); if (PeekChar() == ':' && PeekChar(2) != ':') { AdvanceChar(); ConsumeToken(); AdvanceChar(); if (XPathCharTypes.IsNCNameStart(this.ch)) { // It's a full QName for (; XPathCharTypes.IsNCName(PeekChar()); AdvanceChar()) { ; } id = XPathTokenID.NameTest; qname = new XPathParser.QName(name1, this.CurrentSubstring()); } else if (this.ch == '*') { // We've got a wildcard id = XPathTokenID.NameWildcard; qname = new XPathParser.QName(name1, QueryDataModel.Wildcard); } else { ThrowError(QueryCompileError.InvalidNCName, this.ch == char.MinValue ? "" : CurrentSubstring()); } } else { // It's a name test without a prefix id = XPathTokenID.NameTest; qname = new XPathParser.QName(string.Empty, name1); } // Handle special cases ConsumeWhitespace(); if (IsSpecialPrev()) { // If we're in the the first special case of the lexer, a qname MUST // be a NamedOperator token.Set(GetNamedOperator(qname)); return; } else if (qname.Prefix.Length == 0) { if (this.PeekChar() == '(') { // An NCName followed by a '(' MUST be eiter a node type or function name id = GetNodeTypeOrFunction(qname); if (id != XPathTokenID.Function) { token.Set(id); } else { token.Set(id, qname); } } else if (this.PeekChar() == ':' && this.PeekChar(2) == ':') { // An NCName followed by a '::' MUST be an axis token.Set(GetAxisName(qname)); } else { token.Set(id, qname); } } else { if (this.PeekChar() == '(') { id = XPathTokenID.Function; } token.Set(id, qname); } }
XPathToken NextTokenClass(XPathTokenID tokenClass) { XPathToken token = this.NextToken(); if (null != token) { if (0 != (token.TokenID & tokenClass)) { return token; } this.readToken = token; } return null; }