Search in sources :

Example 1 with GetTagFunction

use of uk.me.parabola.mkgmap.osmstyle.function.GetTagFunction in project mkgmap by openstreetmap.

the class ExpressionReader method readConditions.

/**
 * Read the conditions.  They are terminated by a '[' or '{' character
 * or by end of file.
 * @param ifStack expressions of enclosing if / else
 */
public Op readConditions(Collection<Op[]> ifStack) {
    boolean consumedNonBlank = false;
    while (!scanner.isEndOfFile()) {
        scanner.skipSpace();
        if (scanner.checkToken("[") || scanner.checkToken("{") || scanner.checkToken("then"))
            break;
        consumedNonBlank = true;
        WordInfo wordInfo = scanner.nextWordWithInfo();
        if (isOperation(wordInfo)) {
            saveOp(wordInfo.getText());
        } else if (wordInfo.isQuoted()) {
            pushValue(wordInfo.getText());
        } else if (wordInfo.getText().charAt(0) == '$') {
            String tagname = scanner.nextWord();
            if (tagname.equals("{")) {
                tagname = scanner.nextWord();
                scanner.validateNext("}");
            }
            stack.push(new GetTagFunction(tagname));
        } else if (scanner.checkToken("(")) {
            // it is a function
            // this requires a () after the function name
            scanner.validateNext("(");
            scanner.validateNext(")");
            saveFunction(wordInfo.getText());
        } else {
            pushValue(wordInfo.getText());
        }
    }
    // Complete building the tree
    while (!opStack.isEmpty()) runOp(scanner);
    if (consumedNonBlank && !ifStack.isEmpty() && stack.size() <= 1) {
        // add expressions from enclosing if /else statements
        Op op = null;
        if (!stack.isEmpty())
            op = stack.pop();
        stack.push(appendIfExpr(op, ifStack));
    }
    // The stack should contain one entry which is the complete tree
    if (stack.size() != 1) {
        throw new SyntaxException(scanner, "Stack size is " + stack.size() + " (missing or incomplete expression)");
    }
    assert stack.size() == 1;
    Op op = stack.pop();
    if (op instanceof ValueOp)
        throw new SyntaxException(scanner, "Incomplete expression, just a single symbol: " + op);
    return op;
}
Also used : SyntaxException(uk.me.parabola.mkgmap.scan.SyntaxException) GetTagFunction(uk.me.parabola.mkgmap.osmstyle.function.GetTagFunction) WordInfo(uk.me.parabola.mkgmap.scan.WordInfo)

Example 2 with GetTagFunction

use of uk.me.parabola.mkgmap.osmstyle.function.GetTagFunction in project mkgmap by openstreetmap.

the class ExpressionReader method runOp.

/**
 * Combine the operation at the top of its stack with its values.
 * @param scanner The token scanner; used for line numbers.
 */
private void runOp(TokenScanner scanner) {
    Op op = opStack.pop();
    log.debug("Running op...", op.getType());
    if (op instanceof BinaryOp) {
        if (stack.size() < 2) {
            throw new SyntaxException(scanner, String.format("Not enough arguments for '%s' operator", op.getType().toSymbol()));
        }
        Op arg2 = stack.pop();
        Op arg1 = stack.pop();
        if (arg1.isType(VALUE))
            /*&& arg2.isType(VALUE)*/
            arg1 = new GetTagFunction(arg1.getKeyValue());
        // Deal with the case where you have: a & b=2.  The 'a' is a syntax error in this case.
        if (op.isType(OR) || op.isType(AND)) {
            if (arg1.isType(VALUE) || arg1.isType(FUNCTION))
                throw new SyntaxException(scanner, String.format("Value '%s' is not part of an expression", arg1));
            if (arg2.isType(VALUE) || arg2.isType(FUNCTION))
                throw new SyntaxException(scanner, String.format("Value '%s' is not part of an expression", arg2));
        } else {
            // type too.
            if (!(arg1.isType(VALUE) || arg1.isType(FUNCTION)) || !(arg2.isType(VALUE) || arg2.isType(FUNCTION))) {
                String msg = String.format("Invalid arguments to %s: %s (%s) and %s (%s)", op.getType(), arg1.getType(), arg1, arg2.getType(), arg2);
                throw new SyntaxException(scanner, msg);
            }
        }
        BinaryOp binaryOp = (BinaryOp) op;
        binaryOp.setFirst(arg1);
        binaryOp.setSecond(arg2);
        // The combination foo=* is converted to exists(foo).
        if (op.isType(EQUALS) && arg2.isType(VALUE) && ((ValueOp) arg2).isValue("*")) {
            log.debug("convert to EXISTS");
            op = new ExistsOp();
            op.setFirst(arg1);
        } else if (op.isType(NOT_EQUALS) && arg2.isType(VALUE) && ((ValueOp) arg2).isValue("*")) {
            log.debug("convert to NOT EXISTS");
            op = new NotExistsOp();
            op.setFirst(arg1);
        }
    } else if (!op.isType(OPEN_PAREN)) {
        if (stack.size() < 1)
            throw new SyntaxException(scanner, String.format("Missing argument for %s operator", op.getType().toSymbol()));
        op.setFirst(stack.pop());
    }
    Op first = op.getFirst();
    if (first == null)
        throw new SyntaxException(scanner, "Invalid expression");
    if (first.isType(FUNCTION) && first.getKeyValue() != null) {
        usedTags.add(first.getKeyValue());
    }
    stack.push(op);
}
Also used : SyntaxException(uk.me.parabola.mkgmap.scan.SyntaxException) GetTagFunction(uk.me.parabola.mkgmap.osmstyle.function.GetTagFunction)

Example 3 with GetTagFunction

use of uk.me.parabola.mkgmap.osmstyle.function.GetTagFunction in project mkgmap by openstreetmap.

the class RuleFileReader method readIf.

private boolean readIf(TokenScanner scanner, ExpressionReader expressionReader) {
    // Take the 'if' token
    Token tok = scanner.nextToken();
    scanner.skipSpace();
    // If 'if'' is being used as a keyword then it is followed by a '('.
    Token next = scanner.peekToken();
    if (next.getType() == TokType.SYMBOL && next.isValue("(")) {
        Op origExpr = expressionReader.readConditions();
        scanner.validateNext("then");
        // add rule expr { set <ifVar> = true }
        String ifVar = getNextIfVar();
        ArrayList<Action> actions = new ArrayList<>(1);
        actions.add(new AddTagAction(ifVar, "true", true));
        ActionList actionList = new ActionList(actions, Collections.singleton(ifVar + "=true"));
        saveRule(scanner, origExpr, actionList, null);
        // create expression (<ifVar> = true)
        EqualsOp safeExpr = new EqualsOp();
        safeExpr.setFirst(new GetTagFunction(ifVar));
        safeExpr.setSecond(new ValueOp("true"));
        Op[] ifExpressions = { origExpr, safeExpr };
        ifStack.addLast(ifExpressions);
        return true;
    } else {
        // Wrong syntax for if statement, so push back token to allow a possible expression to be read
        scanner.pushToken(tok);
    }
    return false;
}
Also used : Op(uk.me.parabola.mkgmap.osmstyle.eval.Op) ValueOp(uk.me.parabola.mkgmap.osmstyle.eval.ValueOp) EqualsOp(uk.me.parabola.mkgmap.osmstyle.eval.EqualsOp) NotOp(uk.me.parabola.mkgmap.osmstyle.eval.NotOp) EqualsOp(uk.me.parabola.mkgmap.osmstyle.eval.EqualsOp) DeleteAction(uk.me.parabola.mkgmap.osmstyle.actions.DeleteAction) AddTagAction(uk.me.parabola.mkgmap.osmstyle.actions.AddTagAction) Action(uk.me.parabola.mkgmap.osmstyle.actions.Action) AddTagAction(uk.me.parabola.mkgmap.osmstyle.actions.AddTagAction) ValueOp(uk.me.parabola.mkgmap.osmstyle.eval.ValueOp) ArrayList(java.util.ArrayList) GetTagFunction(uk.me.parabola.mkgmap.osmstyle.function.GetTagFunction) Token(uk.me.parabola.mkgmap.scan.Token) ActionList(uk.me.parabola.mkgmap.osmstyle.actions.ActionList)

Aggregations

GetTagFunction (uk.me.parabola.mkgmap.osmstyle.function.GetTagFunction)3 SyntaxException (uk.me.parabola.mkgmap.scan.SyntaxException)2 ArrayList (java.util.ArrayList)1 Action (uk.me.parabola.mkgmap.osmstyle.actions.Action)1 ActionList (uk.me.parabola.mkgmap.osmstyle.actions.ActionList)1 AddTagAction (uk.me.parabola.mkgmap.osmstyle.actions.AddTagAction)1 DeleteAction (uk.me.parabola.mkgmap.osmstyle.actions.DeleteAction)1 EqualsOp (uk.me.parabola.mkgmap.osmstyle.eval.EqualsOp)1 NotOp (uk.me.parabola.mkgmap.osmstyle.eval.NotOp)1 Op (uk.me.parabola.mkgmap.osmstyle.eval.Op)1 ValueOp (uk.me.parabola.mkgmap.osmstyle.eval.ValueOp)1 Token (uk.me.parabola.mkgmap.scan.Token)1 WordInfo (uk.me.parabola.mkgmap.scan.WordInfo)1