Search in sources :

Example 1 with Token

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

the class Parser method parseId.

private Node parseId(Deque<Node> deque) {
    Stack<Node> stack = new Stack<>();
    stack.push(deque.pop());
    while (!deque.isEmpty()) {
        Node node = new Node(new Token(Type.OPERATOR, "."));
        node.getChildren().add(stack.pop());
        node.getChildren().add(deque.pop());
        stack.push(node);
    }
    return stack.pop();
}
Also used : DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode) Token(io.github.wysohn.triggerreactor.core.script.Token) Stack(java.util.Stack)

Example 2 with Token

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

the class Parser method parseIf.

private Node parseIf() throws IOException, LexerException, ParserException {
    Node ifNode = new Node(token);
    nextToken();
    // condition
    Node condition = parseLogic();
    if (condition == null)
        throw new ParserException("Could not find condition for IF statement! " + ifNode.getToken());
    ifNode.getChildren().add(condition);
    // if body
    Node trueBody = new Node(new Token(Type.BODY, "<BODY>"));
    Node codes = null;
    while ((codes = parseStatement()) != null && !"ENDIF".equals(codes.getToken().value) && !"ELSE".equals(codes.getToken().value) && !"ELSEIF".equals(codes.getToken().value)) {
        trueBody.getChildren().add(codes);
    }
    ifNode.getChildren().add(trueBody);
    if (codes == null) {
        if (codes == null || !"ENDIF".equals(codes.getToken().value))
            throw new ParserException("Could not find ENDIF statement! " + ifNode.getToken());
    }
    if ("ELSEIF".equals(codes.getToken().value)) {
        // elseif body
        Node falseBody = new Node(new Token(Type.BODY, "<BODY>"));
        falseBody.getChildren().add(parseIf());
        ifNode.getChildren().add(falseBody);
    } else if ("ELSE".equals(codes.getToken().value)) {
        // else body
        Node falseBody = new Node(new Token(Type.BODY, "<BODY>"));
        nextToken();
        while ((codes = parseStatement()) != null && !"ENDIF".equals(codes.getToken().value)) {
            falseBody.getChildren().add(codes);
        }
        if (codes == null || !"ENDIF".equals(codes.getToken().value))
            throw new ParserException("Could not find ENDIF statement! " + ifNode.getToken());
        nextToken();
        ifNode.getChildren().add(falseBody);
    } else {
        if (codes == null || !"ENDIF".equals(codes.getToken().value))
            throw new ParserException("Could not find ENDIF statement! " + ifNode.getToken());
        nextToken();
    }
    // return
    return ifNode;
}
Also used : DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode) Token(io.github.wysohn.triggerreactor.core.script.Token)

Example 3 with Token

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

the class Parser method parseFactor.

private Node parseFactor() throws IOException, LexerException, ParserException {
    if ("true".equals(token.value) || "false".equals(token.value)) {
        Node node = new Node(new Token(Type.BOOLEAN, token.value, token.row, token.col));
        nextToken();
        return node;
    }
    if ("null".equals(token.value)) {
        Node node = new Node(new Token(Type.NULLVALUE, null, token.row, token.col));
        nextToken();
        return node;
    }
    if ("$".equals(token.value)) {
        nextToken();
        if (token.type != Type.ID)
            throw new ParserException("Expected to find name of placeholder after $, but found " + token);
        // probably has to be string at this point.
        String placeholderName = (String) token.value;
        Node node = new Node(new Token(Type.PLACEHOLDER, placeholderName, token.row, token.col));
        nextToken();
        while (token != null && ":".equals(token.value)) {
            nextToken();
            node.getChildren().add(parseFactor());
        }
        return node;
    }
    Node idNode = parseId();
    if (idNode != null) {
        return idNode;
    }
    if (token == null)
        return null;
    if (token.type == Type.OPERATOR && "{".equals(token.value)) {
        nextToken();
        Node gvarNode = new Node(new Token(Type.GID, "<GVAR>"));
        Node keyString = parseLogic();
        gvarNode.getChildren().add(keyString);
        if (token == null || token.type != Type.OPERATOR || !"}".equals(token.value)) {
            throw new ParserException("Expected '}' but found " + token);
        }
        nextToken();
        return gvarNode;
    }
    if (token.type == Type.OPERATOR && "(".equals(token.value)) {
        nextToken();
        Node expression = parseLogic();
        if (token == null || token.type != Type.OPERATOR || !")".equals(token.value)) {
            throw new ParserException("Expected ')' but found " + token);
        }
        nextToken();
        return expression;
    }
    // do not process command as an Id
    if (token.type == Type.ID && ((String) token.value).charAt(0) == '#') {
        return null;
    }
    if (token.type.isLiteral()) {
        Node node = new Node(token);
        nextToken();
        return node;
    }
    // unary minus
    if (token.type == Type.OPERATOR_A && "-".equals(token.value)) {
        nextToken();
        if (// number
        token.type != Type.INTEGER && token.type != Type.DECIMAL && // variable
        token.type != Type.ID && // gvar
        !"{".equals(token.value) && // placeholder
        !"$".equals(token.value) && // factor
        !"(".equals(token.value))
            throw new ParserException("Only Number, Variable, or Placeholder are allowed for unary minus operation! " + token);
        Node node = new Node(new Token(Type.UNARYMINUS, "<UNARYMINUS>", token.row, token.col));
        node.getChildren().add(parseFactor());
        return node;
    }
    // negation
    if (token.type == Type.OPERATOR_L && "!".equals(token.value)) {
        Node node = new Node(token);
        nextToken();
        Node child = parseFactor();
        node.getChildren().add(child);
        return node;
    }
    throw new ParserException("Unexpected token " + token);
}
Also used : DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode) Token(io.github.wysohn.triggerreactor.core.script.Token)

Example 4 with Token

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

the class Parser method parseId.

private Node parseId() throws IOException, LexerException, ParserException {
    if (token.type == Type.ID) {
        Deque<Node> deque = new LinkedList<>();
        Token idToken;
        do {
            if (".".equals(token.value))
                nextToken();
            idToken = token;
            nextToken();
            // id[i]
            if (token != null && token.type == Type.OPERATOR && token.value.equals("[")) {
                // array access                                                                                   // access
                nextToken();
                Node index = parseExpression();
                Node arrAccess = new Node(new Token(Type.ARRAYACCESS, "<Array Access>"));
                if (token == null || !"]".equals(token.value))
                    throw new ParserException("Expected ']' but found " + token);
                nextToken();
                arrAccess.getChildren().add(new Node(idToken));
                arrAccess.getChildren().add(index);
                deque.addLast(arrAccess);
            } else // id(args)
            if (token != null && "(".equals(token.value)) {
                // fuction call
                nextToken();
                Node call = new Node(new Token(Type.CALL, idToken.value));
                if (token != null && ")".equals(token.value)) {
                    deque.addLast(call);
                    nextToken();
                } else {
                    call.getChildren().add(parseLogic());
                    while (token != null && ",".equals(token.value)) {
                        nextToken();
                        call.getChildren().add(parseLogic());
                    }
                    if (token == null || !")".equals(token.value))
                        throw new ParserException("Extected ')' but end of stream is reached. " + token);
                    nextToken();
                    deque.addLast(call);
                }
                // id(args)[i]
                if (token != null && token.type == Type.OPERATOR && token.value.equals("[")) {
                    // array access                                                                                   // access
                    nextToken();
                    Node index = parseExpression();
                    Node arrAccess = new Node(new Token(Type.ARRAYACCESS, "<Array Access>"));
                    if (token == null || !"]".equals(token.value))
                        throw new ParserException("Expected ']' but found " + token);
                    nextToken();
                    arrAccess.getChildren().add(index);
                    deque.addLast(arrAccess);
                }
            } else // id
            {
                if (idToken.type != Type.ID)
                    throw new ParserException("Expected an ID but found " + idToken);
                deque.addLast(new Node(idToken));
            }
        } while (token != null && ".".equals(token.value));
        if (deque.peekFirst().getToken().type != Type.THIS)
            deque.push(new Node(new Token(Type.THIS, "<This>", -1, -1)));
        return parseId(deque);
    } else {
        return null;
    }
}
Also used : DefaultMutableTreeNode(javax.swing.tree.DefaultMutableTreeNode) Token(io.github.wysohn.triggerreactor.core.script.Token) LinkedList(java.util.LinkedList)

Example 5 with Token

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

the class Lexer method readOperator.

private Token readOperator() throws IOException, LexerException {
    if (c == '<' || c == '>' || c == '!') {
        String op = String.valueOf(c);
        read();
        if (c == '=') {
            read();
            return new Token(Type.OPERATOR_L, op + "=", row, col);
        } else {
            return new Token(Type.OPERATOR_L, op, row, col);
        }
    } else if (c == '|') {
        String op = String.valueOf(c);
        read();
        if (c == '|') {
            read();
            return new Token(Type.OPERATOR_L, op + "|", row, col);
        } else {
            throw new LexerException("Bit operator is not yet implemented.", this);
        }
    } else if (c == '&') {
        String op = String.valueOf(c);
        read();
        if (c == '&') {
            read();
            return new Token(Type.OPERATOR_L, op + "&", row, col);
        } else {
            throw new LexerException("Bit operator is not yet implemented.", this);
        }
    } else if (c == '=') {
        String op = String.valueOf(c);
        read();
        if (c == '=') {
            read();
            return new Token(Type.OPERATOR_L, op + "=", row, col);
        } else {
            return new Token(Type.OPERATOR, op, row, col);
        }
    } else {
        Token token = null;
        if (c == '+' || c == '-' || c == '*' || c == '/' || c == '%') {
            token = new Token(Type.OPERATOR_A, String.valueOf(c), row, col);
        } else {
            token = new Token(Type.OPERATOR, String.valueOf(c), row, col);
        }
        read();
        return token;
    }
}
Also used : 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