package dev.peerat.parser.java; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.BiFunction; import org.junit.jupiter.api.Test; import dev.peerat.parser.Bag; import dev.peerat.parser.Parser; import dev.peerat.parser.Token; import dev.peerat.parser.TokenType; import dev.peerat.parser.TokenValidator; import dev.peerat.parser.java.operation.AssignOperation; import dev.peerat.parser.java.operation.BreakOperation; import dev.peerat.parser.java.operation.CatchOperation; import dev.peerat.parser.java.operation.ContinueOperation; import dev.peerat.parser.java.operation.DoOperation; import dev.peerat.parser.java.operation.ElseOperation; import dev.peerat.parser.java.operation.FinallyOperation; import dev.peerat.parser.java.operation.ForOperation; import dev.peerat.parser.java.operation.IfOperation; import dev.peerat.parser.java.operation.ReturnOperation; import dev.peerat.parser.java.operation.SynchronizedOperation; import dev.peerat.parser.java.operation.ThrowOperation; import dev.peerat.parser.java.operation.TryOperation; import dev.peerat.parser.java.operation.WhileOperation; import dev.peerat.parser.java.operation.Operation.OperationContainer; import dev.peerat.parser.java.value.Value; import dev.peerat.parser.state.RedirectStateTree; import dev.peerat.parser.state.StateTree; public class OperationTests { public static StateTree get(){ StateTree operation = new StateTree<>(); StateTree operation_name = operation.then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> global.set("left", local.get()))); operation_name.then((validator) -> validator.validate((token) -> token.getValue().equals(";"))).end(); operation_name.then((validator) -> validator.validate((token) -> token.getValue().equals("="))) .then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> global.set("right", local.get()))) .then((validator) -> validator.validate((token) -> token.getValue().equals(";"))) .end((parent, bag) -> { AssignOperation op = new AssignOperation(bag.get("left"), bag.get("right")); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }); StateTree operation_return = operation.then((validator) -> validator.validate((token) -> token.getValue().equals("return"))); operation_return.then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> global.set(local.get()))) .then((validator) -> validator.validate((token) -> token.getValue().equals(";"))) .end((parent,bag) -> { ReturnOperation op = new ReturnOperation(bag.get()); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }); operation_return.then((validator) -> validator.validate((token) -> token.getValue().equals(";"))) .end((parent,bag) -> { ReturnOperation op = new ReturnOperation(bag.get()); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }); operation.then((validator) -> validator.validate((token) -> token.getValue().equals("throw"))) .then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> global.set(local.get()))) .then((validator) -> validator.validate((token) -> token.getValue().equals(";"))) .end((parent,bag) -> { ThrowOperation op = new ThrowOperation(bag.get()); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }); operation.then((validator) -> validator.validate((token) -> token.getValue().equals("do"))) .then((validator) -> validator.validate((token) -> token.getValue().equals("{"))) .end((parent, bag) -> { DoOperation op = new DoOperation(); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }) // .multiple(function_container) .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))) .end(); StateTree operation_else = operation.then((validator) -> validator.validate((token) -> token.getValue().equals("else"))) .end((parent, bag) -> { ElseOperation op = new ElseOperation(); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }); operation_else.then(operation); operation_else.then((validator) -> validator.validate((token) -> token.getValue().equals("{"))) .end() // .multiple(function_container) .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))) .end(); StateTree operation_try = operation.then((validator) -> validator.validate((token) -> token.getValue().equals("try"))); StateTree operation_try_base = operation_try.then((validator) -> validator.validate((token) -> token.getValue().equals("{"))); operation_try.then((validator) -> validator.validate((token) -> token.getValue().equals("("))) .then(new RedirectStateTree<>(VariableTests.get(), (global, local) -> global.set(local.get()))) .then((validator) -> validator.validate((token) -> token.getValue().equals(")"))) .then(operation_try_base); StateTree operation_try_end = operation_try_base.end((parent,bag) -> { TryOperation op = new TryOperation(bag.get()); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }) // .multiple(function_container) .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))) .end((a,b) -> a); StateTree operation_finally = operation_try_end.then((validator) -> validator.validate((token) -> token.getValue().equals("finally"))); operation_finally.then((validator) -> validator.validate((token) -> token.getValue().equals("{"))) .end((parent, bag) -> { FinallyOperation op = new FinallyOperation(); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }) // .multiple(function_container) .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))) .end(); StateTree operation_catch_named = operation_try_end.then((validator) -> validator.validate((token) -> token.getValue().equals("catch"))) .then((validator) -> validator.validate((token) -> token.getValue().equals("("))) .then(new RedirectStateTree<>(TypeTests.get(), (global, local) -> { List list = global.get("types"); if(list == null){ list = new ArrayList<>(); global.set("types", list); } list.add(local.get()); })); operation_catch_named.then((validator) -> validator.validate((token) -> token.getValue().equals("|"))) .then(operation_catch_named); StateTree operation_catch = operation_catch_named.then((validator) -> validator.validate( (token) -> token.getType().equals(TokenType.NAME), (bag, token) -> bag.set("name", token) )) .then((validator) -> validator.validate((token) -> token.getValue().equals(")"))) .then((validator) -> validator.validate((token) -> token.getValue().equals("{"))) .end((parent,bag) -> { CatchOperation op = new CatchOperation(bag.get("types"), bag.get("name")); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }) // .multiple(function_container) .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))) .end(); operation_catch.then(operation_catch_named); operation_catch.then(operation_finally); operation.then((validator) -> validator.validate((token) -> token.getValue().equals("continue"))) .then((validator) -> validator.validate((token) -> token.getValue().equals(";"))) .end((parent,bag) -> { if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(new ContinueOperation()); return null; }); operation.then((validator) -> validator.validate((token) -> token.getValue().equals("break"))) .then((validator) -> validator.validate((token) -> token.getValue().equals(";"))) .end((parent,bag) -> { if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(new BreakOperation()); return null; }); StateTree operation_if = operation.then((validator) -> validator.validate((token) -> token.getValue().equals("if"))) .then((validator) -> validator.validate((token) -> token.getValue().equals("("))) .then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> global.set(local.get()))) .then((validator) -> validator.validate((token) -> token.getValue().equals(")"))) .end((parent,bag) -> { IfOperation op = new IfOperation(bag.get()); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }); operation_if.then(operation); operation_if.then((validator) -> validator.validate((token) -> token.getValue().equals("{"))) .end() // .multiple(function_container) .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))) .end(); StateTree switch_cases = new StateTree<>(); StateTree switch_case_begin = switch_cases.then((validator) -> validator.validate((token) -> token.getValue().equals("case"))); StateTree switch_case = switch_case_begin.then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> global.set(null))) .then((validator) -> validator.validate((token) -> token.getValue().equals(":"))); switch_case.then(switch_case_begin); switch_case.end((a,b) -> a); // .multiple(function_container); switch_cases.then((validator) -> validator.validate((token) -> token.getValue().equals("default"))) .then((validator) -> validator.validate((token) -> token.getValue().equals(":"))) .end((a,b) -> a); // .multiple(function_container); operation.then((validator) -> validator.validate((token) -> token.getValue().equals("switch"))) .then((validator) -> validator.validate((token) -> token.getValue().equals("("))) .then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> global.set(null))) .then((validator) -> validator.validate((token) -> token.getValue().equals(")")) && validator.validate((token) -> token.getValue().equals("{"))) .end((a,b) -> a) .multiple(switch_cases) .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))) .end((a,b) -> a); StateTree operation_for = operation.then((validator) -> validator.validate((token) -> token.getValue().equals("for"))) .then((validator) -> validator.validate((token) -> token.getValue().equals("("))); StateTree operation_for_first_part = operation_for.then((validator) -> validator.validate((token) -> token.getValue().equals(";"))); StateTree operation_for_modifier = operation_for.then((validator) -> validator.validate( (token) -> ModifierTests.getModifier(token.getValue()) > 0, (bag, token) -> bag.set("final", true))); operation_for_modifier.then(operation_for_modifier); StateTree operation_for_type = operation_for.then(new RedirectStateTree<>(TypeTests.get(), (global, local) -> global.set("init_type", local.get()))); operation_for_modifier.then(operation_for_type); StateTree operation_for_assign = operation_for.then((validator) -> validator.validate( (token) -> token.getType().equals(TokenType.NAME), (bag, token) -> bag.set("varname", token))); operation_for_modifier.then(operation_for_assign); operation_for_type.then(operation_for_assign); StateTree operation_for_assign_end = operation_for_assign.then((validator) -> validator.validate((token) -> token.getValue().equals("="))) .then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> { Map map = global.get("init_values"); if(map == null){ map = new HashMap<>(); global.set("init_values", map); } map.put(global.get("varname"), local.get()); })); operation_for_assign.then(operation_for_assign); operation_for_assign.then(operation_for_first_part); operation_for_assign_end.then((validator) -> validator.validate((token) -> token.getValue().equals(","))) .then(operation_for_assign); operation_for_assign_end.then(operation_for_first_part); StateTree operation_for_second_part = operation_for_first_part.then((validator) -> validator.validate((token) -> token.getValue().equals(";"))); operation_for_first_part.then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> global.set("condition", local.get()))) .then(operation_for_second_part); BiFunction operation_for_builder = (parent, bag) -> { List init_vars = new ArrayList<>(); List init_values = new ArrayList<>(); List updates = new ArrayList<>(); if(bag.has("init_type")){ } ForOperation op = new ForOperation(init_vars, init_values, bag.get("condition"), updates); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }; StateTree operation_for_end = operation_for_second_part.then((validator) -> validator.validate((token) -> token.getValue().equals(")"))); operation_for_end.end(operation_for_builder); operation_for_end.then((validator) -> validator.validate((token) -> token.getValue().equals("{"))) .end(operation_for_builder) // .multiple(function_container) .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))) .end(); operation_for_assign.then((validator) -> validator.validate((token) -> token.getValue().equals(":"))) .then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> global.set(null))) .then(operation_for_end); StateTree operation_for_update = operation_for_second_part.then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> { List list = global.get("updates"); if(list == null){ list = new ArrayList<>(); global.set("updates", list); } list.add(local.get()); })); operation_for_update.then(operation_for_end); operation_for_update.then((validator) -> validator.validate((token) -> token.getValue().equals(","))) .then(operation_for_update); StateTree operation_while = operation.then((validator) -> validator.validate((token) -> token.getValue().equals("while"))) .then((validator) -> validator.validate((token) -> token.getValue().equals("("))) .then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> global.set(local.get()))) .then((validator) -> validator.validate((token) -> token.getValue().equals(")"))); operation_while.then((validator) -> validator.validate((token) -> token.getValue().equals("{"))) .end((parent,bag) -> { WhileOperation op = new WhileOperation(bag.get()); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }) // .multiple(function_container) .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))) .end(); operation_while.then(new RedirectStateTree<>(operation, (global, local) -> global.set(null))) .end(); operation_while.then((validator) -> validator.validate((token) -> token.getValue().equals(";"))) .end((a,b) -> a); operation.then((validator) -> validator.validate((token) -> token.getValue().equals("synchronized"))) .then((validator) -> validator.validate((token) -> token.getValue().equals("("))) .then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> global.set(local.get()))) .then((validator) -> validator.validate((token) -> token.getValue().equals(")"))) .then((validator) -> validator.validate((token) -> token.getValue().equals("{"))) .end((parent,bag) -> { SynchronizedOperation op = new SynchronizedOperation(bag.get()); if(parent instanceof OperationContainer) ((OperationContainer)parent).addOperation(op); return op; }) // .multiple(function_container) .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))) .end(); // function_container.then(variable); // function_container.then(operation); return operation; } private static Parser parser = new Parser(){ { setTokenizer(ModifierTests.TOKENIZER); setStateTree(get()); } }; JavaElement testCase(String value) throws Exception{ TokenValidator.TOKENS = 0; TokenValidator.MAX_VALIDATE = 0; JavaElement result = null; parser.parse(value, result); assertEquals(TokenValidator.TOKENS, TokenValidator.MAX_VALIDATE); return result; } @Test void breakOp() throws Exception{ testCase("break;"); } @Test void CatchOp() throws Exception{ System.out.println("exception"); testCase("try{}catch(Exception e){}"); System.out.println("exception|ioexception"); testCase("try{}catch(Exception|IOException e){}"); // System.out.println("exception - ioexception"); // testCase("try{}catch(Exception e){}catch(IOException e){}"); } @Test void ContinueOp() throws Exception{ testCase("continue;"); } @Test void doOp() throws Exception{ testCase("do{}while(true);"); } @Test void elseOp() throws Exception{ testCase("if(true){}else{}"); testCase("if(true){}else if(true){}"); } @Test void finallyOp() throws Exception{ testCase("try{}catch(Exception e){}finally{}"); } @Test void forOp() throws Exception{ testCase("for(;;){}"); testCase("for(int i = 4,j=6;j < i;i++,j++){}"); testCase("for(i = 4,j=6;j < i;i++,j++){}"); } @Test void ifOp() throws Exception{ testCase("if(true){}"); } @Test void methodCallOp() throws Exception{ testCase("System.out.println(\"hello\");"); } @Test void returnOp() throws Exception{ testCase("return true;"); } @Test void switchOp() throws Exception{ testCase("switch(var){ case 1: default:}"); int var = 1; switch(var){ case 1: break; default: break; } } @Test void synchronizedOp() throws Exception{ testCase("synchronized(test){}"); } @Test void throwOp() throws Exception{ testCase("throw e;"); } // @Test // void tryOp() throws Exception{ // testCase("try(Test test = new Test()){}"); // } @Test void whileOp() throws Exception{ testCase("while(true){}"); } @Test void assignOp() throws Exception{ testCase("i=4;"); } }