//>> OrExpr ::= ( OrExpr 'or' )? AndExpr private AstNode ParseOrExpr(AstNode qyInput) { AstNode opnd = ParseAndExpr(qyInput); do { if (! TestOp("or")) { return opnd; } NextLex(); opnd = new Operator(Operator.Op.OR, opnd, ParseAndExpr(qyInput)); }while (true); }
//>> AndExpr ::= ( AndExpr 'and' )? EqualityExpr private AstNode ParseAndExpr(AstNode qyInput) { AstNode opnd = ParseEqualityExpr(qyInput); do { if (! TestOp("and")) { return opnd; } NextLex(); opnd = new Operator(Operator.Op.AND, opnd, ParseEqualityExpr(qyInput)); }while (true); }
internal NumericExpr(Operator.Op op, IQuery opnd1, IQuery opnd2) { if ( opnd1 is VariableQuery || opnd1 is XsltFunction || opnd1.ReturnType() != XPathResultType.Number) _opnd1= new NumberFunctions(opnd1); else _opnd1 = opnd1; if (opnd2 != null && (opnd2 is VariableQuery || opnd2 is XsltFunction || opnd2.ReturnType() != XPathResultType.Number)) _opnd2= new NumberFunctions(opnd2); else _opnd2 = opnd2; _op= op; }
static bool compareStringString1(IQuery opnd1, IQuery opnd2, XPathNavigator qyContext, Operator.Op op, XPathNodeIterator iterator) { String n1 = XmlConvert.ToXPathString(opnd1.getValue(qyContext, iterator)); String n2 = XmlConvert.ToXPathString(opnd2.getValue(qyContext, iterator)); switch (op) { case Operator.Op.EQ : return( n1 == n2 ) ; case Operator.Op.NE : return( n1 != n2 ) ; } return false; }
//>> EqualityOp ::= '=' | '!=' //>> EqualityExpr ::= ( EqualityExpr EqualityOp )? RelationalExpr private AstNode ParseEqualityExpr(AstNode qyInput) { AstNode opnd = ParseRelationalExpr(qyInput); do { Operator.Op op = ( this.scanner.Kind == XPathScanner.LexKind.Eq ? Operator.Op.EQ : this.scanner.Kind == XPathScanner.LexKind.Ne ? Operator.Op.NE : /*default :*/ Operator.Op.INVALID ); if (op == Operator.Op.INVALID) { return opnd; } NextLex(); opnd = new Operator(op, opnd, ParseRelationalExpr(qyInput)); }while (true); }
//>> UnionExpr ::= ( UnionExpr '|' )? PathExpr private AstNode ParseUnionExpr(AstNode qyInput) { AstNode opnd = ParsePathExpr(qyInput); do { if (this.scanner.Kind != XPathScanner.LexKind.Union) { return opnd; } NextLex(); AstNode opnd2 = ParsePathExpr(qyInput); CheckNodeSet(opnd.ReturnType); CheckNodeSet(opnd2.ReturnType); opnd = new Operator(Operator.Op.UNION, opnd, opnd2); }while (true); }
//>> AdditiveOp ::= '+' | '-' //>> AdditiveExpr ::= ( AdditiveExpr AdditiveOp )? MultiplicativeExpr private AstNode ParseAdditiveExpr(AstNode qyInput) { AstNode opnd = ParseMultiplicativeExpr(qyInput); do { Operator.Op op = ( this.scanner.Kind == XPathScanner.LexKind.Plus ? Operator.Op.PLUS : this.scanner.Kind == XPathScanner.LexKind.Minus ? Operator.Op.MINUS : /*default :*/ Operator.Op.INVALID ); if (op == Operator.Op.INVALID) { return opnd; } NextLex(); opnd = new Operator(op, opnd, ParseMultiplicativeExpr(qyInput)); }while (true); }
static bool compareNumberNumber(IQuery opnd1, IQuery opnd2, XPathNavigator qyContext, Operator.Op op, XPathNodeIterator iterator) { double n1 = XmlConvert.ToXPathDouble(opnd1.getValue(qyContext, iterator)); double n2 = XmlConvert.ToXPathDouble(opnd2.getValue(qyContext, iterator)); switch (op) { case Operator.Op.LT : return( n1 < n2 ) ; case Operator.Op.GT : return( n1 > n2 ) ; case Operator.Op.LE : return( n1 <= n2 ) ; case Operator.Op.GE : return( n1 >= n2 ) ; case Operator.Op.EQ : return( n1 == n2 ) ; case Operator.Op.NE : return( n1 != n2 ) ; } return false; }
static bool compareStringQuery1(IQuery opnd1, IQuery opnd2, XPathNavigator qyContext, Operator.Op op , XPathNodeIterator iterator) { XPathNavigator val1; opnd2.setContext(qyContext.Clone()); String n2, n1 = XmlConvert.ToXPathString(opnd1.getValue(qyContext, iterator)); while (true) { val1 = opnd2.advance(); if (val1 != null) n2 = val1.Value; else return false; switch (op) { case Operator.Op.EQ : if (n1 == n2) return true ; break; case Operator.Op.NE : if (n1 != n2) return true ; break; } } }
static bool compareQueryString2(IQuery opnd1, IQuery opnd2, IQuery qyContext, Operator.Op op) { XPathNavigator val1; opnd1.setContext(qyContext.peekElement().Clone()); double n1, n2 = NumberFunctions.Number(XmlConvert.ToXPathString(opnd2.getValue(qyContext))); while (true) { val1 = opnd1.advance(); if (val1 != null) n1 = NumberFunctions.Number(val1.Value); else return false; switch (op) { case Operator.Op.LT :if (n1 < n2) return true; break; case Operator.Op.GT :if (n1 > n2) return true; break; case Operator.Op.LE :if (n1 <= n2) return true; break; case Operator.Op.GE :if (n1 >= n2) return true; break; case Operator.Op.EQ :if (n1 == n2) return true; break; case Operator.Op.NE :if (n1 != n2) return true; break; } } }
static bool compareQueryString1(IQuery opnd1, IQuery opnd2, XPathNavigator qyContext, Operator.Op op, XPathNodeIterator iterator) { XPathNavigator val1; opnd1.setContext(qyContext.Clone()); String n2 = XmlConvert.ToXPathString(opnd2.getValue(qyContext, iterator)); while ((val1 = opnd1.advance()) != null) { if (op == Operator.Op.EQ) { if (val1.Value == n2) return true; } else if (val1.Value != n2) return true; } return false; }
static bool compareQueryQuery2( IQuery opnd1, IQuery opnd2, IQuery qyContext, Operator.Op op) { XPathNavigator val1, val2; double n1,n2; opnd1.setContext(qyContext.peekElement().Clone()); opnd2.setContext(qyContext.peekElement().Clone()); while (true) { val1 = opnd1.advance(); if (val1 != null) n1 = NumberFunctions.Number(val1.Value); else return false; val2 = opnd2.advance(); if (val2 != null) n2 = NumberFunctions.Number(val2.Value); else return false; while (true) { switch (op) { case Operator.Op.LT : if (n1 < n2) return true; break; case Operator.Op.GT : if (n1 > n2) return true; break; case Operator.Op.LE : if (n1 <= n2) return true; break; case Operator.Op.GE : if (n1 >= n2) return true; break; case Operator.Op.EQ : if (n1 == n2) return true; break; case Operator.Op.NE : if (n1 != n2) return true; break; } val2 = opnd2.advance(); if (val2 != null) n2 = NumberFunctions.Number(val2.Value); else { opnd2.reset(); break; } } } }
static bool compareQueryQuery2( IQuery opnd1, IQuery opnd2, XPathNavigator qyContext, Operator.Op op, XPathNodeIterator iterator) { return compareQueryQuery2(opnd1, opnd2, new XPathSelfQuery(qyContext), op); }
static bool compareQueryQuery1( IQuery opnd1, IQuery opnd2, IQuery qyContext, Operator.Op op) { XPathNavigator val1, val2; String str1,str2; opnd1.setContext(qyContext.peekElement().Clone()); opnd2.setContext(qyContext.peekElement().Clone()); while (true) { val1 = opnd1.advance(); if (val1 != null) str1 = val1.Value; else return false; val2 = opnd2.advance(); if (val2 != null) str2 = val2.Value; else return false; while (true) { switch (op) { case Operator.Op.EQ : if (str1 == str2) return true; break; case Operator.Op.NE : if (str1 != str2) return true; break; } val2 = opnd2.advance(); if (val2 != null) str2 = val2.Value; else { opnd2.reset(); break; } } } }
internal LogicalExpr(Operator.Op op, IQuery opnd1, IQuery opnd2) { _opnd1= opnd1; _opnd2= opnd2; _op= op; }
static bool compareBoolString1(IQuery opnd1, IQuery opnd2, XPathNavigator qyContext, Operator.Op op, XPathNodeIterator iterator) { Boolean n1 = Convert.ToBoolean(opnd1.getValue(qyContext, iterator)); Boolean n2 = BooleanFunctions.toBoolean(XmlConvert.ToXPathString(opnd2.getValue(qyContext, iterator))); switch (op) { case Operator.Op.EQ : return( n1 == n2 ); case Operator.Op.NE : return( n1 != n2 ); } return false; }
static bool compareBoolString2(IQuery opnd1, IQuery opnd2, XPathNavigator qyContext, Operator.Op op, XPathNodeIterator iterator) { double n1 = NumberFunctions.Number(Convert.ToBoolean(opnd1.getValue(qyContext, iterator))); double n2 = NumberFunctions.Number(XmlConvert.ToXPathString(opnd2.getValue(qyContext, iterator))); switch (op) { case Operator.Op.LT : return( n1 < n2 ) ; case Operator.Op.GT : return( n1 > n2 ) ; case Operator.Op.LE : return( n1 <= n2 ) ; case Operator.Op.GE : return( n1 >= n2 ) ; } return false; }
static bool compareStringQuery2(IQuery opnd1, IQuery opnd2, XPathNavigator qyContext, Operator.Op op, XPathNodeIterator iterator) { XPathNavigator val1; opnd2.setContext(qyContext.Clone()); double n2, n1 = NumberFunctions.Number(XmlConvert.ToXPathString(opnd1.getValue(qyContext, iterator))); while (true) { val1 = opnd2.advance(); if (val1 != null) n2 = NumberFunctions.Number(val1.Value); else return false; switch (op) { case Operator.Op.LT :if (n1 < n2) return true ; break; case Operator.Op.GT :if (n1 > n2) return true ; break; case Operator.Op.LE :if (n1 <= n2) return true ; break; case Operator.Op.GE :if (n1 >= n2) return true ; break; case Operator.Op.EQ :if (n1 == n2) return true ; break; case Operator.Op.NE :if (n1 != n2) return true ; break; } } }
static bool compareNumberBool1(IQuery opnd1, IQuery opnd2, IQuery qyContext, Operator.Op op) { Boolean n1 = BooleanFunctions.toBoolean(XmlConvert.ToXPathDouble(opnd1.getValue(qyContext))); Boolean n2 = Convert.ToBoolean(opnd2.getValue(qyContext)); switch (op) { case Operator.Op.EQ : return( n1 == n2 ) ; case Operator.Op.NE : return( n1 != n2 ) ; } return false; }
static bool compareQueryBool1(IQuery opnd1, IQuery opnd2, IQuery qyContext, Operator.Op op) { XPathNavigator val1; opnd1.setContext(qyContext.peekElement().Clone()); Boolean n1 = false, n2 = Convert.ToBoolean(opnd2.getValue(qyContext)); val1 = opnd1.advance(); if (val1 != null) { n1 = true; } else { if (op == Operator.Op.EQ ) { return (n2 == n1); } return (n2 != n1); } switch (op) { case Operator.Op.EQ : return (n1 == n2) ; case Operator.Op.NE : return (n1 != n2) ; } return false; }
//>> RelationalOp ::= '<' | '>' | '<=' | '>=' //>> RelationalExpr ::= ( RelationalExpr RelationalOp )? AdditiveExpr private AstNode ParseRelationalExpr(AstNode qyInput) { AstNode opnd = ParseAdditiveExpr(qyInput); do { Operator.Op op = ( this.scanner.Kind == XPathScanner.LexKind.Lt ? Operator.Op.LT : this.scanner.Kind == XPathScanner.LexKind.Le ? Operator.Op.LE : this.scanner.Kind == XPathScanner.LexKind.Gt ? Operator.Op.GT : this.scanner.Kind == XPathScanner.LexKind.Ge ? Operator.Op.GE : /*default :*/ Operator.Op.INVALID ); if (op == Operator.Op.INVALID) { return opnd; } NextLex(); opnd = new Operator(op, opnd, ParseAdditiveExpr(qyInput)); }while (true); }
static bool compareQueryBool2(IQuery opnd1, IQuery opnd2, IQuery qyContext, Operator.Op op) { XPathNavigator val1; opnd1.setContext(qyContext.peekElement().Clone()); double n1, n2 = NumberFunctions.Number(Convert.ToBoolean(opnd2.getValue(qyContext))); val1 = opnd1.advance(); if (val1 != null) n1 = 1.0; else { n1 = 0; switch (op) { case Operator.Op.LT : return (n1 < n2) ; case Operator.Op.GT : return (n1 > n2) ; case Operator.Op.LE : return (n1 <= n2) ; case Operator.Op.GE : return (n1 >= n2) ; } } switch (op) { case Operator.Op.LT : return (n1 < n2) ; case Operator.Op.GT : return (n1 > n2) ; case Operator.Op.LE : return (n1 <= n2) ; case Operator.Op.GE : return (n1 >= n2) ; } return false; }
//>> MultiplicativeOp ::= '*' | 'div' | 'mod' //>> MultiplicativeExpr ::= ( MultiplicativeExpr MultiplicativeOp )? UnaryExpr private AstNode ParseMultiplicativeExpr(AstNode qyInput) { AstNode opnd = ParseUnaryExpr(qyInput); do { Operator.Op op = ( this.scanner.Kind == XPathScanner.LexKind.Star ? Operator.Op.MUL : TestOp("div") ? Operator.Op.DIV : TestOp("mod") ? Operator.Op.MOD : /*default :*/ Operator.Op.INVALID ); if (op == Operator.Op.INVALID) { return opnd; } NextLex(); opnd = new Operator(op, opnd, ParseUnaryExpr(qyInput)); }while (true); }
static bool compareBoolQuery1(IQuery opnd1, IQuery opnd2, XPathNavigator qyContext, Operator.Op op, XPathNodeIterator iterator) { XPathNavigator val1; opnd2.setContext(qyContext.Clone()); Boolean n2 = false, n1 = Convert.ToBoolean(opnd1.getValue(qyContext, iterator)); val1 = opnd2.advance(); if (val1 != null) n2 = true; else { if (op == Operator.Op.EQ ) { return (n2 == n1); } return (n2 != n1); } switch (op) { case Operator.Op.EQ : return (n1 == n2) ; case Operator.Op.NE : return (n1 != n2) ; } return false; }
// --------------- Pattern Parsing ---------------------- //>> Pattern ::= ( Pattern '|' )? LocationPathPattern private AstNode ParsePattern(AstNode qyInput) { AstNode opnd = ParseLocationPathPattern(qyInput); do { if (this.scanner.Kind != XPathScanner.LexKind.Union) { return opnd; } NextLex(); opnd = new Operator(Operator.Op.UNION, opnd, ParseLocationPathPattern(qyInput)); }while (true); }
static bool compareBoolQuery2(IQuery opnd1, IQuery opnd2, XPathNavigator qyContext, Operator.Op op, XPathNodeIterator iterator) { XPathNavigator val1; opnd2.setContext(qyContext.Clone()); double n2, n1 = NumberFunctions.Number(Convert.ToBoolean(opnd1.getValue(qyContext, iterator))); val1 = opnd2.advance(); if (val1 != null) n2 = 1.0; else { n2 = 0; switch (op) { case Operator.Op.LT : return (n1 < n2) ; case Operator.Op.GT : return (n1 > n2) ; case Operator.Op.LE : return (n1 <= n2) ; case Operator.Op.GE : return (n1 >= n2) ; } } switch (op) { case Operator.Op.LT : return (n1 < n2) ; case Operator.Op.GT : return (n1 > n2) ; case Operator.Op.LE : return (n1 <= n2) ; case Operator.Op.GE : return (n1 >= n2) ; } return false; }
static bool compareBoolBool1(IQuery opnd1, IQuery opnd2, IQuery qyContext, Operator.Op op) { Boolean n1 = Convert.ToBoolean(opnd1.getValue(qyContext)); Boolean n2 = Convert.ToBoolean(opnd2.getValue(qyContext)); switch (op) { case Operator.Op.EQ : return( n1 == n2 ) ; case Operator.Op.NE : return( n1 != n2 ) ; } return false; }
static bool compareBoolNumber2(IQuery opnd1, IQuery opnd2, IQuery qyContext, Operator.Op op) { double n1 = NumberFunctions.Number(Convert.ToBoolean(opnd1.getValue(qyContext))); double n2 = XmlConvert.ToXPathDouble(opnd2.getValue(qyContext)); switch (op) { case Operator.Op.LT : return( n1 < n2 ) ; case Operator.Op.GT : return( n1 > n2 ) ; case Operator.Op.LE : return( n1 <= n2 ) ; case Operator.Op.GE : return( n1 >= n2 ) ; } return false; }
private static void ComposeOperator(Operator node, StringBuilder expr) { AstNode op1 = node.Operand1; AstNode op2 = node.Operand2; string op = null; switch (node.OperatorType) { case Operator.Op.PLUS: op = s_Plus; break; case Operator.Op.MINUS: op = s_Minus; break; case Operator.Op.MUL: op = s_Star; break; case Operator.Op.MOD: op = s_Mod; break; case Operator.Op.DIV: op = s_Div; break; case Operator.Op.NEGATE: op = s_Negate; op2 = op1; op1 = null; break; case Operator.Op.LT: op = s_Lt; break; case Operator.Op.GT: op = s_Gt; break; case Operator.Op.LE: op = s_Le; break; case Operator.Op.GE: op = s_Ge; break; case Operator.Op.EQ: op = s_Eq; break; case Operator.Op.NE: op = s_Neq; break; case Operator.Op.OR: op = s_Or; break; case Operator.Op.AND: op = s_And; break; case Operator.Op.UNION: op = s_Union; break; case Operator.Op.INVALID: default: Debug.Fail("Unexpected Operator Type value"); break; } ComposeExpression(op1, expr); expr.Append(op); ComposeExpression(op2, expr); }
static bool compareNumberString(IQuery opnd1, IQuery opnd2, IQuery qyContext, Operator.Op op) { double n1 = XmlConvert.ToXPathDouble(opnd1.getValue(qyContext)); double n2 = NumberFunctions.Number(XmlConvert.ToXPathString(opnd2.getValue(qyContext))); switch (op) { case Operator.Op.LT : return( n1 < n2 ) ; case Operator.Op.GT : return( n1 > n2 ) ; case Operator.Op.LE : return( n1 <= n2 ) ; case Operator.Op.GE : return( n1 >= n2 ) ; case Operator.Op.EQ : return( n1 == n2 ) ; case Operator.Op.NE : return( n1 != n2 ) ; } return false; }