From 5e8207c3a632bd75f0f816f4d2e92db170d51a23 Mon Sep 17 00:00:00 2001 From: jeffcheasey88 <66554203+jeffcheasey88@users.noreply.github.com> Date: Tue, 15 Nov 2022 14:56:19 +0100 Subject: [PATCH] First Version, functional --- src/be/jeffcheasey88/Main.java | 34 ++++++ src/be/jeffcheasey88/parser/Class.java | 104 ++++++++++++++++++ src/be/jeffcheasey88/parser/CodeContext.java | 9 ++ src/be/jeffcheasey88/parser/Executable.java | 16 +++ src/be/jeffcheasey88/parser/Import.java | 36 ++++++ src/be/jeffcheasey88/parser/JavaParser.java | 104 ++++++++++++++++++ src/be/jeffcheasey88/parser/Loop.java | 90 +++++++++++++++ src/be/jeffcheasey88/parser/Method.java | 80 ++++++++++++++ src/be/jeffcheasey88/parser/Package.java | 26 +++++ src/be/jeffcheasey88/parser/Variable.java | 21 ++++ .../jeffcheasey88/parser/JavaParserTest.java | 49 +++++++++ 11 files changed, 569 insertions(+) create mode 100644 src/be/jeffcheasey88/Main.java create mode 100644 src/be/jeffcheasey88/parser/Class.java create mode 100644 src/be/jeffcheasey88/parser/CodeContext.java create mode 100644 src/be/jeffcheasey88/parser/Executable.java create mode 100644 src/be/jeffcheasey88/parser/Import.java create mode 100644 src/be/jeffcheasey88/parser/JavaParser.java create mode 100644 src/be/jeffcheasey88/parser/Loop.java create mode 100644 src/be/jeffcheasey88/parser/Method.java create mode 100644 src/be/jeffcheasey88/parser/Package.java create mode 100644 src/be/jeffcheasey88/parser/Variable.java create mode 100644 test/be/jeffcheasey88/parser/JavaParserTest.java diff --git a/src/be/jeffcheasey88/Main.java b/src/be/jeffcheasey88/Main.java new file mode 100644 index 0000000..1d587a6 --- /dev/null +++ b/src/be/jeffcheasey88/Main.java @@ -0,0 +1,34 @@ +package be.jeffcheasey88; + +import java.io.BufferedReader; +import java.io.BufferedWriter; + import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; + +import be.jeffcheasey88.parser.JavaParser; + +public class Main { + + public static void main(String[] args) throws Exception { + File file = new File("/home/BenjaminCompiler/source.java"); + BufferedReader reader = new BufferedReader(new FileReader(file)); + + JavaParser parser = new JavaParser(reader); + parser.parse(); + parser.updateLoopElse(); + + BufferedWriter writer = new BufferedWriter(new FileWriter(new File("/home/BenjaminCompiler/a/b/Result.java"))); + parser.write(writer); + writer.flush(); + writer.close(); + System.out.println("writed"); + + Process process = Runtime.getRuntime().exec("javac /home/BenjaminCompiler/a/b/Result.java"); + while(process.isAlive()); + System.out.println("exec with exitValue "+process.exitValue()); + + + } + +} diff --git a/src/be/jeffcheasey88/parser/Class.java b/src/be/jeffcheasey88/parser/Class.java new file mode 100644 index 0000000..35ab221 --- /dev/null +++ b/src/be/jeffcheasey88/parser/Class.java @@ -0,0 +1,104 @@ +package be.jeffcheasey88.parser; + +import java.io.BufferedReader; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Class { + + private static Pattern pattern = Pattern.compile("^.*\\s+(.*)(\\s+|\\{)\\{$"); + public static char endVarChar = ';'; + public static String[] packers = new String[] {"{}"}; //,"[]","()","<>" + + private String name; + + private List variables; + private List methods; + + public Class(){ + this.variables = new ArrayList<>(); + this.methods = new ArrayList<>(); + } + + public void parse(BufferedReader reader) throws Exception { + String line = reader.readLine(); + Matcher matcher = pattern.matcher(line); + matcher.matches(); + + this.name = matcher.group(1); + + String buffer = ""; + String read; + while((read = reader.readLine()) != null) buffer+=read; + + parse(buffer); + } + + private void parse(String buffer){ + buffer = removeSpaces(buffer); + + do { + String localBuffer = ""; + for(char c : buffer.toCharArray()){ + localBuffer+=c; + if(c == endVarChar){ + Variable variable = new Variable(CodeContext.CLASS); + variable.parse(localBuffer); + this.variables.add(variable); + buffer = buffer.substring(localBuffer.length()); + localBuffer = ""; + }else if(c == '{'){ + int add = 0; + int reduce = localBuffer.length(); + buffer = buffer.substring(localBuffer.length()); + for(char ch : buffer.toCharArray()){ + localBuffer+=ch; + if(ch == '{'){ + add++; + continue; + } + if(ch == '}'){ + add--; + if(add < 0){ + Method method = new Method(); + method.parse(localBuffer); + this.methods.add(method); + buffer = buffer.substring(localBuffer.length()-reduce); + break; + } + } + } + break; + } + } + if(buffer.equals(localBuffer)) break; + }while(buffer.length() > 0); + } + + private String removeSpaces(String buffer){ + String result = ""; + for(int i = 0; i < buffer.length(); i++){ + char c = buffer.charAt(i); + if(Character.isWhitespace(c)){ + if(c != ' ') continue; + } + result+=c; + } + return result; + } + + + public String getName(){ + return this.name; + } + + public List getVariables(){ + return this.variables; + } + + public List getMethods(){ + return this.methods; + } +} diff --git a/src/be/jeffcheasey88/parser/CodeContext.java b/src/be/jeffcheasey88/parser/CodeContext.java new file mode 100644 index 0000000..c2882c0 --- /dev/null +++ b/src/be/jeffcheasey88/parser/CodeContext.java @@ -0,0 +1,9 @@ +package be.jeffcheasey88.parser; + +public enum CodeContext { + + CLASS, + METHOD, + ARRAY + +} diff --git a/src/be/jeffcheasey88/parser/Executable.java b/src/be/jeffcheasey88/parser/Executable.java new file mode 100644 index 0000000..8fac62e --- /dev/null +++ b/src/be/jeffcheasey88/parser/Executable.java @@ -0,0 +1,16 @@ +package be.jeffcheasey88.parser; + +public abstract class Executable { + + private CodeContext context; + + public Executable(CodeContext context){ + this.context = context; + } + + public CodeContext getContext(){ + return this.context; + } + + public abstract void parse(String value); +} diff --git a/src/be/jeffcheasey88/parser/Import.java b/src/be/jeffcheasey88/parser/Import.java new file mode 100644 index 0000000..55352c5 --- /dev/null +++ b/src/be/jeffcheasey88/parser/Import.java @@ -0,0 +1,36 @@ +package be.jeffcheasey88.parser; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Import { + + private static Pattern pattern = Pattern.compile("^import\\s+(?:static\\s+)?(.*)\\s*;$"); + + private boolean isStatic; + private String name; + + public Import(){} + + public void parse(String line) throws Exception { + Matcher matcher = pattern.matcher(line); + matcher.matches(); + + String firstGroup = matcher.group(1); + if(firstGroup.startsWith("static")){ + this.isStatic = true; + this.name = matcher.group(2); + }else{ + this.name = firstGroup; + } + } + + public String getName(){ + return this.name; + } + + public boolean isStatic(){ + return this.isStatic; + } + +} diff --git a/src/be/jeffcheasey88/parser/JavaParser.java b/src/be/jeffcheasey88/parser/JavaParser.java new file mode 100644 index 0000000..ba5b01f --- /dev/null +++ b/src/be/jeffcheasey88/parser/JavaParser.java @@ -0,0 +1,104 @@ +package be.jeffcheasey88.parser; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class JavaParser { + + private Package pack; + private List imports; + private Class clazz; + + private BufferedReader reader; + + public JavaParser(BufferedReader reader){ + this.reader = reader; + } + + public void parse() throws Exception{ + this.pack = new Package(); + this.pack.parse(reader); + + this.imports = new ArrayList<>(); + parseImport(); + + this.clazz = new Class(); + this.clazz.parse(reader); + } + + public void updateLoopElse(){ + System.out.println("updateLoop"); + for(Method method : this.clazz.getMethods()){ + updateLoop(method.getLoops()); + } + } + + private static Random random = new Random(); + + private void updateLoop(List loops){ + for(int i = 1; i < loops.size(); i++){ + Loop loop = loops.get(i); + if(loop.getType().equalsIgnoreCase("else")){ + Loop update = loops.get(i-1); + String type = update.getType(); + if(type.equalsIgnoreCase("for") || type.equalsIgnoreCase("while")){ + String line = update.toString(); + int index = line.indexOf('{'); + update.getVariables().clear(); + update.getInnerLoops().clear(); + int id = random.nextInt(Integer.MAX_VALUE); + update.parse("boolean passLoop"+id+" = false; "+line.substring(0, index+1)+" passLoop"+id+" = true; "+line.substring(index+1)); + + line = loop.toString(); + index = line.indexOf('{'); + loop.parse("if(!passLoop"+id+"){"+line.substring(index+1)); + } + } + } + } + + private void parseImport() throws Exception{ + reader.readLine(); + String line; + while((line = reader.readLine()).length() > 0){ + Import imp = new Import(); + imp.parse(line); + this.imports.add(imp); + } + } + + public Package getPackage(){ + return this.pack; + } + + public List getImports(){ + return this.imports; + } + + public Class getClazz(){ + return this.clazz; + } + + public void write(BufferedWriter writer) throws Exception{ + writer.write("package "+pack.getName()+";\n"); + writer.write("\n"); + + for(Import imp : this.imports){ + writer.write("import "+((imp.isStatic()) ? "static ":"")+" "+imp.getName()+";\n"); + } + writer.write("\n"); + writer.write("public class "+clazz.getName()+"{\n"); + for(Variable v : clazz.getVariables()){ + writer.write("\t"+v+"\n"); + writer.write("\n"); + } + for(Method m : clazz.getMethods()){ + writer.write("\t"+m+"\n"); + writer.write("\n"); + } + writer.write("}\n"); + } +} diff --git a/src/be/jeffcheasey88/parser/Loop.java b/src/be/jeffcheasey88/parser/Loop.java new file mode 100644 index 0000000..9f43b71 --- /dev/null +++ b/src/be/jeffcheasey88/parser/Loop.java @@ -0,0 +1,90 @@ +package be.jeffcheasey88.parser; + +import java.util.ArrayList; +import java.util.List; + +public class Loop extends Executable{ + + private String line; + private String type; + private List variables; + private List loops; + + public Loop(){ + super(CodeContext.METHOD); + this.variables = new ArrayList<>(); + this.loops = new ArrayList<>(); + } + + @Override + public void parse(String value){ + this.line = value; + + this.type = value.substring(0,Math.min(Math.max(0,value.indexOf('(')), Math.max(0,value.indexOf('{')))); + + int redu = value.indexOf('{'); + String buffer = value.substring(redu+1, value.length()-1); + do { + String localBuffer = ""; + for(char c : buffer.toCharArray()){ + localBuffer+=c; + if(c == Class.endVarChar){ + Variable variable = new Variable(CodeContext.CLASS); + variable.parse(localBuffer); + this.variables.add(variable); + buffer = buffer.substring(localBuffer.length()); + localBuffer = ""; + }else if(c == '{'){ + int add = 0; + int reduce = localBuffer.length(); + buffer = buffer.substring(localBuffer.length()); + for(char ch : buffer.toCharArray()){ + localBuffer+=ch; + if(ch == '{'){ + add++; + continue; + } + if(ch == '}'){ + add--; + if(add < 0){ + Loop loop = new Loop(); + loop.parse(localBuffer); + this.loops.add(loop); + buffer = buffer.substring(localBuffer.length()-reduce); + break; + } + } + } + break; + } + } + if(buffer.equals(localBuffer)) break; + }while(buffer.length() > 0); + } + + public List getVariables(){ + return this.variables; + } + + public List getInnerLoops(){ + return this.loops; + } + + public String getType(){ + return this.type; + } + + @Override + public String toString(){ + return this.line; + } + +// public void show(List list){ +// for(String s : list){ +// System.out.println(s); +// }else{ +// System.out.println("Liste vide"); +// } +// } + +} diff --git a/src/be/jeffcheasey88/parser/Method.java b/src/be/jeffcheasey88/parser/Method.java new file mode 100644 index 0000000..71a5906 --- /dev/null +++ b/src/be/jeffcheasey88/parser/Method.java @@ -0,0 +1,80 @@ +package be.jeffcheasey88.parser; + +import java.util.ArrayList; +import java.util.List; + +public class Method extends Executable{ + + private String value; + private String head; + private List variables; + private List loops; + + public Method(){ + super(CodeContext.CLASS); + this.variables = new ArrayList<>(); + this.loops = new ArrayList<>(); + } + + @Override + public void parse(String value){ + this.value = value; + + int redu = value.indexOf('{'); + this.head = value.substring(0, redu); + String buffer = value.substring(redu+1, value.length()-1); + do { + String localBuffer = ""; + for(char c : buffer.toCharArray()){ + localBuffer+=c; + if(c == Class.endVarChar){ + Variable variable = new Variable(CodeContext.CLASS); + variable.parse(localBuffer); + this.variables.add(variable); + buffer = buffer.substring(localBuffer.length()); + localBuffer = ""; + }else if(c == '{'){ + int add = 0; + int reduce = localBuffer.length(); + buffer = buffer.substring(localBuffer.length()); + for(char ch : buffer.toCharArray()){ + localBuffer+=ch; + if(ch == '{'){ + add++; + continue; + } + if(ch == '}'){ + add--; + if(add < 0){ + Loop loop = new Loop(); + loop.parse(localBuffer); + this.loops.add(loop); + buffer = buffer.substring(localBuffer.length()-reduce); + break; + } + } + } + break; + } + } + if(buffer.equals(localBuffer)) break; + }while(buffer.length() > 0); + } + + public List getLoops(){ + return this.loops; + } + + @Override + public String toString(){ + String s = head+"{\n"; + for(Variable v : this.variables){ + s+="\t\t"+v+"\n"; + } + for(Loop l : this.loops){ + s+="\t\t"+l+"\n"; + } + s+="\t}"; + return s; + } +} diff --git a/src/be/jeffcheasey88/parser/Package.java b/src/be/jeffcheasey88/parser/Package.java new file mode 100644 index 0000000..f7adf4a --- /dev/null +++ b/src/be/jeffcheasey88/parser/Package.java @@ -0,0 +1,26 @@ +package be.jeffcheasey88.parser; + +import java.io.BufferedReader; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Package { + + private static Pattern pattern = Pattern.compile("^package\\s+(.*)\\s*;$"); + + private String name; + + public Package(){} + + public void parse(BufferedReader reader) throws Exception { + String line = reader.readLine(); + Matcher matcher = pattern.matcher(line); + matcher.matches(); + this.name = matcher.group(1); + } + + public String getName(){ + return this.name; + } + +} diff --git a/src/be/jeffcheasey88/parser/Variable.java b/src/be/jeffcheasey88/parser/Variable.java new file mode 100644 index 0000000..fe7c2f7 --- /dev/null +++ b/src/be/jeffcheasey88/parser/Variable.java @@ -0,0 +1,21 @@ +package be.jeffcheasey88.parser; + +public class Variable extends Executable{ + + private String line; + + public Variable(CodeContext context) { + super(context); + } + + @Override + public void parse(String value){ + this.line = value; + } + + @Override + public String toString(){ + return line; + } + +} diff --git a/test/be/jeffcheasey88/parser/JavaParserTest.java b/test/be/jeffcheasey88/parser/JavaParserTest.java new file mode 100644 index 0000000..84e8b71 --- /dev/null +++ b/test/be/jeffcheasey88/parser/JavaParserTest.java @@ -0,0 +1,49 @@ +package be.jeffcheasey88.parser; + +import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.util.List; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; + +@TestInstance(Lifecycle.PER_CLASS) +class JavaParserTest { + + private JavaParser parser; + + @BeforeAll + void init() throws Exception { + File file = new File("C:\\Users\\jeffc\\eclipse-workspace\\JavaBenjaminCompiler\\src\\be\\jeffcheasey88\\parser\\JavaParser.java"); + BufferedReader reader = new BufferedReader(new FileReader(file)); + + parser = new JavaParser(reader); + parser.parse(); + } + + @Test + void checkPackage(){ + Package pack = parser.getPackage(); + + assertEquals(pack.getName(), "be.jeffcheasey88.parser"); + } + + @Test + void checkImports(){ + List imports = parser.getImports(); + assertTrue(imports.size() > 0); + } + + @Test + void checkClazz(){ + Class clazz = parser.getClazz(); + + assertEquals(clazz.getName(), "JavaParser"); + } +}