Search in sources :

Example 1 with Evaluable

use of com.google.refine.expr.Evaluable in project OpenRefine by OpenRefine.

the class Parser method parseExpressionList.

/**
     *  <expression-list> := <empty>
     *                     | <expression> ( "," <expression> )*
     *
     */
protected List<Evaluable> parseExpressionList(String closingDelimiter) throws ParsingException {
    List<Evaluable> l = new LinkedList<Evaluable>();
    if (_token != null && (_token.type != TokenType.Delimiter || !_token.text.equals(closingDelimiter))) {
        while (_token != null) {
            Evaluable eval = parseExpression();
            l.add(eval);
            if (_token != null && _token.type == TokenType.Delimiter && _token.text.equals(",")) {
                // swallow comma, loop back for more
                next(true);
            } else {
                break;
            }
        }
    }
    if (_token != null && _token.type == TokenType.Delimiter && _token.text.equals(closingDelimiter)) {
        // swallow closing delimiter
        next(false);
    } else {
        throw makeException("Missing " + closingDelimiter);
    }
    return l;
}
Also used : Evaluable(com.google.refine.expr.Evaluable) LinkedList(java.util.LinkedList)

Example 2 with Evaluable

use of com.google.refine.expr.Evaluable in project OpenRefine by OpenRefine.

the class Parser method parseSubExpression.

/**
     *  <sub-expression> := <term>
     *                    | <sub-expression> [ "+" "-" ] <term>
     */
protected Evaluable parseSubExpression() throws ParsingException {
    Evaluable sub = parseTerm();
    while (_token != null && _token.type == TokenType.Operator && "+-".indexOf(_token.text) >= 0) {
        String op = _token.text;
        next(true);
        Evaluable sub2 = parseTerm();
        sub = new OperatorCallExpr(new Evaluable[] { sub, sub2 }, op);
    }
    return sub;
}
Also used : OperatorCallExpr(com.google.refine.grel.ast.OperatorCallExpr) Evaluable(com.google.refine.expr.Evaluable)

Example 3 with Evaluable

use of com.google.refine.expr.Evaluable in project OpenRefine by OpenRefine.

the class Parser method parseFactor.

/**
     *  <term> := <term-start> ( <path-segment> )*
     *  <term-start> :=
     *      <string> | <number> | - <number> | <regex> | <identifier> |
     *      <identifier> ( <expression-list> )
     *
     *  <path-segment> := "[" <expression-list> "]"
     *                  | "." <identifier>
     *                  | "." <identifier> "(" <expression-list> ")"
     *
     */
protected Evaluable parseFactor() throws ParsingException {
    if (_token == null) {
        throw makeException("Expecting something more at end of expression");
    }
    Evaluable eval = null;
    if (_token.type == TokenType.String) {
        eval = new LiteralExpr(_token.text);
        next(false);
    } else if (_token.type == TokenType.Regex) {
        RegexToken t = (RegexToken) _token;
        try {
            Pattern pattern = Pattern.compile(_token.text, t.caseInsensitive ? Pattern.CASE_INSENSITIVE : 0);
            eval = new LiteralExpr(pattern);
            next(false);
        } catch (Exception e) {
            throw makeException("Bad regular expression (" + e.getMessage() + ")");
        }
    } else if (_token.type == TokenType.Number) {
        eval = new LiteralExpr(((NumberToken) _token).value);
        next(false);
    } else if (_token.type == TokenType.Operator && _token.text.equals("-")) {
        // unary minus?
        next(true);
        if (_token != null && _token.type == TokenType.Number) {
            Number n = ((NumberToken) _token).value;
            eval = new LiteralExpr(n instanceof Long ? -n.longValue() : -n.doubleValue());
            next(false);
        } else {
            throw makeException("Bad negative number");
        }
    } else if (_token.type == TokenType.Identifier) {
        String text = _token.text;
        next(false);
        if (_token == null || _token.type != TokenType.Delimiter || !_token.text.equals("(")) {
            eval = "null".equals(text) ? new LiteralExpr(null) : new VariableExpr(text);
        } else if ("PI".equals(text)) {
            eval = new LiteralExpr(Math.PI);
            next(false);
        } else {
            Function f = ControlFunctionRegistry.getFunction(text);
            Control c = ControlFunctionRegistry.getControl(text);
            if (f == null && c == null) {
                throw makeException("Unknown function or control named " + text);
            }
            // swallow (
            next(true);
            List<Evaluable> args = parseExpressionList(")");
            if (c != null) {
                Evaluable[] argsA = makeArray(args);
                String errorMessage = c.checkArguments(argsA);
                if (errorMessage != null) {
                    throw makeException(errorMessage);
                }
                eval = new ControlCallExpr(argsA, c);
            } else {
                eval = new FunctionCallExpr(makeArray(args), f);
            }
        }
    } else if (_token.type == TokenType.Delimiter && _token.text.equals("(")) {
        next(true);
        eval = parseExpression();
        if (_token != null && _token.type == TokenType.Delimiter && _token.text.equals(")")) {
            next(false);
        } else {
            throw makeException("Missing )");
        }
    } else if (_token.type == TokenType.Delimiter && _token.text.equals("[")) {
        // [ ... ] array
        // swallow [
        next(true);
        List<Evaluable> args = parseExpressionList("]");
        eval = new FunctionCallExpr(makeArray(args), new ArgsToArray());
    } else {
        throw makeException("Missing number, string, identifier, regex, or parenthesized expression");
    }
    while (_token != null) {
        if (_token.type == TokenType.Operator && _token.text.equals(".")) {
            // swallow .
            next(false);
            if (_token == null || _token.type != TokenType.Identifier) {
                throw makeException("Missing function name");
            }
            String identifier = _token.text;
            next(false);
            if (_token != null && _token.type == TokenType.Delimiter && _token.text.equals("(")) {
                // swallow (
                next(true);
                Function f = ControlFunctionRegistry.getFunction(identifier);
                if (f == null) {
                    throw makeException("Unknown function " + identifier);
                }
                List<Evaluable> args = parseExpressionList(")");
                args.add(0, eval);
                eval = new FunctionCallExpr(makeArray(args), f);
            } else {
                eval = new FieldAccessorExpr(eval, identifier);
            }
        } else if (_token.type == TokenType.Delimiter && _token.text.equals("[")) {
            // swallow [
            next(true);
            List<Evaluable> args = parseExpressionList("]");
            args.add(0, eval);
            eval = new FunctionCallExpr(makeArray(args), ControlFunctionRegistry.getFunction("get"));
        } else {
            break;
        }
    }
    return eval;
}
Also used : Pattern(java.util.regex.Pattern) ControlCallExpr(com.google.refine.grel.ast.ControlCallExpr) ParsingException(com.google.refine.expr.ParsingException) Evaluable(com.google.refine.expr.Evaluable) FunctionCallExpr(com.google.refine.grel.ast.FunctionCallExpr) ArgsToArray(com.google.refine.expr.functions.arrays.ArgsToArray) NumberToken(com.google.refine.grel.Scanner.NumberToken) LiteralExpr(com.google.refine.grel.ast.LiteralExpr) FieldAccessorExpr(com.google.refine.grel.ast.FieldAccessorExpr) VariableExpr(com.google.refine.grel.ast.VariableExpr) List(java.util.List) LinkedList(java.util.LinkedList) RegexToken(com.google.refine.grel.Scanner.RegexToken)

Example 4 with Evaluable

use of com.google.refine.expr.Evaluable in project OpenRefine by OpenRefine.

the class Parser method parseExpression.

/**
     *  <expression> := <sub-expression>
     *                | <expression> [ "<" "<=" ">" ">=" "==" "!=" ] <sub-expression>
     */
protected Evaluable parseExpression() throws ParsingException {
    Evaluable sub = parseSubExpression();
    while (_token != null && _token.type == TokenType.Operator && ">=<==!=".indexOf(_token.text) >= 0) {
        String op = _token.text;
        next(true);
        Evaluable sub2 = parseSubExpression();
        sub = new OperatorCallExpr(new Evaluable[] { sub, sub2 }, op);
    }
    return sub;
}
Also used : OperatorCallExpr(com.google.refine.grel.ast.OperatorCallExpr) Evaluable(com.google.refine.expr.Evaluable)

Example 5 with Evaluable

use of com.google.refine.expr.Evaluable in project OpenRefine by OpenRefine.

the class FacetCount method call.

@Override
public Object call(Properties bindings, Object[] args) {
    if (args.length == 3 && args[1] instanceof String && args[2] instanceof String) {
        // choice value to look up
        Object choiceValue = args[0];
        String facetExpression = (String) args[1];
        String columnName = (String) args[2];
        Project project = (Project) bindings.get("project");
        Column column = project.columnModel.getColumnByName(columnName);
        if (column == null) {
            return new EvalError("No such column named " + columnName);
        }
        String key = "nominal-bin:" + facetExpression;
        ExpressionNominalValueGrouper grouper = (ExpressionNominalValueGrouper) column.getPrecompute(key);
        if (grouper == null) {
            try {
                Evaluable eval = MetaParser.parse(facetExpression);
                Engine engine = new Engine(project);
                grouper = new ExpressionNominalValueGrouper(eval, columnName, column.getCellIndex());
                engine.getAllRows().accept(project, grouper);
                column.setPrecompute(key, grouper);
            } catch (ParsingException e) {
                return new EvalError("Error parsing facet expression " + facetExpression);
            }
        }
        return grouper.getChoiceValueCountMultiple(choiceValue);
    }
    return new EvalError(ControlFunctionRegistry.getFunctionName(this) + " expects a choice value, an expression as a string, and a column name");
}
Also used : Project(com.google.refine.model.Project) Evaluable(com.google.refine.expr.Evaluable) Column(com.google.refine.model.Column) ParsingException(com.google.refine.expr.ParsingException) EvalError(com.google.refine.expr.EvalError) Engine(com.google.refine.browsing.Engine) ExpressionNominalValueGrouper(com.google.refine.browsing.util.ExpressionNominalValueGrouper)

Aggregations

Evaluable (com.google.refine.expr.Evaluable)18 ParsingException (com.google.refine.expr.ParsingException)6 Project (com.google.refine.model.Project)6 Cell (com.google.refine.model.Cell)5 Column (com.google.refine.model.Column)5 Row (com.google.refine.model.Row)5 Properties (java.util.Properties)5 JSONObject (org.json.JSONObject)4 RowVisitor (com.google.refine.browsing.RowVisitor)3 EvalError (com.google.refine.expr.EvalError)3 WrappedCell (com.google.refine.expr.WrappedCell)3 OperatorCallExpr (com.google.refine.grel.ast.OperatorCallExpr)3 Serializable (java.io.Serializable)3 Engine (com.google.refine.browsing.Engine)2 NumericBinIndex (com.google.refine.browsing.util.NumericBinIndex)2 VariableExpr (com.google.refine.grel.ast.VariableExpr)2 CellChange (com.google.refine.model.changes.CellChange)2 LinkedList (java.util.LinkedList)2 Test (org.testng.annotations.Test)2 FilteredRows (com.google.refine.browsing.FilteredRows)1