Tests, Structure, More #10

Merged
i22005 merged 15 commits from Tests into main 2024-06-21 16:16:54 +00:00
5 changed files with 212 additions and 37 deletions
Showing only changes of commit f59d7e9918 - Show all commits

View File

@ -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 --------------------");
i22011 marked this conversation as resolved Outdated

Können wir die ganze Ausgabe in ne extra Klasse auzslagern? Des macht die Main Klasse bissle arg unübersichtlich. Außerdem gehört des nacher nicht in den Endgültigen Compiler.

Können wir die ganze Ausgabe in ne extra Klasse auzslagern? Des macht die Main Klasse bissle arg unübersichtlich. Außerdem gehört des nacher nicht in den Endgültigen Compiler.
List<Token> 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 --------------------");
i22011 marked this conversation as resolved Outdated

Same Here

Same Here
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 -------------------------*/

View File

@ -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

View File

@ -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,11 +77,12 @@ 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
- java -jar pfadtocompiler.jar EmptyClass.java

View File

@ -15,17 +15,17 @@ import java.util.List;
public class FailureTest {
private static final List<String> 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"
);
/**

View File

@ -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<Token> actualTokens = tokenStream.getTokens();
List<String> expectedTokens = Arrays.asList("public", "class", "Name", "{", "}", "<EOF>");
List<String> 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<String, Object> actualTreeStructure = buildTreeStructure(parseTree, parser);
Map<String, Object> 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<String, Object> buildTreeStructure(ParseTree tree, Parser parser) {
return buildTree(tree, parser, 0);
}
private static Map<String, Object> buildTree(ParseTree tree, Parser parser, int indent) {
Map<String, Object> 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<Map<String, Object>> 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<String, Object> 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<String, Object> parse(String input) {
Map<String, Object> node = new HashMap<>();
StringBuilder currentToken = new StringBuilder();
List<Map<String, Object>> 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;
}
}