From 5a28d88f6a8beb4846833eb4260c087bf6dd876e Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Fri, 31 May 2024 09:58:07 +0200 Subject: [PATCH 01/14] comments --- src/main/java/Main.java | 15 +++++---------- src/main/test/java/EmptyClassExample.class | Bin 92 -> 0 bytes src/main/test/java/Tester.java | 4 ++-- 3 files changed, 7 insertions(+), 12 deletions(-) delete mode 100644 src/main/test/java/EmptyClassExample.class diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 24f129b..d865749 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -29,7 +29,7 @@ public class Main { static void parsefile(CharStream codeCharStream) { - /* ------------------------- Scanner -> tokens ------------------------- */ + /*------------------------- Scanner -> tokens -------------------------*/ SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream); CommonTokenStream tokenStream = new CommonTokenStream(lexer); @@ -46,7 +46,7 @@ public class Main { } System.out.println(); - /* ------------------------- Parser -> Parsetree ------------------------- */ + /*------------------------- Parser -> Parsetree -------------------------*/ SimpleJavaParser parser = new SimpleJavaParser(tokenStream); ParseTree parseTree = parser.program(); // parse the input @@ -56,7 +56,7 @@ public class Main { printTree(parseTree, parser, 0); System.out.println(); - /* ------------------------- AST builder -> AST ------------------------- */ + /*------------------------- AST builder -> AST -------------------------*/ ASTBuilder astBuilder = new ASTBuilder(); ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree); @@ -66,19 +66,14 @@ public class Main { printAST(abstractSyntaxTree, 0); System.out.println(); - /* - * ------------------------- Semantic Analyzer -> Tast ------------------------- - */ + /*------------------------- Semantic Analyzer -> Tast -------------------------*/ SemanticAnalyzer.generateTast(abstractSyntaxTree); ProgramNode typedAst = (ProgramNode) SemanticAnalyzer.generateTast(abstractSyntaxTree); // Printing the Tast System.out.println("Tast generated"); - /* - * ------------------------- Bytecode Generator -> Bytecode - * ------------------------- - */ + /*------------------------- Bytecode Generator -> Bytecode -------------------------*/ ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(); //byteCodeGenerator.generateByteCode(abstractSyntaxTree); byteCodeGenerator.visit(typedAst); diff --git a/src/main/test/java/EmptyClassExample.class b/src/main/test/java/EmptyClassExample.class deleted file mode 100644 index 7a73bad66b1cc2283850e64b17c439c901c27cc4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 92 zcmX^0Z`VEs1_l!bc18w4*W7}VO6Q!!;$qi|#N2|MRCWeNMh1bb#Ii*FoW#6zegCAa r)Z`L&24+SEHk-`6%o00B24)S-Fa|~jCI%LuISfD+BLgb~8;A)2qAL?` diff --git a/src/main/test/java/Tester.java b/src/main/test/java/Tester.java index 777c50b..498db7e 100644 --- a/src/main/test/java/Tester.java +++ b/src/main/test/java/Tester.java @@ -5,7 +5,7 @@ public class Tester { } } // java -jar pfadtocompiler.jar EmptyClass.java -//mit bash scipt ode rmakefile test automatisieren -//mvn package +// mit bash scipt ode rmakefile test automatisieren +// mvn package // javac tester // tester compilen // java tester // tester ausführen \ No newline at end of file -- 2.34.1 From a0e55d7b27bac1002fd030f6b071faa5326e80bb Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Fri, 31 May 2024 10:00:46 +0200 Subject: [PATCH 02/14] first testrun of the day --- src/main/test/java/MainTest.java | 2 +- src/main/test/resources/CompilerInput.txt | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/main/test/resources/CompilerInput.txt diff --git a/src/main/test/java/MainTest.java b/src/main/test/java/MainTest.java index f9e848e..516ab6e 100644 --- a/src/main/test/java/MainTest.java +++ b/src/main/test/java/MainTest.java @@ -21,7 +21,7 @@ public class MainTest { void testEmptyClass() { CharStream codeCharStream = null; try { - codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/EmptyClassExample.java")); + codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/CompilerInput.txt")); Main.parsefile(codeCharStream); } catch (IOException e) { System.err.println("Error reading the file: " + e.getMessage()); diff --git a/src/main/test/resources/CompilerInput.txt b/src/main/test/resources/CompilerInput.txt new file mode 100644 index 0000000..918c686 --- /dev/null +++ b/src/main/test/resources/CompilerInput.txt @@ -0,0 +1,13 @@ +public class Example { + + public int testVar; + + public static int testMethod(char b){ + + int a; + int a; + + + } + +} \ No newline at end of file -- 2.34.1 From 2a20a91d35e1fe856c13eb406c37dcb2bb573a1b Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Fri, 31 May 2024 10:55:41 +0200 Subject: [PATCH 03/14] Refactor structure and more --- src/main/java/Main.java | 54 +++++++++--------- src/main/java/classFileOutput/Example.class | Bin 167 -> 0 bytes src/main/java/classFileOutput/Test.class | Bin 97 -> 0 bytes src/main/test/java/Tester.java | 11 ---- .../test/java/EmptyClassExample.java | 0 src/{main => test/java}/test/TestSpecs.md | 0 .../java}/test/java/FailureTest.java | 0 .../java}/test/java/MainTest.java | 4 +- src/test/java/test/java/Tester.java | 19 ++++++ src/{main => test/java}/test/java/make.md | 0 .../java}/semantic/SemanticTest.java | 0 .../resources/AllFeaturesClassExample.java | 0 .../test/resources/CombinedExample.java | 0 .../resources/CompilerInput.java} | 0 .../resources/MoreFeaturesClassExample.java | 0 .../resources/failureTests/TestClass1.java | 0 .../resources/failureTests/TestClass10.java | 0 .../resources/failureTests/TestClass11.java | 0 .../resources/failureTests/TestClass2.java | 0 .../resources/failureTests/TestClass3.java | 0 .../resources/failureTests/TestClass4.java | 0 .../resources/failureTests/TestClass5.java | 0 .../resources/failureTests/TestClass6.java | 0 .../resources/failureTests/TestClass7.java | 0 .../resources/failureTests/TestClass8.java | 0 .../resources/failureTests/TestClass9.java | 0 .../featureTests/BooleanOperations.java | 0 .../featureTests/CharManipulation.java | 0 .../featureTests/ConditionalStatements.java | 0 .../resources/featureTests/LoopExamples.java | 0 .../featureTests/MethodOverloading.java | 0 31 files changed, 47 insertions(+), 41 deletions(-) delete mode 100644 src/main/java/classFileOutput/Example.class delete mode 100644 src/main/java/classFileOutput/Test.class delete mode 100644 src/main/test/java/Tester.java rename src/{main => }/test/java/EmptyClassExample.java (100%) rename src/{main => test/java}/test/TestSpecs.md (100%) rename src/{main => test/java}/test/java/FailureTest.java (100%) rename src/{main => test/java}/test/java/MainTest.java (89%) create mode 100644 src/test/java/test/java/Tester.java rename src/{main => test/java}/test/java/make.md (100%) rename src/test/java/{ => test/java}/semantic/SemanticTest.java (100%) rename src/{main => }/test/resources/AllFeaturesClassExample.java (100%) rename src/{main => }/test/resources/CombinedExample.java (100%) rename src/{main/test/resources/CompilerInput.txt => test/resources/CompilerInput.java} (100%) rename src/{main => }/test/resources/MoreFeaturesClassExample.java (100%) rename src/{main => }/test/resources/failureTests/TestClass1.java (100%) rename src/{main => }/test/resources/failureTests/TestClass10.java (100%) rename src/{main => }/test/resources/failureTests/TestClass11.java (100%) rename src/{main => }/test/resources/failureTests/TestClass2.java (100%) rename src/{main => }/test/resources/failureTests/TestClass3.java (100%) rename src/{main => }/test/resources/failureTests/TestClass4.java (100%) rename src/{main => }/test/resources/failureTests/TestClass5.java (100%) rename src/{main => }/test/resources/failureTests/TestClass6.java (100%) rename src/{main => }/test/resources/failureTests/TestClass7.java (100%) rename src/{main => }/test/resources/failureTests/TestClass8.java (100%) rename src/{main => }/test/resources/failureTests/TestClass9.java (100%) rename src/{main => }/test/resources/featureTests/BooleanOperations.java (100%) rename src/{main => }/test/resources/featureTests/CharManipulation.java (100%) rename src/{main => }/test/resources/featureTests/ConditionalStatements.java (100%) rename src/{main => }/test/resources/featureTests/LoopExamples.java (100%) rename src/{main => }/test/resources/featureTests/MethodOverloading.java (100%) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 8508ccc..a1d1f19 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -37,57 +37,55 @@ public class Main { CommonTokenStream tokenStream = new CommonTokenStream(lexer); // Printing the tokens - // tokenStream.fill(); - // List tokens = tokenStream.getTokens(); - // System.out.println("-------------------- Scanner -> tokens - // --------------------"); - // for (Token token : tokens) { - // String tokenType = - // SimpleJavaLexer.VOCABULARY.getSymbolicName(token.getType()); - // String tokenText = token.getText(); - // // System.out.println("Token Type: " + tokenType + ", Token Text: " + - // // tokenText); - // System.out.println(tokenType + " " + tokenText); - // } - // System.out.println(); + tokenStream.fill(); + List tokens = tokenStream.getTokens(); + System.out.println("-------------------- Scanner -> tokens --------------------"); + for (Token token : tokens) { + String tokenType = + SimpleJavaLexer.VOCABULARY.getSymbolicName(token.getType()); + String tokenText = token.getText(); + // System.out.println("Token Type: " + tokenType + ", Token Text: " + + // tokenText); + System.out.println(tokenType + " " + tokenText); + } + System.out.println(); /*------------------------- Parser -> Parsetree -------------------------*/ SimpleJavaParser parser = new SimpleJavaParser(tokenStream); ParseTree parseTree = parser.program(); // parse the input // Printing the parse tree - // System.out.println("-------------------- Parser -> Parsetree - // --------------------"); - // System.out.println(parseTree.toStringTree(parser)); - // printTree(parseTree, parser, 0); - // System.out.println(); + System.out.println("-------------------- Parser -> Parsetree --------------------"); + System.out.println(parseTree.toStringTree(parser)); + printTree(parseTree, parser, 0); + System.out.println(); /*------------------------- AST builder -> AST -------------------------*/ ASTBuilder astBuilder = new ASTBuilder(); ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree); // Printing the AST - // System.out.println("-------------------- AST builder -> AST - // --------------------"); - // // System.out.println("AST: " + ast.toString()); - // printAST(abstractSyntaxTree, 0); - // System.out.println(); + System.out.println("-------------------- AST builder -> AST --------------------"); + // System.out.println("AST: " + ast.toString()); + printAST(abstractSyntaxTree, 0); + System.out.println(); - /*------------------------- Semantic Analyzer -> Tast -------------------------*/ - SemanticAnalyzer.generateTast(abstractSyntaxTree); + /*------------------------- Semantic Analyzer -> typed AST -------------------------*/ ProgramNode typedAst = (ProgramNode) SemanticAnalyzer.generateTast(abstractSyntaxTree); - // Printing the Tast - System.out.println("Tast generated"); + // Printing the typed AST + System.out.println("-------------------- Semantic Analyzer -> typed AST --------------------"); + printAST(typedAst, 0); + System.out.println(); /*------------------------- Bytecode Generator -> Bytecode -------------------------*/ ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(); - // byteCodeGenerator.generateByteCode(abstractSyntaxTree); byteCodeGenerator.visit(typedAst); System.out.println("Bytecode generated"); } + /** * This method is used to print the parse tree in a structured format. * It recursively traverses the tree and prints the rule names and text of the diff --git a/src/main/java/classFileOutput/Example.class b/src/main/java/classFileOutput/Example.class deleted file mode 100644 index 522ae9edd25429b756d2dd98d755bdedb11f81c3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167 zcmW-Z%?`m(5QV>?KU4{C(b_cjVj~t^h@Jh#4Q;BGxDl^qC9&`T9!g9t=FB(eoXqF@ zdIK{?Lb$q{^QE#OB8*FOGg)QoW476qcJD&ELNG7t!Yzbul5S&sf(VaL5Tla|k+WB~ uw(is%1V731R84Q$94tadyXY4BL`oeceW5zkYw}OPpFZh5)M%>%;ue1AIvEN8 diff --git a/src/main/java/classFileOutput/Test.class b/src/main/java/classFileOutput/Test.class deleted file mode 100644 index 8ba4c23343d79136e322bf6f22591360f6985b92..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 97 zcmX^0Z`VEs1_l!bPDTcnkksN5b_Pa927#=^vPAuy#JqHU|D>$cWS}TBBLkaFW?p8A m9U}v?hGrO0c?nQCBTzFV0}}%am}X>PXW)RcSQ*%WECv8I3=j$c diff --git a/src/main/test/java/Tester.java b/src/main/test/java/Tester.java deleted file mode 100644 index 498db7e..0000000 --- a/src/main/test/java/Tester.java +++ /dev/null @@ -1,11 +0,0 @@ -public class Tester { - public static void main(String[] args) { - new EmptyClassExample(); - // cp mitgeben - } -} -// java -jar pfadtocompiler.jar EmptyClass.java -// mit bash scipt ode rmakefile test automatisieren -// mvn package -// javac tester // tester compilen -// java tester // tester ausführen \ No newline at end of file diff --git a/src/main/test/java/EmptyClassExample.java b/src/test/java/EmptyClassExample.java similarity index 100% rename from src/main/test/java/EmptyClassExample.java rename to src/test/java/EmptyClassExample.java diff --git a/src/main/test/TestSpecs.md b/src/test/java/test/TestSpecs.md similarity index 100% rename from src/main/test/TestSpecs.md rename to src/test/java/test/TestSpecs.md diff --git a/src/main/test/java/FailureTest.java b/src/test/java/test/java/FailureTest.java similarity index 100% rename from src/main/test/java/FailureTest.java rename to src/test/java/test/java/FailureTest.java diff --git a/src/main/test/java/MainTest.java b/src/test/java/test/java/MainTest.java similarity index 89% rename from src/main/test/java/MainTest.java rename to src/test/java/test/java/MainTest.java index 516ab6e..9e03dc7 100644 --- a/src/main/test/java/MainTest.java +++ b/src/test/java/test/java/MainTest.java @@ -21,8 +21,8 @@ public class MainTest { void testEmptyClass() { CharStream codeCharStream = null; try { - codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/CompilerInput.txt")); - Main.parsefile(codeCharStream); + codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/CompilerInput.java")); + Main.parseFile(codeCharStream); } catch (IOException e) { System.err.println("Error reading the file: " + e.getMessage()); } diff --git a/src/test/java/test/java/Tester.java b/src/test/java/test/java/Tester.java new file mode 100644 index 0000000..8890547 --- /dev/null +++ b/src/test/java/test/java/Tester.java @@ -0,0 +1,19 @@ +public class Tester { + public static void main(String[] args) { + // für E2E Tests: + // Testdatei mit Main ausführen/kompilieren + // Testdatei mit "javac CompilerInput.java" kompilieren + + // wenn beides erfolgreich + // Ergebnis vom eigenen Compiler mit "java myOutput" ausführen + // Ergebnis von javac mit "java CompilerInput" ausführen + + + } +} +// cp mitgeben +// java -jar pfadtocompiler.jar EmptyClass.java +// mit bash scipt ode rmakefile test automatisieren +// mvn package +// javac tester // tester compilen +// java tester // tester ausführen \ No newline at end of file diff --git a/src/main/test/java/make.md b/src/test/java/test/java/make.md similarity index 100% rename from src/main/test/java/make.md rename to src/test/java/test/java/make.md diff --git a/src/test/java/semantic/SemanticTest.java b/src/test/java/test/java/semantic/SemanticTest.java similarity index 100% rename from src/test/java/semantic/SemanticTest.java rename to src/test/java/test/java/semantic/SemanticTest.java diff --git a/src/main/test/resources/AllFeaturesClassExample.java b/src/test/resources/AllFeaturesClassExample.java similarity index 100% rename from src/main/test/resources/AllFeaturesClassExample.java rename to src/test/resources/AllFeaturesClassExample.java diff --git a/src/main/test/resources/CombinedExample.java b/src/test/resources/CombinedExample.java similarity index 100% rename from src/main/test/resources/CombinedExample.java rename to src/test/resources/CombinedExample.java diff --git a/src/main/test/resources/CompilerInput.txt b/src/test/resources/CompilerInput.java similarity index 100% rename from src/main/test/resources/CompilerInput.txt rename to src/test/resources/CompilerInput.java diff --git a/src/main/test/resources/MoreFeaturesClassExample.java b/src/test/resources/MoreFeaturesClassExample.java similarity index 100% rename from src/main/test/resources/MoreFeaturesClassExample.java rename to src/test/resources/MoreFeaturesClassExample.java diff --git a/src/main/test/resources/failureTests/TestClass1.java b/src/test/resources/failureTests/TestClass1.java similarity index 100% rename from src/main/test/resources/failureTests/TestClass1.java rename to src/test/resources/failureTests/TestClass1.java diff --git a/src/main/test/resources/failureTests/TestClass10.java b/src/test/resources/failureTests/TestClass10.java similarity index 100% rename from src/main/test/resources/failureTests/TestClass10.java rename to src/test/resources/failureTests/TestClass10.java diff --git a/src/main/test/resources/failureTests/TestClass11.java b/src/test/resources/failureTests/TestClass11.java similarity index 100% rename from src/main/test/resources/failureTests/TestClass11.java rename to src/test/resources/failureTests/TestClass11.java diff --git a/src/main/test/resources/failureTests/TestClass2.java b/src/test/resources/failureTests/TestClass2.java similarity index 100% rename from src/main/test/resources/failureTests/TestClass2.java rename to src/test/resources/failureTests/TestClass2.java diff --git a/src/main/test/resources/failureTests/TestClass3.java b/src/test/resources/failureTests/TestClass3.java similarity index 100% rename from src/main/test/resources/failureTests/TestClass3.java rename to src/test/resources/failureTests/TestClass3.java diff --git a/src/main/test/resources/failureTests/TestClass4.java b/src/test/resources/failureTests/TestClass4.java similarity index 100% rename from src/main/test/resources/failureTests/TestClass4.java rename to src/test/resources/failureTests/TestClass4.java diff --git a/src/main/test/resources/failureTests/TestClass5.java b/src/test/resources/failureTests/TestClass5.java similarity index 100% rename from src/main/test/resources/failureTests/TestClass5.java rename to src/test/resources/failureTests/TestClass5.java diff --git a/src/main/test/resources/failureTests/TestClass6.java b/src/test/resources/failureTests/TestClass6.java similarity index 100% rename from src/main/test/resources/failureTests/TestClass6.java rename to src/test/resources/failureTests/TestClass6.java diff --git a/src/main/test/resources/failureTests/TestClass7.java b/src/test/resources/failureTests/TestClass7.java similarity index 100% rename from src/main/test/resources/failureTests/TestClass7.java rename to src/test/resources/failureTests/TestClass7.java diff --git a/src/main/test/resources/failureTests/TestClass8.java b/src/test/resources/failureTests/TestClass8.java similarity index 100% rename from src/main/test/resources/failureTests/TestClass8.java rename to src/test/resources/failureTests/TestClass8.java diff --git a/src/main/test/resources/failureTests/TestClass9.java b/src/test/resources/failureTests/TestClass9.java similarity index 100% rename from src/main/test/resources/failureTests/TestClass9.java rename to src/test/resources/failureTests/TestClass9.java diff --git a/src/main/test/resources/featureTests/BooleanOperations.java b/src/test/resources/featureTests/BooleanOperations.java similarity index 100% rename from src/main/test/resources/featureTests/BooleanOperations.java rename to src/test/resources/featureTests/BooleanOperations.java diff --git a/src/main/test/resources/featureTests/CharManipulation.java b/src/test/resources/featureTests/CharManipulation.java similarity index 100% rename from src/main/test/resources/featureTests/CharManipulation.java rename to src/test/resources/featureTests/CharManipulation.java diff --git a/src/main/test/resources/featureTests/ConditionalStatements.java b/src/test/resources/featureTests/ConditionalStatements.java similarity index 100% rename from src/main/test/resources/featureTests/ConditionalStatements.java rename to src/test/resources/featureTests/ConditionalStatements.java diff --git a/src/main/test/resources/featureTests/LoopExamples.java b/src/test/resources/featureTests/LoopExamples.java similarity index 100% rename from src/main/test/resources/featureTests/LoopExamples.java rename to src/test/resources/featureTests/LoopExamples.java diff --git a/src/main/test/resources/featureTests/MethodOverloading.java b/src/test/resources/featureTests/MethodOverloading.java similarity index 100% rename from src/main/test/resources/featureTests/MethodOverloading.java rename to src/test/resources/featureTests/MethodOverloading.java -- 2.34.1 From 1132ff015ceac848e350756517b7441a6ab33243 Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Fri, 31 May 2024 11:05:45 +0200 Subject: [PATCH 04/14] Changes in tests --- src/main/java/Main.java | 4 + src/test/java/test/java/FailureTest.java | 2 +- .../java/test/java/semantic/SemanticTest.java | 88 ++++++++++++------- 3 files changed, 60 insertions(+), 34 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index a1d1f19..c78f3ea 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -120,6 +120,10 @@ public class Main { } public static void printAST(ASTNode node, int indent) { + if (node == null) { + System.out.println("null"); + return; + } String indentString = " ".repeat(indent * 2); System.out.println(indentString + node.getClass().toString()); diff --git a/src/test/java/test/java/FailureTest.java b/src/test/java/test/java/FailureTest.java index bc63d91..366ce56 100644 --- a/src/test/java/test/java/FailureTest.java +++ b/src/test/java/test/java/FailureTest.java @@ -63,7 +63,7 @@ public class FailureTest { CharStream codeCharStream = null; try { codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/EmptyClassExample.java")); - Main.parsefile(codeCharStream); + Main.parseFile(codeCharStream); } catch (IOException e) { System.err.println("Error reading the file: " + e.getMessage()); } diff --git a/src/test/java/test/java/semantic/SemanticTest.java b/src/test/java/test/java/semantic/SemanticTest.java index 83287ca..c55e19d 100644 --- a/src/test/java/test/java/semantic/SemanticTest.java +++ b/src/test/java/test/java/semantic/SemanticTest.java @@ -1,6 +1,5 @@ package semantic; - import ast.*; import ast.expression.BinaryExpressionNode; import ast.expression.ExpressionNode; @@ -20,11 +19,10 @@ import ast.type.EnumTypeNode; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import semantic.exeptions.AlreadyDeclearedException; - import java.util.ArrayList; import java.util.List; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.*; public class SemanticTest { @@ -34,10 +32,9 @@ public class SemanticTest { } @Test - public void alreadyDeclaredLocalFieldVar(){ - + public void alreadyDeclaredLocalFieldVar() { ProgramNode programNode = new ProgramNode(); - List classList = new ArrayList(); + List classList = new ArrayList<>(); AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC); ClassNode classNode = new ClassNode(accessTypeNode, "testClass"); @@ -53,16 +50,14 @@ public class SemanticTest { ASTNode typedAst = SemanticAnalyzer.generateTast(programNode); assertEquals(1, SemanticAnalyzer.errors.size()); - assertEquals(true, SemanticAnalyzer.errors.get(0) instanceof AlreadyDeclearedException); - assertEquals(null, typedAst); - + assertInstanceOf(AlreadyDeclearedException.class, SemanticAnalyzer.errors.getFirst()); + assertNull(typedAst); } @Test - public void shouldWorkWithNoError(){ - + public void shouldWorkWithNoError() { ProgramNode programNode = new ProgramNode(); - List classList = new ArrayList(); + List classList = new ArrayList<>(); AccessTypeNode accessTypeNode = new AccessTypeNode(EnumAccessTypeNode.PUBLIC); ClassNode classNode = new ClassNode(accessTypeNode, "testClass"); @@ -72,26 +67,7 @@ public class SemanticTest { MemberNode memberNode2 = new FieldNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2"); classNode.members.add(memberNode2); - List parameterNodeList = new ArrayList(); - ParameterNode parameterNode1 = new ParameterNode(new BaseTypeNode(EnumTypeNode.INT), "param1"); - parameterNodeList.add(parameterNode1); - ParameterListNode parameterListNode = new ParameterListNode(parameterNodeList); - - List statementNodeList = new ArrayList(); - - ExpressionNode expressionNodeObjectVariableLeft = new IdentifierExpressionNode("this"); - ExpressionNode expressionNodeObjectVariableRight = new IdentifierExpressionNode("objectVar"); - - ExpressionNode expressionNodeLeft = new BinaryExpressionNode(expressionNodeObjectVariableLeft, expressionNodeObjectVariableRight, ExpresssionOperator.DOT); - - ExpressionNode expressionNodeRight = new LiteralNode(1); - - BinaryExpressionNode expressionNode = new BinaryExpressionNode(expressionNodeLeft, expressionNodeRight, ExpresssionOperator.ASSIGNMENT); - - StatementNode statementNode1 = new AssignmentStatementNode(expressionNode); - statementNodeList.add(statementNode1); - - MemberNode memberNode3 = new MethodNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2",parameterListNode, statementNodeList ); + MemberNode memberNode3 = getMemberNode(accessTypeNode); classNode.members.add(memberNode3); classList.add(classNode); @@ -101,7 +77,53 @@ public class SemanticTest { assertEquals(0, SemanticAnalyzer.errors.size()); assertEquals(programNode, typedAst); - } + /** + * This method is used to create a MemberNode representing a method. + * It first creates a list of ParameterNodes and adds a ParameterNode to it. + * Then, it creates a ParameterListNode using the list of ParameterNodes. + * After that, it creates a list of StatementNodes and adds a StatementNode to it by calling the getStatementNode method. + * Finally, it creates a MethodNode using the provided AccessTypeNode, a BaseTypeNode representing the return type of the method, + * the method name, the ParameterListNode, and the list of StatementNodes, and returns this MethodNode. + * + * @param accessTypeNode The AccessTypeNode representing the access type of the method. + * @return The created MemberNode representing the method. + */ +private static MemberNode getMemberNode(AccessTypeNode accessTypeNode) { + List parameterNodeList = new ArrayList<>(); + ParameterNode parameterNode1 = new ParameterNode(new BaseTypeNode(EnumTypeNode.INT), "param1"); + parameterNodeList.add(parameterNode1); + ParameterListNode parameterListNode = new ParameterListNode(parameterNodeList); + + List statementNodeList = new ArrayList<>(); + + StatementNode statementNode1 = getStatementNode(); + statementNodeList.add(statementNode1); + + return new MethodNode(accessTypeNode, new BaseTypeNode(EnumTypeNode.INT), "testVar2", parameterListNode, statementNodeList); +} + + /** + * This method is used to create a StatementNode for an assignment operation. + * It first creates two IdentifierExpressionNodes for 'this' and 'objectVar'. + * Then, it creates a BinaryExpressionNode to represent the operation 'this.objectVar'. + * After that, it creates a LiteralNode to represent the integer value 1. + * Finally, it creates another BinaryExpressionNode to represent the assignment operation 'this.objectVar = 1', + * and wraps this expression in an AssignmentStatementNode. + * + * @return The created AssignmentStatementNode representing the assignment operation 'this.objectVar = 1'. + */ +private static StatementNode getStatementNode() { + ExpressionNode expressionNodeObjectVariableLeft = new IdentifierExpressionNode("this"); + ExpressionNode expressionNodeObjectVariableRight = new IdentifierExpressionNode("objectVar"); + + ExpressionNode expressionNodeLeft = new BinaryExpressionNode(expressionNodeObjectVariableLeft, expressionNodeObjectVariableRight, ExpresssionOperator.DOT); + + ExpressionNode expressionNodeRight = new LiteralNode(1); + + BinaryExpressionNode expressionNode = new BinaryExpressionNode(expressionNodeLeft, expressionNodeRight, ExpresssionOperator.ASSIGNMENT); + + return new AssignmentStatementNode(expressionNode); +} } -- 2.34.1 From 9f40949f5aa6689b1eb5495ef4debf2ba3102b23 Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Fri, 31 May 2024 11:20:31 +0200 Subject: [PATCH 05/14] Structure --- src/test/{java/test => }/TestSpecs.md | 10 +++++++++- .../java/{test/java => }/FailureTest.java | 0 src/test/java/{test/java => }/MainTest.java | 6 ------ src/test/java/Tester.java | 12 ++++++++++++ src/test/java/{test/java => }/make.md | 0 .../java => }/semantic/SemanticTest.java | 0 src/test/java/test/java/Tester.java | 19 ------------------- 7 files changed, 21 insertions(+), 26 deletions(-) rename src/test/{java/test => }/TestSpecs.md (87%) rename src/test/java/{test/java => }/FailureTest.java (100%) rename src/test/java/{test/java => }/MainTest.java (76%) create mode 100644 src/test/java/Tester.java rename src/test/java/{test/java => }/make.md (100%) rename src/test/java/{test/java => }/semantic/SemanticTest.java (100%) delete mode 100644 src/test/java/test/java/Tester.java diff --git a/src/test/java/test/TestSpecs.md b/src/test/TestSpecs.md similarity index 87% rename from src/test/java/test/TestSpecs.md rename to src/test/TestSpecs.md index 6fd5a41..7ae3416 100644 --- a/src/test/java/test/TestSpecs.md +++ b/src/test/TestSpecs.md @@ -75,4 +75,12 @@ Compiled Classfile ### Beispiel 2: Filled Class - \ No newline at end of file + + + für E2E Tests: + Testdatei mit Main ausführen/kompilieren + Testdatei mit "javac CompilerInput.java" kompilieren + + wenn beides erfolgreich + Ergebnis vom eigenen Compiler mit "java myOutput" ausführen + Ergebnis von javac mit "java CompilerInput" ausführen diff --git a/src/test/java/test/java/FailureTest.java b/src/test/java/FailureTest.java similarity index 100% rename from src/test/java/test/java/FailureTest.java rename to src/test/java/FailureTest.java diff --git a/src/test/java/test/java/MainTest.java b/src/test/java/MainTest.java similarity index 76% rename from src/test/java/test/java/MainTest.java rename to src/test/java/MainTest.java index 9e03dc7..a8c3a93 100644 --- a/src/test/java/test/java/MainTest.java +++ b/src/test/java/MainTest.java @@ -1,12 +1,6 @@ import org.junit.jupiter.api.Test; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.tree.ParseTree; -import parser.ASTBuilder; -import ast.ClassNode; -import ast.ProgramNode; -import bytecode.ByteCodeGenerator; import java.io.IOException; import java.nio.file.Paths; diff --git a/src/test/java/Tester.java b/src/test/java/Tester.java new file mode 100644 index 0000000..2c62e40 --- /dev/null +++ b/src/test/java/Tester.java @@ -0,0 +1,12 @@ +public class Tester { + public static void main(String[] args) { + + + } +} +// cp mitgeben +// java -jar pfadtocompiler.jar EmptyClass.java +// mit bash scipt ode rmakefile test automatisieren +// mvn package +// javac tester // tester compilen +// java tester // tester ausführen \ No newline at end of file diff --git a/src/test/java/test/java/make.md b/src/test/java/make.md similarity index 100% rename from src/test/java/test/java/make.md rename to src/test/java/make.md diff --git a/src/test/java/test/java/semantic/SemanticTest.java b/src/test/java/semantic/SemanticTest.java similarity index 100% rename from src/test/java/test/java/semantic/SemanticTest.java rename to src/test/java/semantic/SemanticTest.java diff --git a/src/test/java/test/java/Tester.java b/src/test/java/test/java/Tester.java deleted file mode 100644 index 8890547..0000000 --- a/src/test/java/test/java/Tester.java +++ /dev/null @@ -1,19 +0,0 @@ -public class Tester { - public static void main(String[] args) { - // für E2E Tests: - // Testdatei mit Main ausführen/kompilieren - // Testdatei mit "javac CompilerInput.java" kompilieren - - // wenn beides erfolgreich - // Ergebnis vom eigenen Compiler mit "java myOutput" ausführen - // Ergebnis von javac mit "java CompilerInput" ausführen - - - } -} -// cp mitgeben -// java -jar pfadtocompiler.jar EmptyClass.java -// mit bash scipt ode rmakefile test automatisieren -// mvn package -// javac tester // tester compilen -// java tester // tester ausführen \ No newline at end of file -- 2.34.1 From 8d6190b1304e82b3a3625f3d18dc475aea452ebe Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Fri, 31 May 2024 17:09:04 +0200 Subject: [PATCH 06/14] Structure, Makefile, Docs, TestCompilerOutput, more; TODO: fix marked Problems in Makefile; fix Compiler (look at TestCompilerOutput docs) --- .../antlr-4.12.0-complete.jar | Bin pom.xml | 4 +- src/main/java/Main.java | 12 ++--- src/main/java/bytecode/ClassCodeGen.java | 2 +- src/main/resources/CompilerInput.java | 18 +++---- src/test/Makefile | 24 +++++++++ src/test/TestSpecs.md | 51 +++++++++++------- src/test/java/TestCompilerOutput.java | 41 ++++++++++++++ src/test/java/Tester.java | 12 ----- src/test/java/make.md | 0 src/test/resources/CompilerInput.java | 14 ++--- 11 files changed, 117 insertions(+), 61 deletions(-) rename antlr-4.12.0-complete.jar => .lib/antlr-4.12.0-complete.jar (100%) create mode 100644 src/test/Makefile create mode 100644 src/test/java/TestCompilerOutput.java delete mode 100644 src/test/java/Tester.java delete mode 100644 src/test/java/make.md diff --git a/antlr-4.12.0-complete.jar b/.lib/antlr-4.12.0-complete.jar similarity index 100% rename from antlr-4.12.0-complete.jar rename to .lib/antlr-4.12.0-complete.jar diff --git a/pom.xml b/pom.xml index 9ee63e3..a11bfc7 100644 --- a/pom.xml +++ b/pom.xml @@ -9,8 +9,8 @@ 1.0-SNAPSHOT - 21 - 21 + 22 + 22 UTF-8 diff --git a/src/main/java/Main.java b/src/main/java/Main.java index c78f3ea..acea692 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,18 +1,14 @@ import ast.ASTNode; -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.Token; import ast.ProgramNode; -import bytecode.ByteCodeGenerator; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.CommonTokenStream; import parser.ASTBuilder; import parser.generated.SimpleJavaLexer; import parser.generated.SimpleJavaParser; import semantic.SemanticAnalyzer; import bytecode.ByteCodeGenerator; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.tree.ParseTree; + import java.io.IOException; import java.nio.file.Paths; import java.util.List; @@ -20,7 +16,7 @@ import java.util.List; public class Main { public static void main(String[] args) throws Exception { if (args.length > 0) { - + System.out.println("Main file has args: " + args[0]); } else { try { CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/CompilerInput.java")); diff --git a/src/main/java/bytecode/ClassCodeGen.java b/src/main/java/bytecode/ClassCodeGen.java index b0afa69..6bddd61 100644 --- a/src/main/java/bytecode/ClassCodeGen.java +++ b/src/main/java/bytecode/ClassCodeGen.java @@ -52,7 +52,7 @@ public class ClassCodeGen implements ClassVisitor { } private void printIntoClassFile(byte[] byteCode, String name) { - String directoryPath = "src/main/java/classFileOutput"; + String directoryPath = "src/main/resources/classFileOutput"; File directory = new File(directoryPath); if (!directory.exists()) { directory.mkdirs(); diff --git a/src/main/resources/CompilerInput.java b/src/main/resources/CompilerInput.java index 1cbe5ca..d850a3e 100644 --- a/src/main/resources/CompilerInput.java +++ b/src/main/resources/CompilerInput.java @@ -1,18 +1,16 @@ -public class Example { +public class CompilerInput { public int a; public static int testMethod(char x){ - + return 0; } + public class Test { + + public static int testMethod(char x, int a){ + return 0; + } + } } -public class Test { - - public static int testMethod(char x, int a){ - - - - } -} \ No newline at end of file diff --git a/src/test/Makefile b/src/test/Makefile new file mode 100644 index 0000000..da39d6b --- /dev/null +++ b/src/test/Makefile @@ -0,0 +1,24 @@ +# Makefile +### IntelliJs play buttons do not work. Run in "src/test" folder with "make" command to run all +### Or run only parts with "make compile-javac", "make delete" etc. + +all: delete compile-javac compile-raupenpiler + +compile-javac: + javac -d .\resources\output\javac .\resources\CompilerInput.java + +compile-raupenpiler: +## funktioniert bisher nicht, das will die Klasse nicht laden, der traditionelle Weg findet externe Libraries (antlr) nicht, maven hat andere Probleme +## Unseren Compiler also erstmal händisch starten: main.java/Main.java + #javac -d ./resources/output/raupenpiler -cp ../main/java;../../.lib/antlr-4.12.0-complete.jar ../main/java/Main.java + #java -cp ./resources/output/raupenpiler Main + #mvn -f ../../ compile + #mvn -f ../../ exec:java -Dexec.mainClass="Main" + +delete: + rm -f ./resources/output/javac/*.class + rm -f ./resources/output/raupenpiler/*.class + rm -f ./java/*.class + rm -f ../main/resources/classFileOutput/*.class + + diff --git a/src/test/TestSpecs.md b/src/test/TestSpecs.md index 7ae3416..75f979a 100644 --- a/src/test/TestSpecs.md +++ b/src/test/TestSpecs.md @@ -1,5 +1,7 @@ # Scanner + ## Scanner Input + ### Beispiel 1: Empty Class String empty class = "public class Name {}"; @@ -15,11 +17,12 @@ "}" ## Scanner Output + ### Beispiel 1: Empty Class Token Type; Token Text Type gibts nur bei Terminalen, Text bei allen - + [null "public", null "class", IDENTIFIER "Name", null "{", null "}", EOF ""] Bsp von Ihm mal: @@ -35,52 +38,62 @@ Type gibts nur bei Terminalen, Text bei allen [TokRightBrace] # Parser -## Parser Input + +## Parser Input + (Scanner Output) ## Parser Output (AST) -### Beispiel 1: Empty Class - +### Beispiel 1: Empty Class ### Beispiel 2: Filled Class - - # Semantische Analyse / Typcheck -## Typcheck Input + +## Typcheck Input + (Parser Output = AST) ## Typcheck Output ### Beispiel 1: Empty Class - - ### Beispiel 2: Filled Class - # Bytecodegenerierung -## Bytecodegenerierung Input + +## Bytecodegenerierung Input + (Typcheck Output = vom Typcheck eventuell manipulierter AST) ## Bytecodegenerierung Output ### Beispiel 1: Empty Class + Compiled Classfile public class javaFileInput.Example { } - - ### Beispiel 2: Filled Class +## E2E Tests: - für E2E Tests: - Testdatei mit Main ausführen/kompilieren - Testdatei mit "javac CompilerInput.java" kompilieren +- Testdatei mit Main ausführen/kompilieren +- Testdatei mit "javac -d output .\CompilerInput.java" kompilieren +- -> Dateien mit javap vergleichen - wenn beides erfolgreich - Ergebnis vom eigenen Compiler mit "java myOutput" ausführen - Ergebnis von javac mit "java CompilerInput" ausführen +wenn beides erfolgreich +- Ergebnis vom eigenen Compiler mithilfe von TestCompilerOutput ausführen +- (Ergebnis von javac mithilfe von TestCompilerOutput ausführen) + + +### Andis Tipps: +- cp mitgeben +- makefile +- java -jar pfadtocompiler.jar EmptyClass.java +- mvn package +- javac tester // tester compilen +- java tester // tester ausführen +- -> tester ist in unserem Fall TestCompilerOutput.java \ No newline at end of file diff --git a/src/test/java/TestCompilerOutput.java b/src/test/java/TestCompilerOutput.java new file mode 100644 index 0000000..cf6aac0 --- /dev/null +++ b/src/test/java/TestCompilerOutput.java @@ -0,0 +1,41 @@ +/** + * This class is used to test the output of the compiler. + *

+ * Im gleichen Ordner wie die diese Datei (TestCompilerOutput.java) muss die selbstkompilierte CompilerInput.java Datei sein. + * --->>>> Diese muss man also vom Ordner classFileOutput in diesen ordner hier (test/java) rein kopieren. (bis es eine bessere Lösung gibt) <<<<--- + * Die selbstkompilierte .class Datei wird dann hier drin geladen und eine Instanz von ihr erstellt, es können auch Methoden aufgerufen werden. + * Diese TestCompilerOutput.java Datei wird dann mit "javac .\TestCompilerOutput.java" kompiliert und mit "java TestCompilerOutput" ausgeführt. + * Wenn unser Compiler funktioniert, sollten keine Errors kommen (sondern nur die Ausgaben, die wir in der CompilerInput.java Datei gemacht haben, + * oder Methoden, die wir hier aufrufen). + * PROBLEM: hier kommen errors, was eigentlich heißt, dass der Compiler nicht funktioniert, der der Test sollt eigentlich passen + */ +public class TestCompilerOutput { + + public static void main(String[] args) { + try { + // Try to load the class named "CompilerInput" + Class cls = Class.forName("CompilerInput"); + // Print a success message if the class is loaded successfully + System.out.println("Class loaded successfully: " + cls.getName()); + + // Try to create an instance of the loaded class + Object instance = cls.getDeclaredConstructor().newInstance(); + // Print a success message if the instance is created successfully + System.out.println("Instance created: " + instance); + + + // If the class has a main method, you can invoke it + // cls.getMethod("main", String[].class).invoke(null, (Object) new String[]{}); + + // If the class has other methods, you can invoke them as well + // Example: cls.getMethod("someMethod").invoke(instance); + + } catch (ClassNotFoundException e) { + // Print an error message if the class is not found + System.err.println("Class not found: " + e.getMessage()); + } catch (Exception e) { + // Print an error message if any other exception occurs during class loading or instance creation + System.err.println("Error during class loading or execution: " + e.getMessage()); + } + } +} diff --git a/src/test/java/Tester.java b/src/test/java/Tester.java deleted file mode 100644 index 2c62e40..0000000 --- a/src/test/java/Tester.java +++ /dev/null @@ -1,12 +0,0 @@ -public class Tester { - public static void main(String[] args) { - - - } -} -// cp mitgeben -// java -jar pfadtocompiler.jar EmptyClass.java -// mit bash scipt ode rmakefile test automatisieren -// mvn package -// javac tester // tester compilen -// java tester // tester ausführen \ No newline at end of file diff --git a/src/test/java/make.md b/src/test/java/make.md deleted file mode 100644 index e69de29..0000000 diff --git a/src/test/resources/CompilerInput.java b/src/test/resources/CompilerInput.java index 918c686..91b2625 100644 --- a/src/test/resources/CompilerInput.java +++ b/src/test/resources/CompilerInput.java @@ -1,13 +1,9 @@ -public class Example { - - public int testVar; - - public static int testMethod(char b){ - - int a; - int a; +public class CompilerInput { + public int a; + public static int testMethod(char x){ + return 0; } +} -} \ No newline at end of file -- 2.34.1 From 6a971345d49679620cccb13ce136c74caed8390b Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Wed, 12 Jun 2024 11:17:16 +0200 Subject: [PATCH 07/14] Structure and more --- src/main/java/Main.java | 3 +-- src/main/java/bytecode/ClassCodeGen.java | 2 +- .../resources/{ => input}/CompilerInput.java | 0 src/test/Makefile | 5 ++--- src/test/java/TestCompilerOutput.java | 18 ++++++++++-------- .../{ => input}/AllFeaturesClassExample.java | 0 .../resources/{ => input}/CombinedExample.java | 0 .../resources/{ => input}/CompilerInput.java | 7 +++++++ .../{ => input}/MoreFeaturesClassExample.java | 0 .../{ => input}/failureTests/TestClass1.java | 0 .../{ => input}/failureTests/TestClass10.java | 0 .../{ => input}/failureTests/TestClass11.java | 0 .../{ => input}/failureTests/TestClass2.java | 0 .../{ => input}/failureTests/TestClass3.java | 0 .../{ => input}/failureTests/TestClass4.java | 0 .../{ => input}/failureTests/TestClass5.java | 0 .../{ => input}/failureTests/TestClass6.java | 0 .../{ => input}/failureTests/TestClass7.java | 0 .../{ => input}/failureTests/TestClass8.java | 0 .../{ => input}/failureTests/TestClass9.java | 0 .../featureTests/BooleanOperations.java | 0 .../featureTests/CharManipulation.java | 0 .../featureTests/ConditionalStatements.java | 0 .../{ => input}/featureTests/LoopExamples.java | 0 .../featureTests/MethodOverloading.java | 0 25 files changed, 21 insertions(+), 14 deletions(-) rename src/main/resources/{ => input}/CompilerInput.java (100%) rename src/test/resources/{ => input}/AllFeaturesClassExample.java (100%) rename src/test/resources/{ => input}/CombinedExample.java (100%) rename src/test/resources/{ => input}/CompilerInput.java (50%) rename src/test/resources/{ => input}/MoreFeaturesClassExample.java (100%) rename src/test/resources/{ => input}/failureTests/TestClass1.java (100%) rename src/test/resources/{ => input}/failureTests/TestClass10.java (100%) rename src/test/resources/{ => input}/failureTests/TestClass11.java (100%) rename src/test/resources/{ => input}/failureTests/TestClass2.java (100%) rename src/test/resources/{ => input}/failureTests/TestClass3.java (100%) rename src/test/resources/{ => input}/failureTests/TestClass4.java (100%) rename src/test/resources/{ => input}/failureTests/TestClass5.java (100%) rename src/test/resources/{ => input}/failureTests/TestClass6.java (100%) rename src/test/resources/{ => input}/failureTests/TestClass7.java (100%) rename src/test/resources/{ => input}/failureTests/TestClass8.java (100%) rename src/test/resources/{ => input}/failureTests/TestClass9.java (100%) rename src/test/resources/{ => input}/featureTests/BooleanOperations.java (100%) rename src/test/resources/{ => input}/featureTests/CharManipulation.java (100%) rename src/test/resources/{ => input}/featureTests/ConditionalStatements.java (100%) rename src/test/resources/{ => input}/featureTests/LoopExamples.java (100%) rename src/test/resources/{ => input}/featureTests/MethodOverloading.java (100%) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index acea692..6f6517f 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -19,7 +19,7 @@ public class Main { System.out.println("Main file has args: " + args[0]); } else { try { - CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/CompilerInput.java")); + CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/input/CompilerInput.java")); parseFile(codeCharStream); } catch (IOException e) { System.err.println("Error reading the file: " + e.getMessage()); @@ -78,7 +78,6 @@ public class Main { ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(); byteCodeGenerator.visit(typedAst); System.out.println("Bytecode generated"); - } diff --git a/src/main/java/bytecode/ClassCodeGen.java b/src/main/java/bytecode/ClassCodeGen.java index 6bddd61..d91b17b 100644 --- a/src/main/java/bytecode/ClassCodeGen.java +++ b/src/main/java/bytecode/ClassCodeGen.java @@ -52,7 +52,7 @@ public class ClassCodeGen implements ClassVisitor { } private void printIntoClassFile(byte[] byteCode, String name) { - String directoryPath = "src/main/resources/classFileOutput"; + String directoryPath = "src/main/resources/output"; File directory = new File(directoryPath); if (!directory.exists()) { directory.mkdirs(); diff --git a/src/main/resources/CompilerInput.java b/src/main/resources/input/CompilerInput.java similarity index 100% rename from src/main/resources/CompilerInput.java rename to src/main/resources/input/CompilerInput.java diff --git a/src/test/Makefile b/src/test/Makefile index da39d6b..68b9dd2 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -5,7 +5,7 @@ all: delete compile-javac compile-raupenpiler compile-javac: - javac -d .\resources\output\javac .\resources\CompilerInput.java + javac -d .\resources\output\javac .\resources\input\CompilerInput.java compile-raupenpiler: ## funktioniert bisher nicht, das will die Klasse nicht laden, der traditionelle Weg findet externe Libraries (antlr) nicht, maven hat andere Probleme @@ -19,6 +19,5 @@ delete: rm -f ./resources/output/javac/*.class rm -f ./resources/output/raupenpiler/*.class rm -f ./java/*.class - rm -f ../main/resources/classFileOutput/*.class - + rm -f ../main/resources/output/*.class diff --git a/src/test/java/TestCompilerOutput.java b/src/test/java/TestCompilerOutput.java index cf6aac0..567ebde 100644 --- a/src/test/java/TestCompilerOutput.java +++ b/src/test/java/TestCompilerOutput.java @@ -1,16 +1,18 @@ /** * This class is used to test the output of the compiler. - *

- * Im gleichen Ordner wie die diese Datei (TestCompilerOutput.java) muss die selbstkompilierte CompilerInput.java Datei sein. - * --->>>> Diese muss man also vom Ordner classFileOutput in diesen ordner hier (test/java) rein kopieren. (bis es eine bessere Lösung gibt) <<<<--- - * Die selbstkompilierte .class Datei wird dann hier drin geladen und eine Instanz von ihr erstellt, es können auch Methoden aufgerufen werden. - * Diese TestCompilerOutput.java Datei wird dann mit "javac .\TestCompilerOutput.java" kompiliert und mit "java TestCompilerOutput" ausgeführt. + * + *

Im gleichen Ordner wie diese Datei (TestCompilerOutput.java) muss die selbstkompilierte CompilerInput.java Datei sein. + *
Hinweis: Diese muss man also vom Ordner classFileOutput in diesen Ordner hier (test/java) rein kopieren. (bis es eine bessere Lösung gibt)

+ * + *

Die selbstkompilierte .class Datei wird dann hier drin geladen und eine Instanz von ihr erstellt, es können auch Methoden aufgerufen werden. + *

Diese TestCompilerOutput.java Datei wird dann in \src\test\java> mit javac .\TestCompilerOutput.java kompiliert und mit java TestCompilerOutput ausgeführt. * Wenn unser Compiler funktioniert, sollten keine Errors kommen (sondern nur die Ausgaben, die wir in der CompilerInput.java Datei gemacht haben, - * oder Methoden, die wir hier aufrufen). - * PROBLEM: hier kommen errors, was eigentlich heißt, dass der Compiler nicht funktioniert, der der Test sollt eigentlich passen + * oder Methoden, die wir hier aufrufen).

+ * + *

PROBLEM: Hier kommen Errors, was eigentlich heißt, dass der Compiler nicht funktioniert, der Test sollte eigentlich passen. + *
DENN: Wenn ich statt unserem CompilerInput.class die CompilerInput.class von javac verwende (aus src/test/resources/output/javac ), dann funktioniert es.

*/ public class TestCompilerOutput { - public static void main(String[] args) { try { // Try to load the class named "CompilerInput" diff --git a/src/test/resources/AllFeaturesClassExample.java b/src/test/resources/input/AllFeaturesClassExample.java similarity index 100% rename from src/test/resources/AllFeaturesClassExample.java rename to src/test/resources/input/AllFeaturesClassExample.java diff --git a/src/test/resources/CombinedExample.java b/src/test/resources/input/CombinedExample.java similarity index 100% rename from src/test/resources/CombinedExample.java rename to src/test/resources/input/CombinedExample.java diff --git a/src/test/resources/CompilerInput.java b/src/test/resources/input/CompilerInput.java similarity index 50% rename from src/test/resources/CompilerInput.java rename to src/test/resources/input/CompilerInput.java index 91b2625..d850a3e 100644 --- a/src/test/resources/CompilerInput.java +++ b/src/test/resources/input/CompilerInput.java @@ -5,5 +5,12 @@ public class CompilerInput { public static int testMethod(char x){ return 0; } + + public class Test { + + public static int testMethod(char x, int a){ + return 0; + } + } } diff --git a/src/test/resources/MoreFeaturesClassExample.java b/src/test/resources/input/MoreFeaturesClassExample.java similarity index 100% rename from src/test/resources/MoreFeaturesClassExample.java rename to src/test/resources/input/MoreFeaturesClassExample.java diff --git a/src/test/resources/failureTests/TestClass1.java b/src/test/resources/input/failureTests/TestClass1.java similarity index 100% rename from src/test/resources/failureTests/TestClass1.java rename to src/test/resources/input/failureTests/TestClass1.java diff --git a/src/test/resources/failureTests/TestClass10.java b/src/test/resources/input/failureTests/TestClass10.java similarity index 100% rename from src/test/resources/failureTests/TestClass10.java rename to src/test/resources/input/failureTests/TestClass10.java diff --git a/src/test/resources/failureTests/TestClass11.java b/src/test/resources/input/failureTests/TestClass11.java similarity index 100% rename from src/test/resources/failureTests/TestClass11.java rename to src/test/resources/input/failureTests/TestClass11.java diff --git a/src/test/resources/failureTests/TestClass2.java b/src/test/resources/input/failureTests/TestClass2.java similarity index 100% rename from src/test/resources/failureTests/TestClass2.java rename to src/test/resources/input/failureTests/TestClass2.java diff --git a/src/test/resources/failureTests/TestClass3.java b/src/test/resources/input/failureTests/TestClass3.java similarity index 100% rename from src/test/resources/failureTests/TestClass3.java rename to src/test/resources/input/failureTests/TestClass3.java diff --git a/src/test/resources/failureTests/TestClass4.java b/src/test/resources/input/failureTests/TestClass4.java similarity index 100% rename from src/test/resources/failureTests/TestClass4.java rename to src/test/resources/input/failureTests/TestClass4.java diff --git a/src/test/resources/failureTests/TestClass5.java b/src/test/resources/input/failureTests/TestClass5.java similarity index 100% rename from src/test/resources/failureTests/TestClass5.java rename to src/test/resources/input/failureTests/TestClass5.java diff --git a/src/test/resources/failureTests/TestClass6.java b/src/test/resources/input/failureTests/TestClass6.java similarity index 100% rename from src/test/resources/failureTests/TestClass6.java rename to src/test/resources/input/failureTests/TestClass6.java diff --git a/src/test/resources/failureTests/TestClass7.java b/src/test/resources/input/failureTests/TestClass7.java similarity index 100% rename from src/test/resources/failureTests/TestClass7.java rename to src/test/resources/input/failureTests/TestClass7.java diff --git a/src/test/resources/failureTests/TestClass8.java b/src/test/resources/input/failureTests/TestClass8.java similarity index 100% rename from src/test/resources/failureTests/TestClass8.java rename to src/test/resources/input/failureTests/TestClass8.java diff --git a/src/test/resources/failureTests/TestClass9.java b/src/test/resources/input/failureTests/TestClass9.java similarity index 100% rename from src/test/resources/failureTests/TestClass9.java rename to src/test/resources/input/failureTests/TestClass9.java diff --git a/src/test/resources/featureTests/BooleanOperations.java b/src/test/resources/input/featureTests/BooleanOperations.java similarity index 100% rename from src/test/resources/featureTests/BooleanOperations.java rename to src/test/resources/input/featureTests/BooleanOperations.java diff --git a/src/test/resources/featureTests/CharManipulation.java b/src/test/resources/input/featureTests/CharManipulation.java similarity index 100% rename from src/test/resources/featureTests/CharManipulation.java rename to src/test/resources/input/featureTests/CharManipulation.java diff --git a/src/test/resources/featureTests/ConditionalStatements.java b/src/test/resources/input/featureTests/ConditionalStatements.java similarity index 100% rename from src/test/resources/featureTests/ConditionalStatements.java rename to src/test/resources/input/featureTests/ConditionalStatements.java diff --git a/src/test/resources/featureTests/LoopExamples.java b/src/test/resources/input/featureTests/LoopExamples.java similarity index 100% rename from src/test/resources/featureTests/LoopExamples.java rename to src/test/resources/input/featureTests/LoopExamples.java diff --git a/src/test/resources/featureTests/MethodOverloading.java b/src/test/resources/input/featureTests/MethodOverloading.java similarity index 100% rename from src/test/resources/featureTests/MethodOverloading.java rename to src/test/resources/input/featureTests/MethodOverloading.java -- 2.34.1 From b6cc925e020bdeb7a89d269dc1a5e0f09e7db293 Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Wed, 12 Jun 2024 18:01:21 +0200 Subject: [PATCH 08/14] Fixed Makefile --- pom.xml | 5 +++-- src/test/Makefile | 13 +++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index a11bfc7..e6506ea 100644 --- a/pom.xml +++ b/pom.xml @@ -9,8 +9,9 @@ 1.0-SNAPSHOT - 22 - 22 + 22 + ${java.version} + ${java.version} UTF-8 diff --git a/src/test/Makefile b/src/test/Makefile index 68b9dd2..e14b5d4 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -2,20 +2,17 @@ ### IntelliJs play buttons do not work. Run in "src/test" folder with "make" command to run all ### Or run only parts with "make compile-javac", "make delete" etc. -all: delete compile-javac compile-raupenpiler +all: compile-javac compile-raupenpiler compile-javac: javac -d .\resources\output\javac .\resources\input\CompilerInput.java compile-raupenpiler: -## funktioniert bisher nicht, das will die Klasse nicht laden, der traditionelle Weg findet externe Libraries (antlr) nicht, maven hat andere Probleme -## Unseren Compiler also erstmal händisch starten: main.java/Main.java - #javac -d ./resources/output/raupenpiler -cp ../main/java;../../.lib/antlr-4.12.0-complete.jar ../main/java/Main.java - #java -cp ./resources/output/raupenpiler Main - #mvn -f ../../ compile - #mvn -f ../../ exec:java -Dexec.mainClass="Main" + cd ../.. ; mvn -DskipTests package + cd ../.. ; mvn exec:java -Dexec.mainClass="Main" # -Dexec.args="arg0 arg1 arg2" -delete: + +clean: rm -f ./resources/output/javac/*.class rm -f ./resources/output/raupenpiler/*.class rm -f ./java/*.class -- 2.34.1 From 0732712e61105d8c51bc399d0062f1988db89dec Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Mon, 17 Jun 2024 13:42:56 +0200 Subject: [PATCH 09/14] Make, Main: Raupenpiler startup --- src/main/java/Main.java | 50 +++++++++++++------ src/main/java/bytecode/ByteCodeGenerator.java | 8 ++- src/main/java/bytecode/ClassCodeGen.java | 17 ++++--- .../java/bytecode/visitor/ClassVisitor.java | 5 +- src/test/Makefile | 10 +++- src/test/java/FailureTest.java | 2 +- src/test/java/MainTest.java | 2 +- src/test/java/TestCompilerOutput.java | 6 +-- src/test/java/parser/ParserTest.java | 4 ++ 9 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 src/test/java/parser/ParserTest.java diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 6f6517f..7174d66 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -13,23 +13,41 @@ import java.io.IOException; import java.nio.file.Paths; import java.util.List; +/** + * Start Raupenpiler with the following commands: + *

cd .\src\test\ + *

make clean compile-raupenpiler + */ public class Main { public static void main(String[] args) throws Exception { if (args.length > 0) { - System.out.println("Main file has args: " + args[0]); - } else { + // args[0] is the input file path + // args[1] is the output directory path + String inputFilePath = args[0]; + String outputDirectoryPath = args[1]; + System.out.println("Compiling file: " + inputFilePath); try { - CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/input/CompilerInput.java")); - parseFile(codeCharStream); + CharStream inputCharStream = CharStreams.fromPath(Paths.get(inputFilePath)); + compileFile(inputCharStream, outputDirectoryPath); } catch (IOException e) { System.err.println("Error reading the file: " + e.getMessage()); } } + /* !!! Else Branch ist nicht zur Verwendung vorgesehen, alles über make starten !!! + else { + try { + CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/input/CompilerInput.java")); + compileFile(codeCharStream); + } catch (IOException e) { + System.err.println("Error reading the file: " + e.getMessage()); + } + } + */ } - static void parseFile(CharStream codeCharStream) { + static void compileFile(CharStream inputCharStream, String outputDirectoryPath) { /* ------------------------- Scanner -> tokens ------------------------- */ - SimpleJavaLexer lexer = new SimpleJavaLexer(codeCharStream); + SimpleJavaLexer lexer = new SimpleJavaLexer(inputCharStream); CommonTokenStream tokenStream = new CommonTokenStream(lexer); // Printing the tokens @@ -51,20 +69,20 @@ public class Main { ParseTree parseTree = parser.program(); // parse the input // Printing the parse tree - System.out.println("-------------------- Parser -> Parsetree --------------------"); - System.out.println(parseTree.toStringTree(parser)); - printTree(parseTree, parser, 0); - System.out.println(); + System.out.println("-------------------- Parser -> Parsetree --------------------"); + System.out.println(parseTree.toStringTree(parser)); + printTree(parseTree, parser, 0); + System.out.println(); /*------------------------- AST builder -> AST -------------------------*/ ASTBuilder astBuilder = new ASTBuilder(); ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree); // Printing the AST - System.out.println("-------------------- AST builder -> AST --------------------"); - // System.out.println("AST: " + ast.toString()); - printAST(abstractSyntaxTree, 0); - System.out.println(); + System.out.println("-------------------- AST builder -> AST --------------------"); + // System.out.println("AST: " + ast.toString()); + printAST(abstractSyntaxTree, 0); + System.out.println(); /*------------------------- Semantic Analyzer -> typed AST -------------------------*/ ProgramNode typedAst = (ProgramNode) SemanticAnalyzer.generateTast(abstractSyntaxTree); @@ -75,11 +93,12 @@ public class Main { System.out.println(); /*------------------------- Bytecode Generator -> Bytecode -------------------------*/ - ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(); + ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath); byteCodeGenerator.visit(typedAst); System.out.println("Bytecode generated"); } + /* ------------------------- Printing methods ------------------------- */ /** * This method is used to print the parse tree in a structured format. @@ -114,6 +133,7 @@ public class Main { } } + // TODO: Fix this method public static void printAST(ASTNode node, int indent) { if (node == null) { System.out.println("null"); diff --git a/src/main/java/bytecode/ByteCodeGenerator.java b/src/main/java/bytecode/ByteCodeGenerator.java index 5494255..99cf5c1 100644 --- a/src/main/java/bytecode/ByteCodeGenerator.java +++ b/src/main/java/bytecode/ByteCodeGenerator.java @@ -6,10 +6,16 @@ import bytecode.visitor.ProgramVisitor; public class ByteCodeGenerator implements ProgramVisitor { + private final String outputDirectoryPath; + + public ByteCodeGenerator(String outputDirectoryPath) { + this.outputDirectoryPath = outputDirectoryPath; + } + @Override public void visit(ProgramNode programNode) { for (ClassNode classDeclarationNode : programNode.classes) { - ClassCodeGen classCodeGen = new ClassCodeGen(); + ClassCodeGen classCodeGen = new ClassCodeGen(outputDirectoryPath); classDeclarationNode.accept(classCodeGen); } } diff --git a/src/main/java/bytecode/ClassCodeGen.java b/src/main/java/bytecode/ClassCodeGen.java index d91b17b..d8cdaaa 100644 --- a/src/main/java/bytecode/ClassCodeGen.java +++ b/src/main/java/bytecode/ClassCodeGen.java @@ -6,7 +6,9 @@ import ast.member.MemberNode; import ast.member.MethodNode; import ast.type.BaseTypeNode; import bytecode.visitor.ClassVisitor; + import java.io.File; + import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; @@ -17,8 +19,10 @@ import java.io.IOException; public class ClassCodeGen implements ClassVisitor { private Mapper mapper; private ClassWriter classWriter; + private final String outputDirectoryPath; - public ClassCodeGen() { + public ClassCodeGen(String outputDirectoryPath) { + this.outputDirectoryPath = outputDirectoryPath; mapper = new Mapper(); } @@ -45,20 +49,21 @@ public class ClassCodeGen implements ClassVisitor { @Override public void visit(FieldNode fieldNode) { - if(fieldNode.type instanceof BaseTypeNode baseTypeNode){ - classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null ); + if (fieldNode.type instanceof BaseTypeNode baseTypeNode) { + classWriter.visitField(mapper.mapAccessTypeToOpcode(fieldNode.accessTypeNode), fieldNode.identifier, mapper.getTypeChar(baseTypeNode.enumType), null, null); } classWriter.visitEnd(); } private void printIntoClassFile(byte[] byteCode, String name) { - String directoryPath = "src/main/resources/output"; - File directory = new File(directoryPath); + // String outputDirectoryPath = "src/main/resources/output"; + System.out.println("Output directory path: " + outputDirectoryPath); + File directory = new File(outputDirectoryPath); if (!directory.exists()) { directory.mkdirs(); } - String filePath = directoryPath + "/" + name + ".class"; + String filePath = outputDirectoryPath + "/" + name + ".class"; try { FileOutputStream fileOutputStream = new FileOutputStream(filePath); fileOutputStream.write(byteCode); diff --git a/src/main/java/bytecode/visitor/ClassVisitor.java b/src/main/java/bytecode/visitor/ClassVisitor.java index 98ef25c..725b075 100644 --- a/src/main/java/bytecode/visitor/ClassVisitor.java +++ b/src/main/java/bytecode/visitor/ClassVisitor.java @@ -5,6 +5,7 @@ import ast.member.FieldNode; import org.objectweb.asm.ClassWriter; public interface ClassVisitor { - void visit(ClassNode classNode); - void visit(FieldNode fieldNode); + void visit(ClassNode classNode); + + void visit(FieldNode fieldNode); } diff --git a/src/test/Makefile b/src/test/Makefile index e14b5d4..1329f1d 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -9,8 +9,16 @@ compile-javac: compile-raupenpiler: cd ../.. ; mvn -DskipTests package - cd ../.. ; mvn exec:java -Dexec.mainClass="Main" # -Dexec.args="arg0 arg1 arg2" + cd ../.. ; mvn exec:java -Dexec.mainClass="Main" -Dexec.args="'src/main/resources/input/CompilerInput.java' 'src/main/resources/output' " +test: test-javac test-raupenpiler + +test-javac: + compile-javac + java -cp .\resources\output\javac CompilerInput + +test-raupenpiler: + java -cp .\resources\output\raupenpiler CompilerInput clean: rm -f ./resources/output/javac/*.class diff --git a/src/test/java/FailureTest.java b/src/test/java/FailureTest.java index 366ce56..028c5d1 100644 --- a/src/test/java/FailureTest.java +++ b/src/test/java/FailureTest.java @@ -63,7 +63,7 @@ public class FailureTest { CharStream codeCharStream = null; try { codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/EmptyClassExample.java")); - Main.parseFile(codeCharStream); + Main.compileFile(codeCharStream, "src/main/test/resources/output"); } catch (IOException e) { System.err.println("Error reading the file: " + e.getMessage()); } diff --git a/src/test/java/MainTest.java b/src/test/java/MainTest.java index a8c3a93..eec63b0 100644 --- a/src/test/java/MainTest.java +++ b/src/test/java/MainTest.java @@ -16,7 +16,7 @@ public class MainTest { CharStream codeCharStream = null; try { codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/CompilerInput.java")); - Main.parseFile(codeCharStream); + Main.compileFile(codeCharStream, "src/main/test/resources/output"); } catch (IOException e) { System.err.println("Error reading the file: " + e.getMessage()); } diff --git a/src/test/java/TestCompilerOutput.java b/src/test/java/TestCompilerOutput.java index 567ebde..6a7c031 100644 --- a/src/test/java/TestCompilerOutput.java +++ b/src/test/java/TestCompilerOutput.java @@ -1,10 +1,10 @@ /** * This class is used to test the output of the compiler. * - *

Im gleichen Ordner wie diese Datei (TestCompilerOutput.java) muss die selbstkompilierte CompilerInput.java Datei sein. - *
Hinweis: Diese muss man also vom Ordner classFileOutput in diesen Ordner hier (test/java) rein kopieren. (bis es eine bessere Lösung gibt)

+ *

Im gleichen Ordner wie diese Datei (TestCompilerOutput.java) muss die selbst kompilierte CompilerInput.class Datei sein. + *
Hinweis: Diese muss man also vom Ordner main/resources/output in diesen Ordner hier (test/java) rein kopieren. (bis es eine bessere Lösung gibt)

* - *

Die selbstkompilierte .class Datei wird dann hier drin geladen und eine Instanz von ihr erstellt, es können auch Methoden aufgerufen werden. + *

Die selbst kompilierte .class Datei wird dann hier drin geladen und eine Instanz von ihr erstellt, es können auch Methoden aufgerufen werden. *

Diese TestCompilerOutput.java Datei wird dann in \src\test\java> mit javac .\TestCompilerOutput.java kompiliert und mit java TestCompilerOutput ausgeführt. * Wenn unser Compiler funktioniert, sollten keine Errors kommen (sondern nur die Ausgaben, die wir in der CompilerInput.java Datei gemacht haben, * oder Methoden, die wir hier aufrufen).

diff --git a/src/test/java/parser/ParserTest.java b/src/test/java/parser/ParserTest.java new file mode 100644 index 0000000..834f988 --- /dev/null +++ b/src/test/java/parser/ParserTest.java @@ -0,0 +1,4 @@ +package parser; + +public class ParserTest { +} -- 2.34.1 From f59d7e99182f7529f85a741d123d4c1a05d5dd5b Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Mon, 17 Jun 2024 17:42:50 +0200 Subject: [PATCH 10/14] First Tests for Parser, pls check --- src/main/java/Main.java | 11 +- src/test/Makefile | 6 +- src/test/TestSpecs.md | 27 ++-- src/test/java/FailureTest.java | 22 ++-- src/test/java/parser/ParserTest.java | 183 +++++++++++++++++++++++++++ 5 files changed, 212 insertions(+), 37 deletions(-) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 7174d66..21d9349 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -49,17 +49,16 @@ public class Main { /* ------------------------- Scanner -> tokens ------------------------- */ SimpleJavaLexer lexer = new SimpleJavaLexer(inputCharStream); CommonTokenStream tokenStream = new CommonTokenStream(lexer); + tokenStream.fill(); // Printing the tokens - tokenStream.fill(); + System.out.println("-------------------- Scanner -> Tokens --------------------"); List tokens = tokenStream.getTokens(); - System.out.println("-------------------- Scanner -> tokens --------------------"); for (Token token : tokens) { String tokenType = SimpleJavaLexer.VOCABULARY.getSymbolicName(token.getType()); String tokenText = token.getText(); - // System.out.println("Token Type: " + tokenType + ", Token Text: " + - // tokenText); + // System.out.println("Token Type: " + tokenType + ", Token Text: " + tokenText); System.out.println(tokenType + " " + tokenText); } System.out.println(); @@ -70,8 +69,8 @@ public class Main { // Printing the parse tree System.out.println("-------------------- Parser -> Parsetree --------------------"); - System.out.println(parseTree.toStringTree(parser)); - printTree(parseTree, parser, 0); + System.out.println(parseTree.toStringTree(parser)); //one line representation + // printTree(parseTree, parser, 0); System.out.println(); /*------------------------- AST builder -> AST -------------------------*/ diff --git a/src/test/Makefile b/src/test/Makefile index 1329f1d..1498d17 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -14,11 +14,11 @@ compile-raupenpiler: test: test-javac test-raupenpiler test-javac: - compile-javac - java -cp .\resources\output\javac CompilerInput + #compile-javac + #java -cp .\resources\output\javac CompilerInput test-raupenpiler: - java -cp .\resources\output\raupenpiler CompilerInput + #java -cp .\resources\output\raupenpiler CompilerInput clean: rm -f ./resources/output/javac/*.class diff --git a/src/test/TestSpecs.md b/src/test/TestSpecs.md index 75f979a..cbdc1f5 100644 --- a/src/test/TestSpecs.md +++ b/src/test/TestSpecs.md @@ -18,6 +18,8 @@ ## Scanner Output +CommonTokenStream + ### Beispiel 1: Empty Class Token Type; Token Text @@ -28,26 +30,20 @@ Type gibts nur bei Terminalen, Text bei allen Bsp von Ihm mal: [TokPublic,TokClass,TokIdentifier "Name",TokLeftBrace,TokRightBrace] -### Beispiel 2: Filled Class - - [TokClass,TokIdentifier "javaFileInput.Example",TokLeftBrace] - [TokIf,TokLeftParen,TokIdentifier "x",TokLessThan,TokNumber 5,TokRightParen,TokLeftBrace] - [TokFor,TokLeftParen,TokIdentifier "int",TokIdentifier "i",TokAssign,TokNumber 0,TokSemicolon,TokIdentifier "i",TokLessThan,TokNumber 10,TokSemicolon,TokIdentifier "i",TokPlus,TokPlus,TokRightParen,TokLeftBrace] - [TokWhile,TokLeftParen,TokIdentifier "true",TokRightParen,TokLeftBrace] - [TokIdentifier "x",TokAssign,TokNumber 5,TokSemicolon] - [TokRightBrace] - # Parser ## Parser Input +CommonTokenStream (Scanner Output) ## Parser Output (AST) -### Beispiel 1: Empty Class +(program (classDeclaration (accessType public) class Name { })) -### Beispiel 2: Filled Class +ParseTree + +### Beispiel 1: Empty Class # Semantische Analyse / Typcheck @@ -59,8 +55,6 @@ Type gibts nur bei Terminalen, Text bei allen ### Beispiel 1: Empty Class -### Beispiel 2: Filled Class - # Bytecodegenerierung ## Bytecodegenerierung Input @@ -76,8 +70,6 @@ Compiled Classfile public class javaFileInput.Example { } -### Beispiel 2: Filled Class - ## E2E Tests: - Testdatei mit Main ausführen/kompilieren @@ -85,13 +77,14 @@ Compiled Classfile - -> Dateien mit javap vergleichen wenn beides erfolgreich + - Ergebnis vom eigenen Compiler mithilfe von TestCompilerOutput ausführen - (Ergebnis von javac mithilfe von TestCompilerOutput ausführen) - ### Andis Tipps: + - cp mitgeben -- makefile +- makefile - java -jar pfadtocompiler.jar EmptyClass.java - mvn package - javac tester // tester compilen diff --git a/src/test/java/FailureTest.java b/src/test/java/FailureTest.java index 028c5d1..f131e33 100644 --- a/src/test/java/FailureTest.java +++ b/src/test/java/FailureTest.java @@ -15,17 +15,17 @@ import java.util.List; public class FailureTest { private static final List TEST_FILES = Arrays.asList( - "src/main/test/resources/failureTests/TestClass1.java", - "src/main/test/resources/failureTests/TestClass2.java", - "src/main/test/resources/failureTests/TestClass3.java", - "src/main/test/resources/failureTests/TestClass4.java", - "src/main/test/resources/failureTests/TestClass5.java", - "src/main/test/resources/failureTests/TestClass6.java", - "src/main/test/resources/failureTests/TestClass7.java", - "src/main/test/resources/failureTests/TestClass8.java", - "src/main/test/resources/failureTests/TestClass9.java", - "src/main/test/resources/failureTests/TestClass10.java", - "src/main/test/resources/failureTests/TestClass11.java" + "src/main/test/resources/input/failureTests/TestClass1.java", + "src/main/test/resources/input/failureTests/TestClass2.java", + "src/main/test/resources/input/failureTests/TestClass3.java", + "src/main/test/resources/input/failureTests/TestClass4.java", + "src/main/test/resources/input/failureTests/TestClass5.java", + "src/main/test/resources/input/failureTests/TestClass6.java", + "src/main/test/resources/input/failureTests/TestClass7.java", + "src/main/test/resources/input/failureTests/TestClass8.java", + "src/main/test/resources/input/failureTests/TestClass9.java", + "src/main/test/resources/input/failureTests/TestClass10.java", + "src/main/test/resources/input/failureTests/TestClass11.java" ); /** diff --git a/src/test/java/parser/ParserTest.java b/src/test/java/parser/ParserTest.java index 834f988..173f1ce 100644 --- a/src/test/java/parser/ParserTest.java +++ b/src/test/java/parser/ParserTest.java @@ -1,4 +1,187 @@ package parser; +import ast.ProgramNode; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.tree.ParseTree; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import parser.generated.SimpleJavaLexer; +import parser.generated.SimpleJavaParser; + +import static org.junit.jupiter.api.Assertions.*; + +import java.nio.file.Paths; +import java.util.*; +import java.util.function.BooleanSupplier; + public class ParserTest { + @BeforeEach + public void init() { // noch nicht benötigt + String inputFilePath = "src/main/resources/input/CompilerInput.java"; + String outputDirectoryPath = "src/main/resources/output"; + } + + /** + * This test method is used to test the scanner functionality of the SimpleJavaLexer. + * It creates a CharStream from a string representing a simple Java class declaration, + * and uses the SimpleJavaLexer to tokenize this input. + * It then compares the actual tokens and their types produced by the lexer to the expected tokens and their types. + */ + @Test + public void scannerTest() { + // Create a CharStream from a string representing a simple Java class declaration + CharStream inputCharStream = CharStreams.fromString("public class Name {}"); + + // Use the SimpleJavaLexer to tokenize the input + SimpleJavaLexer lexer = new SimpleJavaLexer(inputCharStream); + CommonTokenStream tokenStream = new CommonTokenStream(lexer); + tokenStream.fill(); + + // Prepare the expected results + List actualTokens = tokenStream.getTokens(); + List expectedTokens = Arrays.asList("public", "class", "Name", "{", "}", ""); + List expectedTokenTypes = Arrays.asList(null, null, "IDENTIFIER", null, null, "EOF"); + + // Compare the actual tokens and their types to the expected tokens and their types + assertEquals(expectedTokens.size(), actualTokens.size()); + for (int i = 0; i < expectedTokens.size(); i++) { + assertEquals(expectedTokens.get(i), actualTokens.get(i).getText()); + assertEquals(expectedTokenTypes.get(i), SimpleJavaLexer.VOCABULARY.getSymbolicName(actualTokens.get(i).getType())); + } + } + + + @Test + public void parserTest() { + // init + CharStream inputCharStream = CharStreams.fromString("public class Name {}"); + SimpleJavaLexer lexer = new SimpleJavaLexer(inputCharStream); + CommonTokenStream tokenStream = new CommonTokenStream(lexer); + tokenStream.fill(); + + + /* Parser -> Parsetree */ + SimpleJavaParser parser = new SimpleJavaParser(tokenStream); + ParseTree parseTree = parser.program(); // parse the input + + //Variante 1 (geht) + String actualParseTreeAsString = parseTree.toStringTree(parser); + String expectedParseTreeAsString = "(program (classDeclaration (accessType public) class Name { }))"; + + assertEquals(actualParseTreeAsString, expectedParseTreeAsString); + + //Variante 2 (geht nicht) + // - Sollte es gehen und es liegt am Parser? (keine Ahnung) -> Bitte Fehler (actual und expected) durchlesen + Map actualTreeStructure = buildTreeStructure(parseTree, parser); + Map expectedTreeStructure = parseStringToTree(expectedParseTreeAsString); + + assertEquals(actualTreeStructure, expectedTreeStructure); + + + } + + @Test + public void astBuilderTest() { + // TODO: Implement this test method + + + + + /* AST builder -> AST */ + ASTBuilder astBuilder = new ASTBuilder(); + // ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree); + + //String actualASTasString = new ASTBuilder().visit(parseTree).toString(); + + // ProgramNode actualAST = new ASTBuilder().visit(parseTree); + // ProgramNode expectedAST = new ProgramNode(); + // expectedAST.add(new ProgramNode.ClassNode("Name", new ProgramNode())); + } + + + // Helpers Variante 2.1 + + public static Map buildTreeStructure(ParseTree tree, Parser parser) { + return buildTree(tree, parser, 0); + } + + private static Map buildTree(ParseTree tree, Parser parser, int indent) { + Map node = new HashMap<>(); + + if (tree instanceof RuleContext) { + int ruleIndex = ((RuleContext) tree).getRuleIndex(); + String ruleName = parser.getRuleNames()[ruleIndex]; + node.put("rule", ruleName); + } else { + node.put("text", tree.getText()); + } + + List> children = new ArrayList<>(); + for (int i = 0; i < tree.getChildCount(); i++) { + children.add(buildTree(tree.getChild(i), parser, indent + 1)); + } + + if (!children.isEmpty()) { + node.put("children", children); + } + + return node; + } + + // Helpers Variante 2.2 + + public static Map parseStringToTree(String input) { + input = input.trim(); + if (input.startsWith("(") && input.endsWith(")")) { + input = input.substring(1, input.length() - 1).trim(); + } + return parse(input); + } + + private static Map parse(String input) { + Map node = new HashMap<>(); + StringBuilder currentToken = new StringBuilder(); + List> children = new ArrayList<>(); + + int depth = 0; + boolean inToken = false; + for (char ch : input.toCharArray()) { + if (ch == '(') { + if (depth == 0) { + if (currentToken.length() > 0) { + node.put("node", currentToken.toString().trim()); + currentToken.setLength(0); + } + } else { + currentToken.append(ch); + } + depth++; + } else if (ch == ')') { + depth--; + if (depth == 0) { + children.add(parse(currentToken.toString().trim())); + currentToken.setLength(0); + } else { + currentToken.append(ch); + } + } else if (Character.isWhitespace(ch) && depth == 0) { + if (currentToken.length() > 0) { + node.put("node", currentToken.toString().trim()); + currentToken.setLength(0); + } + } else { + currentToken.append(ch); + } + } + + if (currentToken.length() > 0) { + node.put("node", currentToken.toString().trim()); + } + + if (!children.isEmpty()) { + node.put("children", children); + } + + return node; + } } -- 2.34.1 From 102961bccc072e2481c31d03a133f5b0f5b604c0 Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Wed, 19 Jun 2024 12:49:46 +0200 Subject: [PATCH 11/14] Added logging --- src/main/java/Main.java | 146 ++++++++-------------- src/main/java/MyLogger.java | 178 +++++++++++++++++++++++++++ src/test/Makefile | 3 +- src/test/java/parser/ParserTest.java | 3 - 4 files changed, 229 insertions(+), 101 deletions(-) create mode 100644 src/main/java/MyLogger.java diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 21d9349..6e26428 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,4 +1,3 @@ -import ast.ASTNode; import ast.ProgramNode; import parser.ASTBuilder; import parser.generated.SimpleJavaLexer; @@ -11,7 +10,7 @@ import org.antlr.v4.runtime.tree.ParseTree; import java.io.IOException; import java.nio.file.Paths; -import java.util.List; + /** * Start Raupenpiler with the following commands: @@ -19,6 +18,8 @@ import java.util.List; *

make clean compile-raupenpiler */ public class Main { + + public static void main(String[] args) throws Exception { if (args.length > 0) { // args[0] is the input file path @@ -45,105 +46,56 @@ public class Main { */ } - static void compileFile(CharStream inputCharStream, String outputDirectoryPath) { - /* ------------------------- Scanner -> tokens ------------------------- */ - SimpleJavaLexer lexer = new SimpleJavaLexer(inputCharStream); - CommonTokenStream tokenStream = new CommonTokenStream(lexer); - tokenStream.fill(); - - // Printing the tokens - System.out.println("-------------------- Scanner -> Tokens --------------------"); - List tokens = tokenStream.getTokens(); - for (Token token : tokens) { - String tokenType = - SimpleJavaLexer.VOCABULARY.getSymbolicName(token.getType()); - String tokenText = token.getText(); - // System.out.println("Token Type: " + tokenType + ", Token Text: " + tokenText); - System.out.println(tokenType + " " + tokenText); - } - System.out.println(); - - /*------------------------- Parser -> Parsetree -------------------------*/ - SimpleJavaParser parser = new SimpleJavaParser(tokenStream); - ParseTree parseTree = parser.program(); // parse the input - - // Printing the parse tree - System.out.println("-------------------- Parser -> Parsetree --------------------"); - System.out.println(parseTree.toStringTree(parser)); //one line representation - // printTree(parseTree, parser, 0); - System.out.println(); - - /*------------------------- AST builder -> AST -------------------------*/ - ASTBuilder astBuilder = new ASTBuilder(); - ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree); - - // Printing the AST - System.out.println("-------------------- AST builder -> AST --------------------"); - // System.out.println("AST: " + ast.toString()); - printAST(abstractSyntaxTree, 0); - System.out.println(); - - /*------------------------- Semantic Analyzer -> typed AST -------------------------*/ - ProgramNode typedAst = (ProgramNode) SemanticAnalyzer.generateTast(abstractSyntaxTree); - - // Printing the typed AST - System.out.println("-------------------- Semantic Analyzer -> typed AST --------------------"); - printAST(typedAst, 0); - System.out.println(); - - /*------------------------- Bytecode Generator -> Bytecode -------------------------*/ - ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath); - byteCodeGenerator.visit(typedAst); - System.out.println("Bytecode generated"); - } - - /* ------------------------- Printing methods ------------------------- */ - /** - * This method is used to print the parse tree in a structured format. - * It recursively traverses the tree and prints the rule names and text of the - * nodes. - * - * @param tree The parse tree to be printed. - * @param parser The parser used to parse the input. It's used to get the rule - * names. - * @param indent The current indentation level. It's used to format the output. - */ - public static void printTree(ParseTree tree, Parser parser, int indent) { - // Create an indentation string based on the current indentation level - String indentString = " ".repeat(indent * 2); + * This method is used to compile a file from a given CharStream and output the bytecode to a specified directory. + * It goes through the following steps: + *

1. Scanner: It uses the SimpleJavaLexer to tokenize the input CharStream. + *

2. Parser: It uses the SimpleJavaParser to parse the tokens and generate a ParseTree. + *

3. AST Builder: It uses the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST). + *

4. Semantic Analyzer: It uses the SemanticAnalyzer to generate a typed AST. + *

5. Bytecode Generator: It uses the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory. + * + * @param inputCharStream The CharStream representing the input file to be compiled. + * @param outputDirectoryPath The path of the directory where the output bytecode should be written. + */ +static void compileFile(CharStream inputCharStream, String outputDirectoryPath) { + // Initialize the logger + new MyLogger(); - // If the tree node is an instance of RuleContext (i.e., it's an internal node), - // print the rule name - if (tree instanceof RuleContext) { - int ruleIndex = ((RuleContext) tree).getRuleIndex(); - String ruleName = parser.getRuleNames()[ruleIndex]; - System.out.println(indentString + ruleName); - } else { - // If the tree node is not an instance of RuleContext (i.e., it's a leaf node), - // print the text of the node - System.out.println(indentString + tree.getText()); - } + /* ------------------------- Scanner -> tokens ------------------------- */ + // Use the SimpleJavaLexer to tokenize the input CharStream + SimpleJavaLexer lexer = new SimpleJavaLexer(inputCharStream); + CommonTokenStream tokenStream = new CommonTokenStream(lexer); + tokenStream.fill(); + // Log the tokens + MyLogger.logScanner(tokenStream); - // Recursively print the children of the current node, increasing the - // indentation level - for (int i = 0; i < tree.getChildCount(); i++) { - printTree(tree.getChild(i), parser, indent + 1); - } - } + /*------------------------- Parser -> Parse tree -------------------------*/ + // Use the SimpleJavaParser to parse the tokens and generate a ParseTree + SimpleJavaParser parser = new SimpleJavaParser(tokenStream); + ParseTree parseTree = parser.program(); // parse the input + // Log the ParseTree + MyLogger.logParser(parseTree, parser); - // TODO: Fix this method - public static void printAST(ASTNode node, int indent) { - if (node == null) { - System.out.println("null"); - return; - } - String indentString = " ".repeat(indent * 2); - System.out.println(indentString + node.getClass().toString()); + /*------------------------- AST builder -> AST -------------------------*/ + // Use the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST) + ASTBuilder astBuilder = new ASTBuilder(); + ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree); + // Log the AST + MyLogger.logAST(abstractSyntaxTree); - // for (ASTNode child : node.) { - // printAST(child, indent + 1); - // } - } + /*------------------------- Semantic Analyzer -> typed AST -------------------------*/ + // Use the SemanticAnalyzer to generate a typed AST + ProgramNode typedAst = (ProgramNode) SemanticAnalyzer.generateTast(abstractSyntaxTree); + // Log the typed AST + MyLogger.logSemanticAnalyzer(typedAst); + /*------------------------- Bytecode Generator -> Bytecode -------------------------*/ + // Use the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory + ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath); + assert typedAst != null; + byteCodeGenerator.visit(typedAst); + // Log the bytecode generation + MyLogger.logBytecodeGenerator(); +} } \ No newline at end of file diff --git a/src/main/java/MyLogger.java b/src/main/java/MyLogger.java new file mode 100644 index 0000000..1ab206f --- /dev/null +++ b/src/main/java/MyLogger.java @@ -0,0 +1,178 @@ +import ast.ASTNode; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.Parser; +import org.antlr.v4.runtime.RuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTree; +import parser.generated.SimpleJavaLexer; +import parser.generated.SimpleJavaParser; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.logging.*; + +/** + Beispiel für Logging-Arten: +

logger.severe("Schwerwiegender Fehler"); +

logger.warning("Warnung"); +

logger.info("Information"); +

logger.config("Konfigurationshinweis"); +

logger.fine("Fein"); +

logger.finer("Feiner"); +

logger.finest("Am feinsten"); +

You may toggle the logging level of the console and file handlers by + changing the level ALL/OFF/etc. in the constructor. + consoleHandler.setLevel(Level.OFF); + fileHandler.setLevel(Level.ALL); + */ +public class MyLogger { + + static Logger logger = Logger.getLogger("RaupenLogs"); + + public MyLogger() { + // ------------------------- Logging ------------------------- + logger.setLevel(Level.ALL); + logger.getParent().getHandlers()[0].setLevel(Level.ALL); + logger.setUseParentHandlers(false); + + // Custom formatter class + class CustomFormatter extends Formatter { + private final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss dd-MM-yyyy"); + + @Override + public String format(LogRecord record) { + return formatMessage(record) + System.lineSeparator(); + } + + @Override + public String getHead(Handler h) { + Date now = new Date(); + String dateTime = dateFormat.format(now); + return "Log Start Time: " + dateTime + "\n" + + "Logger Name: " + h.getFormatter().getClass().getName() + "\n\n"; + } + } + + try { + // Configure console handler + Handler consoleHandler = new ConsoleHandler(); + // Toggle console logging on/off + consoleHandler.setLevel(Level.OFF); + consoleHandler.setFormatter(new CustomFormatter()); + logger.addHandler(consoleHandler); + + // Configure file handler + Handler fileHandler = new FileHandler("src/main/resources/logs/RaupenLog.log"); + // Toggle file logging on/off + fileHandler.setLevel(Level.ALL); + fileHandler.setFormatter(new CustomFormatter()); + logger.addHandler(fileHandler); + + } catch (SecurityException | IOException e) { + e.printStackTrace(); + } + } + + public static void logScanner(CommonTokenStream tokenStream) { + // Printing the tokens + logger.info("-------------------- Scanner -> Tokens --------------------"); + List tokens = tokenStream.getTokens(); + for (Token token : tokens) { + String tokenType = + SimpleJavaLexer.VOCABULARY.getSymbolicName(token.getType()); + String tokenText = token.getText(); + // logger.info("Token Type: " + tokenType + ", Token Text: " + tokenText); + logger.info(tokenType + " " + tokenText); + } + logger.info("\n"); + } + + public static void logParser(ParseTree parseTree, SimpleJavaParser parser) { + // Printing the parse tree + logger.info("-------------------- Parser -> Parsetree --------------------"); + logger.info(parseTree.toStringTree(parser)); //one line representation + logTree(parseTree, parser, 0); + logger.info("\n"); + } + + public static void logAST(ASTNode node) { + // Printing the AST + logger.info("-------------------- AST builder -> AST --------------------"); + // logger.info("AST: " + ast.toString()); + logAST(node, 0); + logger.info("\n"); + } + + public static void logSemanticAnalyzer(ASTNode node) { + // Printing the typed AST + logger.info("-------------------- Semantic Analyzer -> typed AST --------------------"); + logAST(node, 0); + logger.info("\n"); + } + + public static void logBytecodeGenerator() { + // Printing the bytecode + logger.info("-------------------- Bytecode Generator -> Bytecode --------------------"); + logger.info("Bytecode generated"); + logger.info("\n"); + } + + + + + + + + + + /* ------------------------- Printing methods ------------------------- */ + + /** + * This method is used to print the parse tree in a structured format. + * It recursively traverses the tree and prints the rule names and text of the + * nodes. + * + * @param tree The parse tree to be printed. + * @param parser The parser used to parse the input. It's used to get the rule + * names. + * @param indent The current indentation level. It's used to format the output. + */ + public static void logTree(ParseTree tree, Parser parser, int indent) { + // Create an indentation string based on the current indentation level + String indentString = " ".repeat(indent * 2); + + // If the tree node is an instance of RuleContext (i.e., it's an internal node), + // print the rule name + if (tree instanceof RuleContext) { + int ruleIndex = ((RuleContext) tree).getRuleIndex(); + String ruleName = parser.getRuleNames()[ruleIndex]; + logger.info(indentString + ruleName); + } else { + // If the tree node is not an instance of RuleContext (i.e., it's a leaf node), + // print the text of the node + logger.info(indentString + tree.getText()); + } + + // Recursively print the children of the current node, increasing the + // indentation level + for (int i = 0; i < tree.getChildCount(); i++) { + logTree(tree.getChild(i), parser, indent + 1); + } + } + + // TODO: Fix this method + public static void logAST(ASTNode node, int indent) { + if (node == null) { + System.out.println("null"); + return; + } + String indentString = " ".repeat(indent * 2); + logger.info(indentString + node.getClass().toString()); + + // for (ASTNode child : node.) { + // printAST(child, indent + 1); + // } + } +} diff --git a/src/test/Makefile b/src/test/Makefile index 1498d17..b9c9ecb 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -1,6 +1,6 @@ # Makefile ### IntelliJs play buttons do not work. Run in "src/test" folder with "make" command to run all -### Or run only parts with "make compile-javac", "make delete" etc. +### Or run only parts with "make compile-javac", "make clean" etc. all: compile-javac compile-raupenpiler @@ -25,4 +25,5 @@ clean: rm -f ./resources/output/raupenpiler/*.class rm -f ./java/*.class rm -f ../main/resources/output/*.class + rm -f ../main/resources/logs/*.log diff --git a/src/test/java/parser/ParserTest.java b/src/test/java/parser/ParserTest.java index 173f1ce..d599632 100644 --- a/src/test/java/parser/ParserTest.java +++ b/src/test/java/parser/ParserTest.java @@ -1,6 +1,5 @@ package parser; -import ast.ProgramNode; import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.ParseTree; import org.junit.jupiter.api.BeforeEach; @@ -10,9 +9,7 @@ import parser.generated.SimpleJavaParser; import static org.junit.jupiter.api.Assertions.*; -import java.nio.file.Paths; import java.util.*; -import java.util.function.BooleanSupplier; public class ParserTest { @BeforeEach -- 2.34.1 From 8f742191bb9d0d5fcf62af22343a5f464eb5ac14 Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Wed, 19 Jun 2024 14:19:47 +0200 Subject: [PATCH 12/14] Small changes --- src/main/java/Main.java | 21 ++++++++++--------- .../java/{MyLogger.java => RaupenLogger.java} | 20 +++++++++--------- src/main/java/bytecode/ClassCodeGen.java | 2 +- 3 files changed, 22 insertions(+), 21 deletions(-) rename src/main/java/{MyLogger.java => RaupenLogger.java} (92%) diff --git a/src/main/java/Main.java b/src/main/java/Main.java index 6e26428..54758ff 100644 --- a/src/main/java/Main.java +++ b/src/main/java/Main.java @@ -1,3 +1,4 @@ +import ast.ASTNode; import ast.ProgramNode; import parser.ASTBuilder; import parser.generated.SimpleJavaLexer; @@ -60,7 +61,7 @@ public class Main { */ static void compileFile(CharStream inputCharStream, String outputDirectoryPath) { // Initialize the logger - new MyLogger(); + new RaupenLogger(); /* ------------------------- Scanner -> tokens ------------------------- */ // Use the SimpleJavaLexer to tokenize the input CharStream @@ -68,34 +69,34 @@ static void compileFile(CharStream inputCharStream, String outputDirectoryPath) CommonTokenStream tokenStream = new CommonTokenStream(lexer); tokenStream.fill(); // Log the tokens - MyLogger.logScanner(tokenStream); + RaupenLogger.logScanner(tokenStream); - /*------------------------- Parser -> Parse tree -------------------------*/ + /*------------------------- Parser -> Parsetree -------------------------*/ // Use the SimpleJavaParser to parse the tokens and generate a ParseTree SimpleJavaParser parser = new SimpleJavaParser(tokenStream); ParseTree parseTree = parser.program(); // parse the input // Log the ParseTree - MyLogger.logParser(parseTree, parser); + RaupenLogger.logParser(parseTree, parser); /*------------------------- AST builder -> AST -------------------------*/ // Use the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST) ASTBuilder astBuilder = new ASTBuilder(); - ProgramNode abstractSyntaxTree = (ProgramNode) astBuilder.visit(parseTree); + ASTNode abstractSyntaxTree = astBuilder.visit(parseTree); // Log the AST - MyLogger.logAST(abstractSyntaxTree); + RaupenLogger.logAST(abstractSyntaxTree); /*------------------------- Semantic Analyzer -> typed AST -------------------------*/ // Use the SemanticAnalyzer to generate a typed AST - ProgramNode typedAst = (ProgramNode) SemanticAnalyzer.generateTast(abstractSyntaxTree); + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); // Log the typed AST - MyLogger.logSemanticAnalyzer(typedAst); + RaupenLogger.logSemanticAnalyzer(typedAst); /*------------------------- Bytecode Generator -> Bytecode -------------------------*/ // Use the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath); assert typedAst != null; - byteCodeGenerator.visit(typedAst); + byteCodeGenerator.visit((ProgramNode) typedAst); // Log the bytecode generation - MyLogger.logBytecodeGenerator(); + RaupenLogger.logBytecodeGenerator(); } } \ No newline at end of file diff --git a/src/main/java/MyLogger.java b/src/main/java/RaupenLogger.java similarity index 92% rename from src/main/java/MyLogger.java rename to src/main/java/RaupenLogger.java index 1ab206f..5d17415 100644 --- a/src/main/java/MyLogger.java +++ b/src/main/java/RaupenLogger.java @@ -27,11 +27,11 @@ import java.util.logging.*; consoleHandler.setLevel(Level.OFF); fileHandler.setLevel(Level.ALL); */ -public class MyLogger { +public class RaupenLogger { static Logger logger = Logger.getLogger("RaupenLogs"); - public MyLogger() { + public RaupenLogger() { // ------------------------- Logging ------------------------- logger.setLevel(Level.ALL); logger.getParent().getHandlers()[0].setLevel(Level.ALL); @@ -97,18 +97,18 @@ public class MyLogger { logger.info("\n"); } - public static void logAST(ASTNode node) { + public static void logAST(ASTNode abstractSyntaxTree) { // Printing the AST logger.info("-------------------- AST builder -> AST --------------------"); // logger.info("AST: " + ast.toString()); - logAST(node, 0); + logAST(abstractSyntaxTree, 0); logger.info("\n"); } - public static void logSemanticAnalyzer(ASTNode node) { + public static void logSemanticAnalyzer(ASTNode typedAst) { // Printing the typed AST logger.info("-------------------- Semantic Analyzer -> typed AST --------------------"); - logAST(node, 0); + logAST(typedAst, 0); logger.info("\n"); } @@ -163,13 +163,13 @@ public class MyLogger { } // TODO: Fix this method - public static void logAST(ASTNode node, int indent) { - if (node == null) { - System.out.println("null"); + public static void logAST(ASTNode abstractSyntaxTree, int indent) { + if (abstractSyntaxTree == null) { + logger.severe("AST is null !!!"); return; } String indentString = " ".repeat(indent * 2); - logger.info(indentString + node.getClass().toString()); + logger.info(indentString + abstractSyntaxTree.getClass()); // for (ASTNode child : node.) { // printAST(child, indent + 1); diff --git a/src/main/java/bytecode/ClassCodeGen.java b/src/main/java/bytecode/ClassCodeGen.java index d8cdaaa..089b567 100644 --- a/src/main/java/bytecode/ClassCodeGen.java +++ b/src/main/java/bytecode/ClassCodeGen.java @@ -57,7 +57,7 @@ public class ClassCodeGen implements ClassVisitor { private void printIntoClassFile(byte[] byteCode, String name) { // String outputDirectoryPath = "src/main/resources/output"; - System.out.println("Output directory path: " + outputDirectoryPath); + // System.out.println("Output directory path: " + outputDirectoryPath); File directory = new File(outputDirectoryPath); if (!directory.exists()) { directory.mkdirs(); -- 2.34.1 From cfcb61d49e172a159bcf307ca05359ee391b4861 Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Wed, 19 Jun 2024 16:32:46 +0200 Subject: [PATCH 13/14] Running now possible with make or java.exe -jar in console --- .gitignore | 4 +- pom.xml | 22 ++++ src/main/java/Main.java | 102 ----------------- src/main/java/main/Main.java | 108 ++++++++++++++++++ src/main/java/{ => main}/RaupenLogger.java | 2 + src/test/Makefile | 4 +- src/test/TestSpecs.md | 6 +- .../java/{ => main}/EmptyClassExample.java | 2 + src/test/java/{ => main}/FailureTest.java | 4 +- src/test/java/{ => main}/MainTest.java | 2 + .../java/{ => main}/TestCompilerOutput.java | 6 +- 11 files changed, 151 insertions(+), 111 deletions(-) delete mode 100644 src/main/java/Main.java create mode 100644 src/main/java/main/Main.java rename src/main/java/{ => main}/RaupenLogger.java (99%) rename src/test/java/{ => main}/EmptyClassExample.java (65%) rename src/test/java/{ => main}/FailureTest.java (97%) rename src/test/java/{ => main}/MainTest.java (97%) rename src/test/java/{ => main}/TestCompilerOutput.java (86%) diff --git a/.gitignore b/.gitignore index c134c76..8f74459 100644 --- a/.gitignore +++ b/.gitignore @@ -76,4 +76,6 @@ fabric.properties # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser -/target \ No newline at end of file +/target +src/main/resources/logs/RaupenLog.log +src/main/resources/output/CompilerInput.class diff --git a/pom.xml b/pom.xml index e6506ea..27cbd7f 100644 --- a/pom.xml +++ b/pom.xml @@ -45,6 +45,28 @@ maven-surefire-plugin 3.0.0-M5 + + maven-assembly-plugin + + + make-assembly + package + + single + + + + + + + main.Main + + + + jar-with-dependencies + + + diff --git a/src/main/java/Main.java b/src/main/java/Main.java deleted file mode 100644 index 54758ff..0000000 --- a/src/main/java/Main.java +++ /dev/null @@ -1,102 +0,0 @@ -import ast.ASTNode; -import ast.ProgramNode; -import parser.ASTBuilder; -import parser.generated.SimpleJavaLexer; -import parser.generated.SimpleJavaParser; -import semantic.SemanticAnalyzer; -import bytecode.ByteCodeGenerator; - -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.tree.ParseTree; - -import java.io.IOException; -import java.nio.file.Paths; - - -/** - * Start Raupenpiler with the following commands: - *

cd .\src\test\ - *

make clean compile-raupenpiler - */ -public class Main { - - - public static void main(String[] args) throws Exception { - if (args.length > 0) { - // args[0] is the input file path - // args[1] is the output directory path - String inputFilePath = args[0]; - String outputDirectoryPath = args[1]; - System.out.println("Compiling file: " + inputFilePath); - try { - CharStream inputCharStream = CharStreams.fromPath(Paths.get(inputFilePath)); - compileFile(inputCharStream, outputDirectoryPath); - } catch (IOException e) { - System.err.println("Error reading the file: " + e.getMessage()); - } - } - /* !!! Else Branch ist nicht zur Verwendung vorgesehen, alles über make starten !!! - else { - try { - CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/input/CompilerInput.java")); - compileFile(codeCharStream); - } catch (IOException e) { - System.err.println("Error reading the file: " + e.getMessage()); - } - } - */ - } - - /** - * This method is used to compile a file from a given CharStream and output the bytecode to a specified directory. - * It goes through the following steps: - *

1. Scanner: It uses the SimpleJavaLexer to tokenize the input CharStream. - *

2. Parser: It uses the SimpleJavaParser to parse the tokens and generate a ParseTree. - *

3. AST Builder: It uses the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST). - *

4. Semantic Analyzer: It uses the SemanticAnalyzer to generate a typed AST. - *

5. Bytecode Generator: It uses the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory. - * - * @param inputCharStream The CharStream representing the input file to be compiled. - * @param outputDirectoryPath The path of the directory where the output bytecode should be written. - */ -static void compileFile(CharStream inputCharStream, String outputDirectoryPath) { - // Initialize the logger - new RaupenLogger(); - - /* ------------------------- Scanner -> tokens ------------------------- */ - // Use the SimpleJavaLexer to tokenize the input CharStream - SimpleJavaLexer lexer = new SimpleJavaLexer(inputCharStream); - CommonTokenStream tokenStream = new CommonTokenStream(lexer); - tokenStream.fill(); - // Log the tokens - RaupenLogger.logScanner(tokenStream); - - /*------------------------- Parser -> Parsetree -------------------------*/ - // Use the SimpleJavaParser to parse the tokens and generate a ParseTree - SimpleJavaParser parser = new SimpleJavaParser(tokenStream); - ParseTree parseTree = parser.program(); // parse the input - // Log the ParseTree - RaupenLogger.logParser(parseTree, parser); - - /*------------------------- AST builder -> AST -------------------------*/ - // Use the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST) - ASTBuilder astBuilder = new ASTBuilder(); - ASTNode abstractSyntaxTree = astBuilder.visit(parseTree); - // Log the AST - RaupenLogger.logAST(abstractSyntaxTree); - - /*------------------------- Semantic Analyzer -> typed AST -------------------------*/ - // Use the SemanticAnalyzer to generate a typed AST - ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); - // Log the typed AST - RaupenLogger.logSemanticAnalyzer(typedAst); - - /*------------------------- Bytecode Generator -> Bytecode -------------------------*/ - // Use the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory - ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath); - assert typedAst != null; - byteCodeGenerator.visit((ProgramNode) typedAst); - // Log the bytecode generation - RaupenLogger.logBytecodeGenerator(); -} -} \ No newline at end of file diff --git a/src/main/java/main/Main.java b/src/main/java/main/Main.java new file mode 100644 index 0000000..5384677 --- /dev/null +++ b/src/main/java/main/Main.java @@ -0,0 +1,108 @@ +package main; + +import ast.ASTNode; +import ast.ProgramNode; +import parser.ASTBuilder; +import parser.generated.SimpleJavaLexer; +import parser.generated.SimpleJavaParser; +import semantic.SemanticAnalyzer; +import bytecode.ByteCodeGenerator; + +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.tree.ParseTree; + +import java.io.IOException; +import java.nio.file.Paths; + + +/** + * Start Raupenpiler using make: + *

cd .\src\test\ + *

make clean compile-raupenpiler + *

Start Raupenpiler using jar: + *

java.exe -jar .\target\JavaCompiler-1.0-SNAPSHOT-jar-with-dependencies.jar 'path_to_input_file.java' 'path_to_output_directory' + *

Example: + * java.exe -jar .\target\JavaCompiler-1.0-SNAPSHOT-jar-with-dependencies.jar 'src/main/resources/input/CompilerInput.java' 'src/main/resources/output' + */ +public class Main { + + + public static void main(String[] args) throws Exception { + if (args.length > 0) { + // args[0] is the input file path + // args[1] is the output directory path + String inputFilePath = args[0]; + String outputDirectoryPath = args[1]; + System.out.println("Compiling file: " + inputFilePath); + try { + CharStream inputCharStream = CharStreams.fromPath(Paths.get(inputFilePath)); + compileFile(inputCharStream, outputDirectoryPath); + } catch (IOException e) { + System.err.println("Error reading the file: " + e.getMessage()); + } + } + /* !!! Else Branch ist nicht zur Verwendung vorgesehen, immer mit args starten !!! + else { + try { + CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/input/CompilerInput.java")); + compileFile(codeCharStream); + } catch (IOException e) { + System.err.println("Error reading the file: " + e.getMessage()); + } + } + */ + } + + /** + * This method is used to compile a file from a given CharStream and output the bytecode to a specified directory. + * It goes through the following steps: + *

1. Scanner: It uses the SimpleJavaLexer to tokenize the input CharStream. + *

2. Parser: It uses the SimpleJavaParser to parse the tokens and generate a ParseTree. + *

3. AST Builder: It uses the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST). + *

4. Semantic Analyzer: It uses the SemanticAnalyzer to generate a typed AST. + *

5. Bytecode Generator: It uses the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory. + * + * @param inputCharStream The CharStream representing the input file to be compiled. + * @param outputDirectoryPath The path of the directory where the output bytecode should be written. + */ + static void compileFile(CharStream inputCharStream, String outputDirectoryPath) { + // Initialize the logger + new RaupenLogger(); + + /* ------------------------- Scanner -> tokens ------------------------- */ + // Use the SimpleJavaLexer to tokenize the input CharStream + SimpleJavaLexer lexer = new SimpleJavaLexer(inputCharStream); + CommonTokenStream tokenStream = new CommonTokenStream(lexer); + tokenStream.fill(); + // Log the tokens + RaupenLogger.logScanner(tokenStream); + + /*------------------------- Parser -> Parsetree -------------------------*/ + // Use the SimpleJavaParser to parse the tokens and generate a ParseTree + SimpleJavaParser parser = new SimpleJavaParser(tokenStream); + ParseTree parseTree = parser.program(); // parse the input + // Log the ParseTree + RaupenLogger.logParser(parseTree, parser); + + /*------------------------- AST builder -> AST -------------------------*/ + // Use the ASTBuilder to visit the ParseTree and generate an Abstract Syntax Tree (AST) + ASTBuilder astBuilder = new ASTBuilder(); + ASTNode abstractSyntaxTree = astBuilder.visit(parseTree); + // Log the AST + RaupenLogger.logAST(abstractSyntaxTree); + + /*------------------------- Semantic Analyzer -> typed AST -------------------------*/ + // Use the SemanticAnalyzer to generate a typed AST + ASTNode typedAst = SemanticAnalyzer.generateTast(abstractSyntaxTree); + // Log the typed AST + RaupenLogger.logSemanticAnalyzer(typedAst); + + /*------------------------- Bytecode Generator -> Bytecode -------------------------*/ + // Use the ByteCodeGenerator to generate bytecode from the typed AST and output it to the specified directory + ByteCodeGenerator byteCodeGenerator = new ByteCodeGenerator(outputDirectoryPath); + assert typedAst != null; + byteCodeGenerator.visit((ProgramNode) typedAst); + // Log the bytecode generation + RaupenLogger.logBytecodeGenerator(); + } +} \ No newline at end of file diff --git a/src/main/java/RaupenLogger.java b/src/main/java/main/RaupenLogger.java similarity index 99% rename from src/main/java/RaupenLogger.java rename to src/main/java/main/RaupenLogger.java index 5d17415..4ea499f 100644 --- a/src/main/java/RaupenLogger.java +++ b/src/main/java/main/RaupenLogger.java @@ -1,3 +1,5 @@ +package main; + import ast.ASTNode; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.Parser; diff --git a/src/test/Makefile b/src/test/Makefile index b9c9ecb..e3e7d75 100644 --- a/src/test/Makefile +++ b/src/test/Makefile @@ -8,8 +8,8 @@ compile-javac: javac -d .\resources\output\javac .\resources\input\CompilerInput.java compile-raupenpiler: - cd ../.. ; mvn -DskipTests package - cd ../.. ; mvn exec:java -Dexec.mainClass="Main" -Dexec.args="'src/main/resources/input/CompilerInput.java' 'src/main/resources/output' " + cd ../.. ; mvn -DskipTests install + cd ../.. ; mvn exec:java -Dexec.mainClass="main.Main" -Dexec.args="'src/main/resources/input/CompilerInput.java' 'src/main/resources/output' " test: test-javac test-raupenpiler diff --git a/src/test/TestSpecs.md b/src/test/TestSpecs.md index cbdc1f5..0911765 100644 --- a/src/test/TestSpecs.md +++ b/src/test/TestSpecs.md @@ -78,8 +78,8 @@ Compiled Classfile wenn beides erfolgreich -- Ergebnis vom eigenen Compiler mithilfe von TestCompilerOutput ausführen -- (Ergebnis von javac mithilfe von TestCompilerOutput ausführen) +- Ergebnis vom eigenen Compiler mithilfe von main.TestCompilerOutput ausführen +- (Ergebnis von javac mithilfe von main.TestCompilerOutput ausführen) ### Andis Tipps: @@ -89,4 +89,4 @@ wenn beides erfolgreich - mvn package - javac tester // tester compilen - java tester // tester ausführen -- -> tester ist in unserem Fall TestCompilerOutput.java \ No newline at end of file +- -> tester ist in unserem Fall main.TestCompilerOutput.java \ No newline at end of file diff --git a/src/test/java/EmptyClassExample.java b/src/test/java/main/EmptyClassExample.java similarity index 65% rename from src/test/java/EmptyClassExample.java rename to src/test/java/main/EmptyClassExample.java index 9f54ec6..e7715be 100644 --- a/src/test/java/EmptyClassExample.java +++ b/src/test/java/main/EmptyClassExample.java @@ -1,3 +1,5 @@ +package main; + public class EmptyClassExample { private class Inner { } diff --git a/src/test/java/FailureTest.java b/src/test/java/main/FailureTest.java similarity index 97% rename from src/test/java/FailureTest.java rename to src/test/java/main/FailureTest.java index f131e33..5a2e1c8 100644 --- a/src/test/java/FailureTest.java +++ b/src/test/java/main/FailureTest.java @@ -1,3 +1,5 @@ +package main; + import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -62,7 +64,7 @@ public class FailureTest { void typedASTTest() throws IOException { CharStream codeCharStream = null; try { - codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/EmptyClassExample.java")); + codeCharStream = CharStreams.fromPath(Paths.get("src/main/test/resources/main/EmptyClassExample.java")); Main.compileFile(codeCharStream, "src/main/test/resources/output"); } catch (IOException e) { System.err.println("Error reading the file: " + e.getMessage()); diff --git a/src/test/java/MainTest.java b/src/test/java/main/MainTest.java similarity index 97% rename from src/test/java/MainTest.java rename to src/test/java/main/MainTest.java index eec63b0..363fa35 100644 --- a/src/test/java/MainTest.java +++ b/src/test/java/main/MainTest.java @@ -1,3 +1,5 @@ +package main; + import org.junit.jupiter.api.Test; import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; diff --git a/src/test/java/TestCompilerOutput.java b/src/test/java/main/TestCompilerOutput.java similarity index 86% rename from src/test/java/TestCompilerOutput.java rename to src/test/java/main/TestCompilerOutput.java index 6a7c031..6a30e14 100644 --- a/src/test/java/TestCompilerOutput.java +++ b/src/test/java/main/TestCompilerOutput.java @@ -1,11 +1,13 @@ +package main; + /** * This class is used to test the output of the compiler. * - *

Im gleichen Ordner wie diese Datei (TestCompilerOutput.java) muss die selbst kompilierte CompilerInput.class Datei sein. + *

Im gleichen Ordner wie diese Datei (main.TestCompilerOutput.java) muss die selbst kompilierte CompilerInput.class Datei sein. *
Hinweis: Diese muss man also vom Ordner main/resources/output in diesen Ordner hier (test/java) rein kopieren. (bis es eine bessere Lösung gibt)

* *

Die selbst kompilierte .class Datei wird dann hier drin geladen und eine Instanz von ihr erstellt, es können auch Methoden aufgerufen werden. - *

Diese TestCompilerOutput.java Datei wird dann in \src\test\java> mit javac .\TestCompilerOutput.java kompiliert und mit java TestCompilerOutput ausgeführt. + *

Diese main.TestCompilerOutput.java Datei wird dann in \src\test\java> mit javac .\main.TestCompilerOutput.java kompiliert und mit java main.TestCompilerOutput ausgeführt. * Wenn unser Compiler funktioniert, sollten keine Errors kommen (sondern nur die Ausgaben, die wir in der CompilerInput.java Datei gemacht haben, * oder Methoden, die wir hier aufrufen).

* -- 2.34.1 From 8cc67080ecd2f22608ce4650538314d6159a6560 Mon Sep 17 00:00:00 2001 From: Lucas <89882946+notbad3500@users.noreply.github.com> Date: Wed, 19 Jun 2024 17:09:38 +0200 Subject: [PATCH 14/14] Small changes --- .gitignore | 4 ++++ pom.xml | 5 ++--- src/main/java/main/Main.java | 8 ++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 8f74459..8c5079b 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,7 @@ fabric.properties /target src/main/resources/logs/RaupenLog.log src/main/resources/output/CompilerInput.class +src/test/resources/output/javac/CompilerInput$Test.class +src/test/resources/output/javac/CompilerInput.class +src/test/resources/output/raupenpiler/CompilerInput.class +src/test/resources/output/raupenpiler/CompilerInput$Test.class diff --git a/pom.xml b/pom.xml index 27cbd7f..0baf035 100644 --- a/pom.xml +++ b/pom.xml @@ -4,9 +4,9 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - org.example + de.dhbw-stuttgart JavaCompiler - 1.0-SNAPSHOT + 1.0 22 @@ -69,5 +69,4 @@ - \ No newline at end of file diff --git a/src/main/java/main/Main.java b/src/main/java/main/Main.java index 5384677..8b858b4 100644 --- a/src/main/java/main/Main.java +++ b/src/main/java/main/Main.java @@ -20,15 +20,15 @@ import java.nio.file.Paths; *

cd .\src\test\ *

make clean compile-raupenpiler *

Start Raupenpiler using jar: - *

java.exe -jar .\target\JavaCompiler-1.0-SNAPSHOT-jar-with-dependencies.jar 'path_to_input_file.java' 'path_to_output_directory' - *

Example: + *

java.exe -jar path_to_jar\JavaCompiler-1.0-SNAPSHOT-jar-with-dependencies.jar 'path_to_input_file.java' 'path_to_output_directory' + *

Example (jar needs to be in the target directory, compile with make or mvn package first): * java.exe -jar .\target\JavaCompiler-1.0-SNAPSHOT-jar-with-dependencies.jar 'src/main/resources/input/CompilerInput.java' 'src/main/resources/output' */ public class Main { public static void main(String[] args) throws Exception { - if (args.length > 0) { + if (args.length == 2) { // args[0] is the input file path // args[1] is the output directory path String inputFilePath = args[0]; @@ -41,7 +41,7 @@ public class Main { System.err.println("Error reading the file: " + e.getMessage()); } } - /* !!! Else Branch ist nicht zur Verwendung vorgesehen, immer mit args starten !!! + /* !!! Else Branch (main ohne args starten) ist nicht zur Verwendung vorgesehen, immer mit args starten !!! else { try { CharStream codeCharStream = CharStreams.fromPath(Paths.get("src/main/resources/input/CompilerInput.java")); -- 2.34.1