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();
}
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;
}
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);
}
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;
}
}
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;
}
}
Aggregations