Search in sources :

Example 1 with FieldAccessorExpr

use of com.google.refine.grel.ast.FieldAccessorExpr 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.Error) {
            throw makeException("Unknown function or control named" + _token.text);
        } else 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 FieldAccessorExpr

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

the class Parser method parse.

/**
 * Parse method
 */
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 = findEndBrace(s, 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

FieldAccessorExpr (com.google.refine.grel.ast.FieldAccessorExpr)2 VariableExpr (com.google.refine.grel.ast.VariableExpr)2 Evaluable (com.google.refine.expr.Evaluable)1 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 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Pattern (java.util.regex.Pattern)1