diff --git a/src/be/jeffcheasey88/peeratcode/parser/Tokenizer.java b/src/be/jeffcheasey88/peeratcode/parser/Tokenizer.java index d1ab30f..8bdf391 100644 --- a/src/be/jeffcheasey88/peeratcode/parser/Tokenizer.java +++ b/src/be/jeffcheasey88/peeratcode/parser/Tokenizer.java @@ -78,12 +78,12 @@ public class Tokenizer { for(int i = 0; i < line.length(); i++){ char c = line.charAt(i); Token token; - if(Character.isAlphabetic(c) || Character.isDigit(c)){ + if(Character.isAlphabetic(c) || Character.isDigit(c) || c == '_' || c == '$'){ String value = ""; int j = i; for(; j < line.length(); j++){ c = line.charAt(j); - if(Character.isAlphabetic(c) || Character.isDigit(c)) value+=c; + if(Character.isAlphabetic(c) || Character.isDigit(c) || c == '_' || c == '$') value+=c; else break; } token = new Token(1, i+1, value, TokenType.NAME); diff --git a/src/be/jeffcheasey88/peeratcode/parser/java/Annotation.java b/src/be/jeffcheasey88/peeratcode/parser/java/Annotation.java index 995797a..5f46c92 100644 --- a/src/be/jeffcheasey88/peeratcode/parser/java/Annotation.java +++ b/src/be/jeffcheasey88/peeratcode/parser/java/Annotation.java @@ -6,6 +6,12 @@ import be.jeffcheasey88.peeratcode.parser.Token; public class Annotation{ + public static interface Annotable{ + + void addAnnotation(Annotation annotation); + + } + private Token name; private Map values; diff --git a/src/be/jeffcheasey88/peeratcode/parser/java/Class.java b/src/be/jeffcheasey88/peeratcode/parser/java/Class.java index c25a685..81e5401 100644 --- a/src/be/jeffcheasey88/peeratcode/parser/java/Class.java +++ b/src/be/jeffcheasey88/peeratcode/parser/java/Class.java @@ -3,8 +3,11 @@ package be.jeffcheasey88.peeratcode.parser.java; import java.util.List; import be.jeffcheasey88.peeratcode.parser.Token; +import be.jeffcheasey88.peeratcode.parser.java.Annotation.Annotable; +import be.jeffcheasey88.peeratcode.parser.java.Function.FunctionContainer; +import be.jeffcheasey88.peeratcode.parser.java.Variable.VariableContainer; -public class Class extends JavaElement implements FunctionContainer{ +public class Class extends JavaElement implements Annotable, FunctionContainer, VariableContainer{ private List annotations; @@ -20,6 +23,16 @@ public class Class extends JavaElement implements FunctionContainer{ public void addFunction(Function function) { this.elements.add(function); } + + @Override + public void addAnnotation(Annotation annotation) { + this.annotations.add(annotation); + } + + @Override + public void addVariable(Variable variable) { + this.elements.add(variable); + } } diff --git a/src/be/jeffcheasey88/peeratcode/parser/java/Function.java b/src/be/jeffcheasey88/peeratcode/parser/java/Function.java index 0735cee..041c1f7 100644 --- a/src/be/jeffcheasey88/peeratcode/parser/java/Function.java +++ b/src/be/jeffcheasey88/peeratcode/parser/java/Function.java @@ -3,8 +3,16 @@ package be.jeffcheasey88.peeratcode.parser.java; import java.util.List; import be.jeffcheasey88.peeratcode.parser.Token; +import be.jeffcheasey88.peeratcode.parser.java.Annotation.Annotable; +import be.jeffcheasey88.peeratcode.parser.java.Variable.VariableContainer; -public class Function extends JavaElement{ +public class Function extends JavaElement implements Annotable, VariableContainer{ + + public static interface FunctionContainer{ + + void addFunction(Function function); + + } private List annotations; @@ -38,4 +46,14 @@ public class Function extends JavaElement{ this.throwables = throwables; } + @Override + public void addAnnotation(Annotation annotation) { + this.annotations.add(annotation); + } + + @Override + public void addVariable(Variable variable) { + this.elements.add(variable); + } + } diff --git a/src/be/jeffcheasey88/peeratcode/parser/java/FunctionContainer.java b/src/be/jeffcheasey88/peeratcode/parser/java/FunctionContainer.java deleted file mode 100644 index 2c34755..0000000 --- a/src/be/jeffcheasey88/peeratcode/parser/java/FunctionContainer.java +++ /dev/null @@ -1,7 +0,0 @@ -package be.jeffcheasey88.peeratcode.parser.java; - -public interface FunctionContainer{ - - void addFunction(Function function); - -} diff --git a/src/be/jeffcheasey88/peeratcode/parser/java/JavaParser.java b/src/be/jeffcheasey88/peeratcode/parser/java/JavaParser.java index f829260..059f0ac 100644 --- a/src/be/jeffcheasey88/peeratcode/parser/java/JavaParser.java +++ b/src/be/jeffcheasey88/peeratcode/parser/java/JavaParser.java @@ -20,6 +20,8 @@ import be.jeffcheasey88.peeratcode.parser.Token; import be.jeffcheasey88.peeratcode.parser.TokenType; import be.jeffcheasey88.peeratcode.parser.TokenValidator; import be.jeffcheasey88.peeratcode.parser.Tokenizer; +import be.jeffcheasey88.peeratcode.parser.java.Annotation.Annotable; +import be.jeffcheasey88.peeratcode.parser.java.Function.FunctionContainer; import be.jeffcheasey88.peeratcode.parser.java.Value.BiValue; import be.jeffcheasey88.peeratcode.parser.state.BuilderStateTree; import be.jeffcheasey88.peeratcode.parser.state.InitialStateTree; @@ -134,6 +136,8 @@ public class JavaParser extends Parser { StateTree type_generic_split = type_generic.then((validator) -> validator.validate((token) -> token.getValue().equals(","), concat)); type_generic_split.then(type_generic); + type_begin.then(type_generic_end); //remove ? + StateTree type_generic_unknow = type_begin.then((validator) -> validator.validate((token) -> token.getValue().equals("?"), concat)); type_generic_unknow.then(type_generic_end); type_generic_split.then(type_generic_unknow); @@ -279,9 +283,6 @@ public class JavaParser extends Parser { StateTree value_parenthesis_end = value_parenthesis.then(new RedirectStateTree<>(value_container, (global, local) -> global.set("left", local.get()))) .then((validator) -> validator.validate((token) -> token.getValue().equals(")"))); value_parenthesis_end.end(); - value_parenthesis_end.then((v) -> v.validate((t) -> { - return false; - })); value_parenthesis_end.then(value_call); value_parenthesis_end.then(value_left); value_container.then((validator) -> validator.validate((token) -> token.getValue().equals("!"))).then(value_container); @@ -294,7 +295,10 @@ public class JavaParser extends Parser { .then((validator) -> validator.validate((token) -> token.getValue().equals("]"))) .then(value_left); value_inside.then(value_left); - value_left.end(); + value_left.end((parent, bag) -> { + if(bag.get() == null) bag.set(bag.get("left")); + return null; + }); StateTree value_equals = value_left.then((validator) -> validator.validate((token) -> token.getValue().equals("="), (bag, token) -> bag.set("action", "="))); value_equals.then(new RedirectStateTree<>(value_container, value_right)).end(value_builder); value_equals.then((validator) -> validator.validate((token) -> token.getValue().equals("="), (bag, token) -> bag.set("action", "=="))).then(new RedirectStateTree<>(value_container, value_right)).end(value_builder); @@ -420,13 +424,17 @@ public class JavaParser extends Parser { })) .then(annotation_name); annotation_name.end((parent, bag) -> { - bag.set(new Annotation(bag.get("name"))); + Annotation result = new Annotation(bag.get("name")); + bag.set(result); + if(parent instanceof Annotable) ((Annotable)parent).addAnnotation(result); return null; }); StateTree annotation_begin = annotation_name.then((validator) -> validator.validate((token) -> token.getValue().equals("("))); StateTree annotation_end = annotation_begin.then((validator) -> validator.validate((token) -> token.getValue().equals(")"))); annotation_end.end((parent, bag) -> { - bag.set(new Annotation(bag.get("name"), bag.get("values"))); + Annotation result = new Annotation(bag.get("name"), bag.get("values")); + bag.set(result); + if(parent instanceof Annotable) ((Annotable)parent).addAnnotation(result); return null; }); StateTree annotation_var = annotation_begin.then((validator) -> validator.validate( diff --git a/src/be/jeffcheasey88/peeratcode/parser/java/Variable.java b/src/be/jeffcheasey88/peeratcode/parser/java/Variable.java index 6929e33..8b2d2d1 100644 --- a/src/be/jeffcheasey88/peeratcode/parser/java/Variable.java +++ b/src/be/jeffcheasey88/peeratcode/parser/java/Variable.java @@ -3,8 +3,15 @@ package be.jeffcheasey88.peeratcode.parser.java; import java.util.List; import be.jeffcheasey88.peeratcode.parser.Token; +import be.jeffcheasey88.peeratcode.parser.java.Annotation.Annotable; -public class Variable extends JavaElement{ +public class Variable extends JavaElement implements Annotable{ + + public static interface VariableContainer{ + + void addVariable(Variable variable); + + } private List annotations; @@ -34,4 +41,9 @@ public class Variable extends JavaElement{ public String toString(){ return "Variable[mod="+mod+", type="+type+", name="+name+", elips="+elips+", value="+value+"]"; } + + @Override + public void addAnnotation(Annotation annotation){ + this.annotations.add(annotation); + } } diff --git a/test/be/jeffcheasey88/peeratcode/parser/java/AnnotationTests.java b/test/be/jeffcheasey88/peeratcode/parser/java/AnnotationTests.java index 408b204..0647b17 100644 --- a/test/be/jeffcheasey88/peeratcode/parser/java/AnnotationTests.java +++ b/test/be/jeffcheasey88/peeratcode/parser/java/AnnotationTests.java @@ -11,6 +11,8 @@ import be.jeffcheasey88.peeratcode.parser.Parser; import be.jeffcheasey88.peeratcode.parser.Token; import be.jeffcheasey88.peeratcode.parser.TokenType; import be.jeffcheasey88.peeratcode.parser.TokenValidator; +import be.jeffcheasey88.peeratcode.parser.java.Annotation.Annotable; +import be.jeffcheasey88.peeratcode.parser.java.Function.FunctionContainer; import be.jeffcheasey88.peeratcode.parser.state.RedirectStateTree; import be.jeffcheasey88.peeratcode.parser.state.StateTree; @@ -37,13 +39,17 @@ public class AnnotationTests { })) .then(annotation_name); annotation_name.end((parent, bag) -> { - bag.set(new Annotation(bag.get("name"))); + Annotation result = new Annotation(bag.get("name")); + bag.set(result); + if(parent instanceof Annotable) ((Annotable)parent).addAnnotation(result); return null; }); StateTree annotation_begin = annotation_name.then((validator) -> validator.validate((token) -> token.getValue().equals("("))); StateTree annotation_end = annotation_begin.then((validator) -> validator.validate((token) -> token.getValue().equals(")"))); annotation_end.end((parent, bag) -> { - bag.set(new Annotation(bag.get("name"), bag.get("values"))); + Annotation result = new Annotation(bag.get("name"), bag.get("values")); + bag.set(result); + if(parent instanceof Annotable) ((Annotable)parent).addAnnotation(result); return null; }); StateTree annotation_var = annotation_begin.then((validator) -> validator.validate( diff --git a/test/be/jeffcheasey88/peeratcode/parser/java/FunctionTests.java b/test/be/jeffcheasey88/peeratcode/parser/java/FunctionTests.java index 841be4b..d7ed762 100644 --- a/test/be/jeffcheasey88/peeratcode/parser/java/FunctionTests.java +++ b/test/be/jeffcheasey88/peeratcode/parser/java/FunctionTests.java @@ -13,6 +13,7 @@ import be.jeffcheasey88.peeratcode.parser.Parser; import be.jeffcheasey88.peeratcode.parser.Token; import be.jeffcheasey88.peeratcode.parser.TokenType; import be.jeffcheasey88.peeratcode.parser.TokenValidator; +import be.jeffcheasey88.peeratcode.parser.java.Function.FunctionContainer; import be.jeffcheasey88.peeratcode.parser.state.BuilderStateTree; import be.jeffcheasey88.peeratcode.parser.state.InitialStateTree; import be.jeffcheasey88.peeratcode.parser.state.RedirectStateTree; diff --git a/test/be/jeffcheasey88/peeratcode/parser/java/TypeTests.java b/test/be/jeffcheasey88/peeratcode/parser/java/TypeTests.java index 8086c23..e5659a7 100644 --- a/test/be/jeffcheasey88/peeratcode/parser/java/TypeTests.java +++ b/test/be/jeffcheasey88/peeratcode/parser/java/TypeTests.java @@ -38,6 +38,8 @@ public class TypeTests{ StateTree type_generic_split = type_generic.then((validator) -> validator.validate((token) -> token.getValue().equals(","), concat)); type_generic_split.then(type_generic); + type_begin.then(type_generic_end); + StateTree type_generic_unknow = type_begin.then((validator) -> validator.validate((token) -> token.getValue().equals("?"), concat)); type_generic_unknow.then(type_generic_end); type_generic_split.then(type_generic_unknow); diff --git a/test/be/jeffcheasey88/peeratcode/parser/java/ValueTests.java b/test/be/jeffcheasey88/peeratcode/parser/java/ValueTests.java index acaae7a..3ce0d1c 100644 --- a/test/be/jeffcheasey88/peeratcode/parser/java/ValueTests.java +++ b/test/be/jeffcheasey88/peeratcode/parser/java/ValueTests.java @@ -54,13 +54,19 @@ public class ValueTests { StateTree value_instance = value.then((validator) -> validator.validate((token) -> token.getValue().equals("new"))); StateTree value_name = new StateTree(); value.then(value_name); - value_instance.then(new RedirectStateTree<>(value_name, (global, local) -> global.set(null))) - .end((a,b) -> a) + value_instance.then(new RedirectStateTree<>(value_name, (global, local) -> global.set(local.get()))) + .end((parent, bag) -> { + Value result = new Value(bag.get()); + bag.set(result); + return result; + }) .then((validator) -> validator.validate((token) -> token.getValue().equals("{"))) .end((a,b) -> a) // .multiple(braces_container) .unique((validator) -> validator.validate((token) -> token.getValue().equals("}"))).end((a,b) -> a); - value_name = value_name.then(new RedirectStateTree<>(TypeTests.get(), (global, local) -> global.set(local.get()))); + value_name = value_name.then(new RedirectStateTree<>(TypeTests.get(), (global, local) -> { + global.set(local.get()); + })); value_name.end((parent,bag) -> { Value result = new Value(bag.get()); bag.set(result); @@ -94,6 +100,7 @@ public class ValueTests { StateTree value_generic_name = value_generic_begin.then((validator) -> validator.validate((token) -> token.getType().equals(TokenType.NAME))); StateTree value_generic_split = value_generic_name.then((validator) -> validator.validate((token) -> token.getValue().equals(","))); StateTree value_generic_end = value_generic_begin.then((validator) -> validator.validate((token) -> token.getValue().equals(">"))); + value_generic_begin.then(value_generic_end); value_generic_end.then(value_arg_begin); value_generic_end.then(value_generic_name); value_generic_end.then(value_generic_split); diff --git a/test/be/jeffcheasey88/peeratcode/parser/java/VariableTests.java b/test/be/jeffcheasey88/peeratcode/parser/java/VariableTests.java new file mode 100644 index 0000000..68aadc9 --- /dev/null +++ b/test/be/jeffcheasey88/peeratcode/parser/java/VariableTests.java @@ -0,0 +1,94 @@ +package be.jeffcheasey88.peeratcode.parser.java; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.BiFunction; + +import org.junit.jupiter.api.Test; + +import be.jeffcheasey88.peeratcode.parser.Bag; +import be.jeffcheasey88.peeratcode.parser.Parser; +import be.jeffcheasey88.peeratcode.parser.Token; +import be.jeffcheasey88.peeratcode.parser.TokenType; +import be.jeffcheasey88.peeratcode.parser.TokenValidator; +import be.jeffcheasey88.peeratcode.parser.java.Variable.VariableContainer; +import be.jeffcheasey88.peeratcode.parser.state.InitialStateTree; +import be.jeffcheasey88.peeratcode.parser.state.RedirectStateTree; +import be.jeffcheasey88.peeratcode.parser.state.StateTree; + +public class VariableTests{ + + public static StateTree get(){ + BiFunction variable_builder = (parent, bag) -> { + Integer mod = bag.get("mod"); + Token type = bag.get("type"); + Map map = bag.get("vars"); + for(Entry vars : map.entrySet()){ + Variable result = new Variable(mod == null ? 0 : mod, type, vars.getKey(), false, vars.getValue()); + bag.set(result); + if(parent instanceof VariableContainer) ((VariableContainer)parent).addVariable(result); + } + return null; + }; + + InitialStateTree variable = new InitialStateTree<>(); + variable.multiple(AnnotationTests.get()); + StateTree variable_mod = variable.then(new RedirectStateTree<>(ModifierTests.get(), (global, local) -> global.set("mod", local.get()))); + StateTree variable_type = variable.then(new RedirectStateTree<>(TypeTests.get(), (global, local) -> global.set("type", local.get()))); + variable_mod.then(variable_type); + StateTree variable_name = variable_type.then((validator) -> validator.validate( + (token) -> token.getType().equals(TokenType.NAME), + (bag, token) -> { + Map map = bag.get("vars"); + if(map == null){ + map = new LinkedHashMap<>(); + bag.set("vars", map); + } + bag.set("last", token); + map.put(token, null); + })); + variable_name.then((validator) -> validator.validate((token) -> token.getValue().equals(";"))) + .end(variable_builder); + StateTree variable_split = variable_name.then((validator) -> validator.validate((token) -> token.getValue().equals(","))); + variable_split.then(variable_name); + StateTree variable_value = variable_name.then((validator) -> validator.validate((token) -> token.getValue().equals("="))) + .then(new RedirectStateTree<>(ValueTests.get(), (global, local) -> { + global.>get("vars").put(global.get("last"), local.get()); + })); + variable_value.then(variable_split); + variable_value.then((validator) -> validator.validate((token) -> token.getValue().equals(";"))) + .end(variable_builder); + variable_value.end(variable_builder); + + return variable; + } + + 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 = new JavaElement(); + + parser.parse(value, result); + + assertEquals(TokenValidator.TOKENS, TokenValidator.MAX_VALIDATE); + + return result; + } + + @Test + void hashMap() throws Exception{ + JavaElement result = testCase("private static final Map>> map = new HashMap<>();"); + } +}