Search in sources :

Example 11 with Token

use of io.github.wysohn.triggerreactor.core.script.Token in project TriggerReactor by wysohn.

the class Interpreter method interpret.

/**
 * @param node
 * @return return codes in Executor. null if execution continues.
 * @throws InterpreterException
 */
private Integer interpret(Node node) throws InterpreterException {
    try {
        if (interrupter != null && interrupter.onNodeProcess(node)) {
            return Executor.STOP;
        }
        if (node.getToken().type == Type.BODY || "IF".equals(node.getToken().value) || "ELSEIF".equals(node.getToken().value) || "WHILE".equals(node.getToken().value)) {
            return null;
        } else if (node.getToken().type == Type.EXECUTOR) {
            String command = (String) node.getToken().value;
            Object[] args = new Object[node.getChildren().size()];
            for (int i = args.length - 1; i >= 0; i--) {
                Token argument = stack.pop();
                if (isVariable(argument)) {
                    argument = unwrapVariable(argument);
                }
                args[i] = argument.value;
            }
            if (interrupter != null && interrupter.onCommand(context, command, args)) {
                return null;
            } else {
                if (!executorMap.containsKey(command))
                    throw new InterpreterException("No executor named #" + command + " found!");
                return executorMap.get(command).execute(sync, context, args);
            }
        } else if (node.getToken().type == Type.PLACEHOLDER) {
            String placeholderName = (String) node.getToken().value;
            Object[] args = new Object[node.getChildren().size()];
            for (int i = args.length - 1; i >= 0; i--) {
                Token argument = stack.pop();
                if (isVariable(argument)) {
                    argument = unwrapVariable(argument);
                }
                args[i] = argument.value;
            }
            if (!placeholderMap.containsKey(placeholderName))
                throw new InterpreterException("No placeholder named $" + placeholderName + " found!");
            Object replaced = placeholderMap.get(placeholderName).parse(context, args);
            if (replaced == null) {
                replaced = "$" + placeholderName;
            }
            if (replaced instanceof Number) {
                double d = ((Number) replaced).doubleValue();
                if (d % 1 == 0) {
                    // whole number
                    stack.push(new Token(Type.INTEGER, (int) d));
                } else {
                    stack.push(new Token(Type.DECIMAL, d));
                }
            } else {
                stack.push(new Token(Type.EPS, replaced));
            }
        } else if (node.getToken().type == Type.OPERATOR_A) {
            Token right = stack.pop();
            Token left = stack.pop();
            if (isVariable(right)) {
                right = unwrapVariable(right);
            }
            if (isVariable(left)) {
                left = unwrapVariable(left);
            }
            switch((String) node.getToken().value) {
                case "+":
                    if (left.type == Type.STRING || right.type == Type.STRING) {
                        stack.push(new Token(Type.STRING, String.valueOf(left.value) + String.valueOf(right.value)));
                    } else {
                        if (left.isInt() && right.isInt()) {
                            int leftVal = left.toInt(), rightVal = right.toInt();
                            stack.push(new Token(left.isInt() && right.isInt() ? Type.INTEGER : Type.DECIMAL, leftVal + rightVal));
                        } else {
                            double leftVal = left.isInt() ? left.toInt() : left.toDouble();
                            double rightVal = right.isInt() ? right.toInt() : right.toDouble();
                            stack.push(new Token(left.isInt() && right.isInt() ? Type.INTEGER : Type.DECIMAL, leftVal + rightVal));
                        }
                    }
                    break;
                case "-":
                    if (left.isInt() && right.isInt()) {
                        int leftVal = left.toInt(), rightVal = right.toInt();
                        stack.push(new Token(left.isInt() && right.isInt() ? Type.INTEGER : Type.DECIMAL, leftVal - rightVal));
                    } else {
                        double leftVal = left.isInt() ? left.toInt() : left.toDouble();
                        double rightVal = right.isInt() ? right.toInt() : right.toDouble();
                        stack.push(new Token(left.isInt() && right.isInt() ? Type.INTEGER : Type.DECIMAL, leftVal - rightVal));
                    }
                    break;
                case "*":
                    if (left.isInt() && right.isInt()) {
                        int leftVal = left.toInt(), rightVal = right.toInt();
                        stack.push(new Token(left.isInt() && right.isInt() ? Type.INTEGER : Type.DECIMAL, leftVal * rightVal));
                    } else {
                        double leftVal = left.isInt() ? left.toInt() : left.toDouble();
                        double rightVal = right.isInt() ? right.toInt() : right.toDouble();
                        stack.push(new Token(left.isInt() && right.isInt() ? Type.INTEGER : Type.DECIMAL, leftVal * rightVal));
                    }
                    break;
                case "/":
                    if (left.isInt() && right.isInt()) {
                        int leftVal = left.toInt(), rightVal = right.toInt();
                        stack.push(new Token(left.isInt() && right.isInt() ? Type.INTEGER : Type.DECIMAL, leftVal / rightVal));
                    } else {
                        double leftVal = left.isInt() ? left.toInt() : left.toDouble();
                        double rightVal = right.isInt() ? right.toInt() : right.toDouble();
                        stack.push(new Token(left.isInt() && right.isInt() ? Type.INTEGER : Type.DECIMAL, leftVal / rightVal));
                    }
                    break;
                case "%":
                    if (left.isInt() && right.isInt()) {
                        int leftVal = left.toInt(), rightVal = right.toInt();
                        stack.push(new Token(left.isInt() && right.isInt() ? Type.INTEGER : Type.DECIMAL, leftVal % rightVal));
                    } else {
                        double leftVal = left.isInt() ? left.toInt() : left.toDouble();
                        double rightVal = right.isInt() ? right.toInt() : right.toDouble();
                        stack.push(new Token(left.isInt() && right.isInt() ? Type.INTEGER : Type.DECIMAL, leftVal % rightVal));
                    }
                    break;
                default:
                    throw new InterpreterException("Cannot interpret the unknown operator " + node.getToken().value);
            }
        } else if (node.getToken().type == Type.UNARYMINUS) {
            Token value = stack.pop();
            if (isVariable(value)) {
                value = unwrapVariable(value);
            }
            if (!value.isNumeric())
                throw new InterpreterException("Cannot do unary minus operation for non-numeric value " + value);
            stack.push(value.isInt() ? new Token(Type.INTEGER, -value.toInt(), value.row, value.col) : new Token(Type.DECIMAL, -value.toDouble(), value.row, value.col));
        } else if (node.getToken().type == Type.OPERATOR_L) {
            if ("!".equals(node.getToken().value)) {
                Token boolval = stack.pop();
                if (isVariable(boolval)) {
                    boolval = unwrapVariable(boolval);
                }
                if (boolval.type == Type.NULLVALUE) {
                    // treat null as false
                    stack.push(new Token(Type.BOOLEAN, true));
                } else if (boolval.isBoolean()) {
                    stack.push(new Token(Type.BOOLEAN, !boolval.toBoolean()));
                } else if (boolval.isDouble()) {
                    stack.push(new Token(Type.BOOLEAN, boolval.toDouble() == 0.0));
                } else if (boolval.isInt()) {
                    stack.push(new Token(Type.BOOLEAN, boolval.toInt() == 0));
                } else {
                    throw new InterpreterException("Cannot negate non-boolean value " + boolval);
                }
            } else {
                Token right = stack.pop();
                Token left = stack.pop();
                if (isVariable(right)) {
                    right = unwrapVariable(right);
                }
                if (isVariable(left)) {
                    left = unwrapVariable(left);
                }
                switch((String) node.getToken().value) {
                    case "<":
                        if (!left.isNumeric() || !right.isNumeric())
                            throw new InterpreterException("Only numeric values can be compared!");
                        stack.push(new Token(Type.BOOLEAN, (left.isInt() ? left.toInt() : left.toDouble()) < (right.isInt() ? right.toInt() : right.toDouble())));
                        break;
                    case ">":
                        if (!left.isNumeric() || !right.isNumeric())
                            throw new InterpreterException("Only numeric values can be compared!");
                        stack.push(new Token(Type.BOOLEAN, (left.isInt() ? left.toInt() : left.toDouble()) > (right.isInt() ? right.toInt() : right.toDouble())));
                        break;
                    case "<=":
                        if (!left.isNumeric() || !right.isNumeric())
                            throw new InterpreterException("Only numeric values can be compared!");
                        stack.push(new Token(Type.BOOLEAN, (left.isInt() ? left.toInt() : left.toDouble()) <= (right.isInt() ? right.toInt() : right.toDouble())));
                        break;
                    case ">=":
                        if (!left.isNumeric() || !right.isNumeric())
                            throw new InterpreterException("Only numeric values can be compared!");
                        stack.push(new Token(Type.BOOLEAN, (left.isInt() ? left.toInt() : left.toDouble()) >= (right.isInt() ? right.toInt() : right.toDouble())));
                        break;
                    case "==":
                        if (right.type == Type.NULLVALUE) {
                            stack.push(new Token(Type.BOOLEAN, left.value == null));
                        } else {
                            stack.push(new Token(Type.BOOLEAN, left.value.equals(right.value)));
                        }
                        break;
                    case "!=":
                        if (right.type == Type.NULLVALUE) {
                            stack.push(new Token(Type.BOOLEAN, left.value != null));
                        } else {
                            stack.push(new Token(Type.BOOLEAN, !left.value.equals(right.value)));
                        }
                        break;
                    case "&&":
                        stack.push(new Token(Type.BOOLEAN, left.toBoolean() && right.toBoolean()));
                        break;
                    case "||":
                        stack.push(new Token(Type.BOOLEAN, left.toBoolean() || right.toBoolean()));
                        break;
                }
            }
        } else if (node.getToken().type == Type.OPERATOR) {
            Token right, left;
            switch((String) node.getToken().value) {
                case "=":
                    right = stack.pop();
                    left = stack.pop();
                    assignValue(left, right);
                    break;
                case ".":
                    right = stack.pop();
                    // function call
                    if (right.type == Type.CALL) {
                        Object[] args = new Object[callArgsSize];
                        for (int i = callArgsSize - 1; i >= 0; i--) {
                            Token argument = stack.pop();
                            if (isVariable(argument)) {
                                argument = unwrapVariable(argument);
                            }
                            args[i] = argument.value;
                        }
                        callArgsSize = 0;
                        left = stack.pop();
                        if (left.type == Type.THIS) {
                            callFunction(new Token(Type.OBJECT, right.value), new Token(Type.OBJECT, selfReference), args);
                        } else {
                            Token temp = left;
                            if (isVariable(left)) {
                                left = unwrapVariable(left);
                            }
                            if (left.getType() == Type.NULLVALUE) {
                                throw new InterpreterException("Could not access " + temp + " because it doesn't exist!");
                            }
                            if (left.isObject()) {
                                callFunction(right, left, args);
                            } else {
                                Accessor accessor = (Accessor) left.value;
                                Object var;
                                try {
                                    var = accessor.evaluateTarget();
                                } catch (NoSuchFieldException e) {
                                    throw new InterpreterException("Unknown field " + accessor, e);
                                } catch (Exception e) {
                                    throw new InterpreterException("Unknown error " + e.getMessage(), e);
                                }
                                callFunction(right, new Token(Type.EPS, var), args);
                            }
                        }
                    } else // field access
                    {
                        left = stack.pop();
                        if (left.type == Type.THIS) {
                            stack.push(right);
                        } else {
                            Token temp = left;
                            if (isVariable(left)) {
                                left = unwrapVariable(left);
                            }
                            if (left.getType() == Type.NULLVALUE) {
                                throw new InterpreterException("Could not access " + temp + " because it doesn't exist!");
                            }
                            if (left.isObject() || left.isArray()) {
                                stack.push(new Token(Type.ACCESS, new Accessor(left.value, (String) right.value)));
                            } else {
                                Accessor accessor = (Accessor) left.value;
                                Object var;
                                try {
                                    var = accessor.evaluateTarget();
                                } catch (NoSuchFieldException e) {
                                    throw new InterpreterException("Unknown field " + accessor, e);
                                } catch (Exception e) {
                                    throw new InterpreterException("Unknown error " + e.getMessage(), e);
                                }
                                stack.push(new Token(Type.ACCESS, new Accessor(var, (String) right.value)));
                            }
                        }
                    }
                    break;
            }
        } else if (node.getToken().type == Type.ARRAYACCESS) {
            Token right = stack.pop();
            Token left = stack.pop();
            if (isVariable(left)) {
                left = unwrapVariable(left);
            }
            if (isVariable(right)) {
                right = unwrapVariable(right);
            }
            if (!left.isArray())
                throw new InterpreterException(left + " is not an array!");
            if (!right.isInt())
                throw new InterpreterException(right + " is not a valid index for array!");
            stack.push(new Token(Type.ACCESS, new Accessor(left.value, (Integer) right.value)));
        } else if (node.getToken().type == Type.THIS) {
            stack.push(node.getToken());
        } else if (node.getToken().type == Type.ID) {
            stack.push(node.getToken());
        } else if (node.getToken().type == Type.GID) {
            Token keyToken = stack.pop();
            if (isVariable(keyToken)) {
                keyToken = unwrapVariable(keyToken);
            }
            if (keyToken.getType() != Type.STRING) {
                throw new InterpreterException(keyToken + " is not a valid global variable id.");
            }
            stack.push(new Token(Type.GID, keyToken.value));
        } else if (node.getToken().type == Type.CALL) {
            stack.push(node.getToken());
            callArgsSize = node.getChildren().size();
        } else if (node.getToken().type == Type.STRING) {
            stack.push(new Token(node.getToken().type, node.getToken().value));
        } else if (node.getToken().type == Type.INTEGER) {
            stack.push(new Token(node.getToken().type, Integer.parseInt((String) node.getToken().value)));
        } else if (node.getToken().type == Type.DECIMAL) {
            stack.push(new Token(node.getToken().type, Double.parseDouble((String) node.getToken().value)));
        } else if (node.getToken().type == Type.BOOLEAN) {
            stack.push(new Token(node.getToken().type, Boolean.parseBoolean((String) node.getToken().value)));
        } else if (node.getToken().type == Type.EPS) {
            stack.push(new Token(node.getToken().type, node.getToken().value));
        } else if (node.getToken().type == Type.NULLVALUE) {
            stack.push(new Token(node.getToken().type, null));
        } else {
            throw new InterpreterException("Cannot interpret the unknown node " + node.getToken().type.name());
        }
    } catch (Exception e) {
        throw new InterpreterException("Error occured while processing Node " + node, e);
    }
    return null;
}
Also used : Token(io.github.wysohn.triggerreactor.core.script.Token) IScriptObject(io.github.wysohn.triggerreactor.core.script.wrapper.IScriptObject) Accessor(io.github.wysohn.triggerreactor.core.script.wrapper.Accessor)

Example 12 with Token

use of io.github.wysohn.triggerreactor.core.script.Token in project TriggerReactor by wysohn.

the class Interpreter method start.

// Check if stopFlag is on before pop Token from stack.
private void start(Node node) throws InterpreterException {
    if (stopFlag)
        return;
    // IF children -- [0] : condition , [1] : true body , [2] : false body(may not exist)
    if ("ELSEIF".equals(node.getToken().value) || "IF".equals(node.getToken().value)) {
        // [0] condition
        start(node.getChildren().get(0));
        if (stopFlag)
            return;
        Token resultToken = stack.pop();
        if (isVariable(resultToken)) {
            resultToken = unwrapVariable(resultToken);
        }
        if (resultToken.type == Type.NULLVALUE) {
            // null check failed
            if (node.getChildren().size() > 2) {
                start(node.getChildren().get(2));
            }
        } else {
            // normal IF statement
            if (resultToken.isBoolean()) {
                boolean result = (boolean) resultToken.value;
                if (result) {
                    // [1] true body
                    start(node.getChildren().get(1));
                } else if (node.getChildren().size() > 2) {
                    // [2] false body
                    start(node.getChildren().get(2));
                }
            } else if (resultToken.isInt()) {
                int value = resultToken.toInt();
                if (value != 0) {
                    start(node.getChildren().get(1));
                } else if (node.getChildren().size() > 2) {
                    start(node.getChildren().get(2));
                }
            } else if (resultToken.isDouble()) {
                double value = resultToken.toDouble();
                if (value != 0.0) {
                    start(node.getChildren().get(1));
                } else if (node.getChildren().size() > 2) {
                    start(node.getChildren().get(2));
                }
            } else if (resultToken.value != null) {
                // always true if not null
                start(node.getChildren().get(1));
            } else {
                throw new InterpreterException("Unexpected token for IF statement! -- " + resultToken);
            }
        }
    } else if ("WHILE".equals(node.getToken().value)) {
        Token resultToken = null;
        do {
            start(node.getChildren().get(0));
            resultToken = stack.pop();
            if (resultToken == null)
                throw new InterpreterException("Could not find conditon for WHILE statement!");
            if (isVariable(resultToken)) {
                resultToken = unwrapVariable(resultToken);
            }
            if (!(resultToken.value instanceof Boolean))
                throw new InterpreterException("Unexpected token for WHILE statement! -- " + resultToken);
            if ((boolean) resultToken.value) {
                start(node.getChildren().get(1));
            } else {
                break;
            }
        } while (!stopFlag);
    } else if ("FOR".equals(node.getToken().value)) {
        start(node.getChildren().get(0));
        if (stopFlag)
            return;
        Token idToken = stack.pop();
        if (idToken == null)
            throw new InterpreterException("Iteration variable for FOR statement not found!");
        if (node.getChildren().get(1).getToken().type != Type.ITERATOR)
            throw new InterpreterException("Expected <ITERATOR> but found " + node.getChildren().get(1).getToken());
        Node iterNode = node.getChildren().get(1);
        if (iterNode.getChildren().size() == 1) {
            start(iterNode.getChildren().get(0));
            if (stopFlag)
                return;
            Token valueToken = stack.pop();
            if (isVariable(valueToken)) {
                valueToken = unwrapVariable(valueToken);
            }
            if (!valueToken.isIterable())
                throw new InterpreterException(valueToken + " is not iterable!");
            if (valueToken.isArray()) {
                for (int i = 0; i < Array.getLength(valueToken.value); i++) {
                    Object obj = Array.get(valueToken.value, i);
                    if (stopFlag)
                        break;
                    assignValue(idToken, parseValue(obj));
                    start(node.getChildren().get(2));
                }
            } else {
                for (Object obj : (Iterable<?>) valueToken.value) {
                    if (stopFlag)
                        break;
                    assignValue(idToken, parseValue(obj));
                    start(node.getChildren().get(2));
                }
            }
        } else if (iterNode.getChildren().size() == 2) {
            Node initNode = iterNode.getChildren().get(0);
            if (initNode.getToken().type != Type.INTEGER)
                throw new InterpreterException("Init value must be an Integer value! -- " + initNode);
            start(initNode);
            if (stopFlag)
                return;
            Token initToken = stack.pop();
            Node limitNode = iterNode.getChildren().get(1);
            start(limitNode);
            if (stopFlag)
                return;
            Token limitToken = stack.pop();
            if (isVariable(limitToken)) {
                limitToken = unwrapVariable(limitToken);
            }
            if (limitToken.type != Type.INTEGER)
                throw new InterpreterException("Limit value must be an Integer value! -- " + limitToken);
            for (int i = initToken.toInt(); !stopFlag && i < limitToken.toInt(); i++) {
                assignValue(idToken, new Token(Type.INTEGER, i));
                start(node.getChildren().get(2));
            }
        } else {
            throw new InterpreterException("Number of <ITERATOR> must be 1 or 2!");
        }
    } else {
        for (int i = 0; i < node.getChildren().size(); i++) {
            Node child = node.getChildren().get(i);
            start(child);
            // experimental
            if (i == 0) {
                if ("&&".equals(node.getToken().value)) {
                    Token leftBool = stack.pop();
                    if (isVariable(leftBool)) {
                        leftBool = unwrapVariable(leftBool);
                    }
                    stack.push(leftBool);
                    if (!leftBool.isBoolean())
                        throw new InterpreterException("Left of && operator should be Boolean but was " + leftBool);
                    boolean result = leftBool.toBoolean();
                    if (!result) {
                        // false anyway
                        return;
                    }
                } else if ("||".equals(node.getToken().value)) {
                    Token leftBool = stack.pop();
                    if (isVariable(leftBool)) {
                        leftBool = unwrapVariable(leftBool);
                    }
                    stack.push(leftBool);
                    if (!leftBool.isBoolean())
                        throw new InterpreterException("Left of || operator should be Boolean but was " + leftBool);
                    boolean result = leftBool.toBoolean();
                    if (result) {
                        // true anyway
                        return;
                    }
                }
            }
        }
    }
    Integer result = interpret(node);
    if (result != null) {
        switch(result) {
            case Executor.STOP:
                stopFlag = true;
                return;
            case Executor.WAIT:
                waitFlag = true;
                synchronized (this) {
                    while (waitFlag) {
                        try {
                            this.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                break;
            default:
                throw new InterpreterException(result + " is not a valid return code!");
        }
    }
}
Also used : Node(io.github.wysohn.triggerreactor.core.script.parser.Node) Token(io.github.wysohn.triggerreactor.core.script.Token) IScriptObject(io.github.wysohn.triggerreactor.core.script.wrapper.IScriptObject)

Example 13 with Token

use of io.github.wysohn.triggerreactor.core.script.Token in project TriggerReactor by wysohn.

the class Parser method parseStatement.

private Node parseStatement() throws ParserException, IOException, LexerException {
    skipEndLines();
    if (token != null) {
        if ("IF".equals(token.value)) {
            return parseIf();
        } else if ("ELSEIF".equals(token.value)) {
            Node elseNode = new Node(token);
            return elseNode;
        } else if ("ELSE".equals(token.value)) {
            Node elseNode = new Node(token);
            return elseNode;
        } else if ("ENDIF".equals(token.value)) {
            Node endIfNode = new Node(token);
            return endIfNode;
        } else if ("WHILE".equals(token.value)) {
            Node whileNode = new Node(token);
            nextToken();
            Node condition = parseComparison();
            if (condition == null)
                throw new ParserException("Could not find condition for WHILE statement! " + whileNode.getToken());
            whileNode.getChildren().add(condition);
            Node body = new Node(new Token(Type.BODY, "<BODY>"));
            Node codes = null;
            while ((codes = parseStatement()) != null && !"ENDWHILE".equals(codes.getToken().value)) {
                body.getChildren().add(codes);
            }
            if (codes == null)
                throw new ParserException("Could not find ENDWHILE statement! " + whileNode.getToken());
            whileNode.getChildren().add(body);
            return whileNode;
        } else if ("ENDWHILE".equals(token.value)) {
            Node endWhileNode = new Node(token);
            nextToken();
            return endWhileNode;
        } else if ("FOR".equals(token.value)) {
            Node forNode = new Node(token);
            nextToken();
            Node varName = parseId();
            if (varName == null)
                throw new ParserException("Could not find variable name for FOR statement! " + forNode.getToken());
            forNode.getChildren().add(varName);
            if (!"=".equals(token.value))
                throw new ParserException("Expected '=' but found " + token);
            nextToken();
            Node iteration = new Node(new Token(Type.ITERATOR, "<ITERATOR>"));
            forNode.getChildren().add(iteration);
            Node first = parseFactor();
            if (first == null)
                throw new ParserException("Could not find initial value for FOR statement! " + forNode.getToken());
            iteration.getChildren().add(first);
            if (":".equals(token.value)) {
                nextToken();
                Node second = parseFactor();
                if (second == null)
                    throw new ParserException("Could not find max limit for FOR statement! " + forNode.getToken());
                iteration.getChildren().add(second);
            }
            Node body = new Node(new Token(Type.BODY, "<BODY>"));
            Node codes = null;
            while ((codes = parseStatement()) != null && !"ENDFOR".equals(codes.getToken().value)) {
                body.getChildren().add(codes);
            }
            if (codes == null)
                throw new ParserException("Could not find ENDFOR statement! " + forNode.getToken());
            forNode.getChildren().add(body);
            return forNode;
        } else if ("ENDFOR".equals(token.value)) {
            Node endForNode = new Node(token);
            nextToken();
            return endForNode;
        } else if (token.type == Type.ID) {
            if (((String) token.value).charAt(0) == '#') {
                int row = token.row;
                int col = token.col;
                String command = ((String) token.value).substring(1);
                StringBuilder builder = new StringBuilder(command);
                nextToken();
                while (token != null && ":".equals(token.value)) {
                    nextToken();
                    builder.append(":" + token.value);
                    nextToken();
                }
                Node commandNode = new Node(new Token(Type.EXECUTOR, builder.toString(), row, col));
                List<Node> args = new ArrayList<>();
                if (token != null && token.type != Type.ENDL) {
                    do {
                        Node node = parseLogic();
                        if (node != null)
                            args.add(node);
                        if (token != null && ",".equals(token.value))
                            nextToken();
                    } while ((token != null && token.type != Type.ENDL));
                }
                commandNode.getChildren().addAll(args);
                nextToken();
                return commandNode;
            } else {
                Node left = parseFactor();
                if (left == null)
                    throw new ParserException("Expected an Id but found nothing. Is the code complete?");
                if (token == null || token.type == Type.ENDL)
                    return left;
                if (!"=".equals(token.value))
                    throw new ParserException("Expected '=' after id [" + left.getToken() + "] but found " + token);
                Node assign = new Node(new Token(Type.OPERATOR, "=", token.row, token.col));
                nextToken();
                Node right = parseLogic();
                if (right == null)
                    throw new ParserException("Expected some logic but found nothing. Is the code complete?");
                assign.getChildren().add(left);
                assign.getChildren().add(right);
                if (token != null && token.type != Type.ENDL)
                    throw new ParserException("Expected end of line but found " + token);
                nextToken();
                return assign;
            }
        } else if (token.type == Type.OPERATOR && "{".equals(token.value)) {
            nextToken();
            Node left = new Node(new Token(Type.GID, "<GVAR>"));
            Node keyString = parseLogic();
            left.getChildren().add(keyString);
            if (token == null || token.type != Type.OPERATOR || !"}".equals(token.value)) {
                throw new ParserException("Expected '}' but found " + token);
            }
            nextToken();
            if (!"=".equals(token.value))
                throw new ParserException("Expected '=' after id [" + left.getToken().value + "] but found " + token);
            Node assign = new Node(new Token(Type.OPERATOR, "=", token.row, token.col));
            nextToken();
            Node right = parseLogic();
            if (right == null)
                throw new ParserException("Expected logic but found nothing " + token);
            assign.getChildren().add(left);
            assign.getChildren().add(right);
            if (token != null && token.type != Type.ENDL)
                throw new ParserException("Expected end of line but found " + token);
            nextToken();
            return assign;
        } else {
            throw new ParserException("Unexpected token " + token);
        }
    } else {
        return null;
    }
}
Also used : DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode) ArrayList(java.util.ArrayList) Token(io.github.wysohn.triggerreactor.core.script.Token)

Example 14 with Token

use of io.github.wysohn.triggerreactor.core.script.Token in project TriggerReactor by wysohn.

the class Lexer method main.

public static void main(String[] ar) throws IOException, LexerException {
    Charset charset = Charset.forName("UTF-8");
    String text = "" + "X = 5\n" + "str = \"abc\"\n" + "FOR i = 0 : 10\n" + "    str = str + X\n" + "    IF player.in.health > 2 && player.in.health[3] > 0\n" + "        #MESSAGE 3*4\n" + "    ELSE\n" + "        #MESSAGE str\n" + "    ENDIF\n" + "    #MESSAGE player.in.hasPermission(x, 2+3, 5 > 4)\n" + "    X = X - 1\n" + "    IF X < 0\n" + "        #STOP\n" + "    ENDIF\n" + "    #WAIT 1\n" + "ENDFOR";
    // String text = "#CMD \"w \"+name ";
    System.out.println("original: \n" + text);
    Lexer lexer = new Lexer(text, charset);
    System.out.println("result: \n");
    Token tok = null;
    while ((tok = lexer.getToken()) != null) System.out.println(tok.type + "] " + tok.value);
}
Also used : Charset(java.nio.charset.Charset) Token(io.github.wysohn.triggerreactor.core.script.Token)

Example 15 with Token

use of io.github.wysohn.triggerreactor.core.script.Token in project TriggerReactor by wysohn.

the class Parser method parse.

public Node parse() throws IOException, LexerException, ParserException {
    Node root = new Node(new Token(Type.ROOT, "<ROOT>", -1, -1));
    Node statement = null;
    while ((statement = parseStatement()) != null) root.getChildren().add(statement);
    return root;
}
Also used : DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode) Token(io.github.wysohn.triggerreactor.core.script.Token)

Aggregations

Token (io.github.wysohn.triggerreactor.core.script.Token)20 Charset (java.nio.charset.Charset)11 Lexer (io.github.wysohn.triggerreactor.core.script.lexer.Lexer)10 Test (org.junit.Test)10 Node (io.github.wysohn.triggerreactor.core.script.parser.Node)7 LinkedList (java.util.LinkedList)7 Parser (io.github.wysohn.triggerreactor.core.script.parser.Parser)6 DefaultMutableTreeNode (javax.swing.tree.DefaultMutableTreeNode)6 IScriptObject (io.github.wysohn.triggerreactor.core.script.wrapper.IScriptObject)2 Accessor (io.github.wysohn.triggerreactor.core.script.wrapper.Accessor)1 ArrayList (java.util.ArrayList)1 Stack (java.util.Stack)1