First Tests for Parser, pls check
Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled

This commit is contained in:
Lucas 2024-06-17 17:42:50 +02:00
parent 0732712e61
commit f59d7e9918
5 changed files with 212 additions and 37 deletions

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 --------------------");
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 --------------------");
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,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

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;
}
}