/*
* Copyright (C) 2009 JavaRosa
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.openrosa.client.jr.xpath.parser.ast;
import java.util.Vector;
import org.openrosa.client.jr.xpath.expr.XPathArithExpr;
import org.openrosa.client.jr.xpath.expr.XPathBinaryOpExpr;
import org.openrosa.client.jr.xpath.expr.XPathBoolExpr;
import org.openrosa.client.jr.xpath.expr.XPathCmpExpr;
import org.openrosa.client.jr.xpath.expr.XPathEqExpr;
import org.openrosa.client.jr.xpath.expr.XPathExpression;
import org.openrosa.client.jr.xpath.expr.XPathUnionExpr;
import org.openrosa.client.jr.xpath.parser.Parser;
import org.openrosa.client.jr.xpath.parser.Token;
import org.openrosa.client.jr.xpath.parser.XPathSyntaxException;
public class ASTNodeBinaryOp extends ASTNode {
public static final int ASSOC_LEFT = 1;
public static final int ASSOC_RIGHT = 2;
public int associativity;
public Vector exprs;
public Vector ops;
public ASTNodeBinaryOp () {
exprs = new Vector();
ops = new Vector();
}
public Vector getChildren() {
return exprs;
}
public XPathExpression build() throws XPathSyntaxException {
XPathExpression x;
if (associativity == ASSOC_LEFT) {
x = ((ASTNode)exprs.elementAt(0)).build();
for (int i = 1; i < exprs.size(); i++) {
x = getBinOpExpr(Parser.vectInt(ops, i - 1), x, ((ASTNode)exprs.elementAt(i)).build());
}
} else {
x = ((ASTNode)exprs.elementAt(exprs.size() - 1)).build();
for (int i = exprs.size() - 2; i >= 0; i--) {
x = getBinOpExpr(Parser.vectInt(ops, i), ((ASTNode)exprs.elementAt(i)).build(), x);
}
}
return x;
}
private XPathBinaryOpExpr getBinOpExpr (int op, XPathExpression a, XPathExpression b) throws XPathSyntaxException {
switch (op) {
case Token.OR: return new XPathBoolExpr(XPathBoolExpr.OR, a, b);
case Token.AND: return new XPathBoolExpr(XPathBoolExpr.AND, a, b);
case Token.EQ: return new XPathEqExpr(true, a, b);
case Token.NEQ: return new XPathEqExpr(false, a, b);
case Token.LT: return new XPathCmpExpr(XPathCmpExpr.LT, a, b);
case Token.LTE: return new XPathCmpExpr(XPathCmpExpr.LTE, a, b);
case Token.GT: return new XPathCmpExpr(XPathCmpExpr.GT, a, b);
case Token.GTE: return new XPathCmpExpr(XPathCmpExpr.GTE, a, b);
case Token.PLUS: return new XPathArithExpr(XPathArithExpr.ADD, a, b);
case Token.MINUS: return new XPathArithExpr(XPathArithExpr.SUBTRACT, a, b);
case Token.MULT: return new XPathArithExpr(XPathArithExpr.MULTIPLY, a, b);
case Token.DIV: return new XPathArithExpr(XPathArithExpr.DIVIDE, a, b);
case Token.MOD: return new XPathArithExpr(XPathArithExpr.MODULO, a, b);
case Token.UNION: return new XPathUnionExpr(a, b);
default: throw new XPathSyntaxException();
}
}
}