Search in sources :

Example 1 with VariableExpr

use of com.google.refine.grel.ast.VariableExpr 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 2 with VariableExpr

use of com.google.refine.grel.ast.VariableExpr in project OpenRefine by OpenRefine.

the class Filter method call.

@Override
public Object call(Properties bindings, Evaluable[] args) {
    Object o = args[0].evaluate(bindings);
    if (ExpressionUtils.isError(o)) {
        return o;
    } else if (!ExpressionUtils.isArrayOrCollection(o) && !(o instanceof JSONArray)) {
        return new EvalError("First argument is not an array");
    }
    String name = ((VariableExpr) args[1]).getName();
    Object oldValue = bindings.get(name);
    try {
        List<Object> results = null;
        if (o.getClass().isArray()) {
            Object[] values = (Object[]) o;
            results = new ArrayList<Object>(values.length);
            for (Object v : values) {
                if (v != null) {
                    bindings.put(name, v);
                } else {
                    bindings.remove(name);
                }
                Object r = args[2].evaluate(bindings);
                if (r instanceof Boolean && ((Boolean) r).booleanValue()) {
                    results.add(v);
                }
            }
        } else if (o instanceof JSONArray) {
            JSONArray a = (JSONArray) o;
            int l = a.length();
            results = new ArrayList<Object>(l);
            for (int i = 0; i < l; i++) {
                try {
                    Object v = a.get(i);
                    if (v != null) {
                        bindings.put(name, v);
                    } else {
                        bindings.remove(name);
                    }
                    Object r = args[2].evaluate(bindings);
                    if (r instanceof Boolean && ((Boolean) r).booleanValue()) {
                        results.add(v);
                    }
                } catch (JSONException e) {
                    results.add(new EvalError(e.getMessage()));
                }
            }
        } else {
            Collection<Object> collection = ExpressionUtils.toObjectCollection(o);
            results = new ArrayList<Object>(collection.size());
            for (Object v : collection) {
                if (v != null) {
                    bindings.put(name, v);
                } else {
                    bindings.remove(name);
                }
                Object r = args[2].evaluate(bindings);
                if (r instanceof Boolean && ((Boolean) r).booleanValue()) {
                    results.add(v);
                }
            }
        }
        return results.toArray();
    } finally {
        /*
             *  Restore the old value bound to the variable, if any.
             */
        if (oldValue != null) {
            bindings.put(name, oldValue);
        } else {
            bindings.remove(name);
        }
    }
}
Also used : JSONArray(org.json.JSONArray) ArrayList(java.util.ArrayList) JSONException(org.json.JSONException) Collection(java.util.Collection) EvalError(com.google.refine.expr.EvalError) VariableExpr(com.google.refine.grel.ast.VariableExpr)

Example 3 with VariableExpr

use of com.google.refine.grel.ast.VariableExpr in project OpenRefine by OpenRefine.

the class ForEach method call.

@Override
public Object call(Properties bindings, Evaluable[] args) {
    Object o = args[0].evaluate(bindings);
    if (ExpressionUtils.isError(o)) {
        return o;
    } else if (!ExpressionUtils.isArrayOrCollection(o) && !(o instanceof JSONArray)) {
        return new EvalError("First argument to forEach is not an array");
    }
    String name = ((VariableExpr) args[1]).getName();
    Object oldValue = bindings.get(name);
    try {
        List<Object> results = null;
        if (o.getClass().isArray()) {
            Object[] values = (Object[]) o;
            results = new ArrayList<Object>(values.length);
            for (Object v : values) {
                if (v != null) {
                    bindings.put(name, v);
                } else {
                    bindings.remove(name);
                }
                Object r = args[2].evaluate(bindings);
                results.add(r);
            }
        } else if (o instanceof JSONArray) {
            JSONArray a = (JSONArray) o;
            int l = a.length();
            results = new ArrayList<Object>(l);
            for (int i = 0; i < l; i++) {
                try {
                    Object v = a.get(i);
                    if (v != null) {
                        bindings.put(name, v);
                    } else {
                        bindings.remove(name);
                    }
                    Object r = args[2].evaluate(bindings);
                    results.add(r);
                } catch (JSONException e) {
                    results.add(new EvalError(e.getMessage()));
                }
            }
        } else {
            Collection<Object> collection = ExpressionUtils.toObjectCollection(o);
            results = new ArrayList<Object>(collection.size());
            for (Object v : collection) {
                if (v != null) {
                    bindings.put(name, v);
                } else {
                    bindings.remove(name);
                }
                Object r = args[2].evaluate(bindings);
                results.add(r);
            }
        }
        return results.toArray();
    } finally {
        /*
             *  Restore the old value bound to the variable, if any.
             */
        if (oldValue != null) {
            bindings.put(name, oldValue);
        } else {
            bindings.remove(name);
        }
    }
}
Also used : JSONArray(org.json.JSONArray) ArrayList(java.util.ArrayList) JSONException(org.json.JSONException) Collection(java.util.Collection) EvalError(com.google.refine.expr.EvalError) VariableExpr(com.google.refine.grel.ast.VariableExpr)

Example 4 with VariableExpr

use of com.google.refine.grel.ast.VariableExpr in project OpenRefine by OpenRefine.

the class ForNonBlank method call.

@Override
public Object call(Properties bindings, Evaluable[] args) {
    Object o = args[0].evaluate(bindings);
    Evaluable var = args[1];
    String name = ((VariableExpr) var).getName();
    if (ExpressionUtils.isNonBlankData(o)) {
        Object oldValue = bindings.get(name);
        bindings.put(name, o);
        try {
            return args[2].evaluate(bindings);
        } finally {
            /*
                 *  Restore the old value bound to the variable, if any.
                 */
            if (oldValue != null) {
                bindings.put(name, oldValue);
            } else {
                bindings.remove(name);
            }
        }
    } else {
        return args[3].evaluate(bindings);
    }
}
Also used : Evaluable(com.google.refine.expr.Evaluable) VariableExpr(com.google.refine.grel.ast.VariableExpr)

Example 5 with VariableExpr

use of com.google.refine.grel.ast.VariableExpr in project OpenRefine by OpenRefine.

the class Parser method parse.

public static Template parse(String s) throws ParsingException {
    List<Fragment> fragments = new ArrayList<Fragment>();
    int start = 0, current = 0;
    while (current < s.length() - 1) {
        char c = s.charAt(current);
        char c2 = s.charAt(current + 1);
        if (c == '\\') {
            if (c2 == '\\' || c2 == '{' || c2 == '$') {
                fragments.add(new StaticFragment(s.substring(start, current).concat(Character.toString(c2))));
                start = current += 2;
            } else {
                // Invalid escape - just leave it in the template
                current += 1;
            }
            continue;
        }
        if (c == '$' && c2 == '{') {
            int closeBrace = s.indexOf('}', current + 2);
            if (closeBrace > current + 1) {
                String columnName = s.substring(current + 2, closeBrace);
                if (current > start) {
                    fragments.add(new StaticFragment(s.substring(start, current)));
                }
                start = current = closeBrace + 1;
                fragments.add(new DynamicFragment(new FieldAccessorExpr(new FieldAccessorExpr(new VariableExpr("cells"), columnName), "value")));
                continue;
            }
        } else if (c == '{' && c2 == '{') {
            int closeBrace = s.indexOf('}', current + 2);
            if (closeBrace > current + 1 && closeBrace < s.length() - 1 && s.charAt(closeBrace + 1) == '}') {
                String expression = s.substring(current + 2, closeBrace);
                if (current > start) {
                    fragments.add(new StaticFragment(s.substring(start, current)));
                }
                start = current = closeBrace + 2;
                fragments.add(new DynamicFragment(MetaParser.parse(expression)));
                continue;
            }
        }
        current++;
    }
    if (start < s.length()) {
        fragments.add(new StaticFragment(s.substring(start)));
    }
    return new Template(fragments);
}
Also used : ArrayList(java.util.ArrayList) FieldAccessorExpr(com.google.refine.grel.ast.FieldAccessorExpr) VariableExpr(com.google.refine.grel.ast.VariableExpr)

Aggregations

VariableExpr (com.google.refine.grel.ast.VariableExpr)7 ArrayList (java.util.ArrayList)5 EvalError (com.google.refine.expr.EvalError)4 JSONArray (org.json.JSONArray)3 JSONException (org.json.JSONException)3 Evaluable (com.google.refine.expr.Evaluable)2 FieldAccessorExpr (com.google.refine.grel.ast.FieldAccessorExpr)2 Collection (java.util.Collection)2 List (java.util.List)2 ParsingException (com.google.refine.expr.ParsingException)1 ArgsToArray (com.google.refine.expr.functions.arrays.ArgsToArray)1 NumberToken (com.google.refine.grel.Scanner.NumberToken)1 RegexToken (com.google.refine.grel.Scanner.RegexToken)1 ControlCallExpr (com.google.refine.grel.ast.ControlCallExpr)1 FunctionCallExpr (com.google.refine.grel.ast.FunctionCallExpr)1 LiteralExpr (com.google.refine.grel.ast.LiteralExpr)1 LinkedList (java.util.LinkedList)1 Pattern (java.util.regex.Pattern)1