renamings
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
import lexer.StupsLexer;
|
import lexer.StupsLexer;
|
||||||
import org.antlr.v4.runtime.CharStreams;
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
import org.antlr.v4.runtime.Lexer;
|
import org.antlr.v4.runtime.Lexer;
|
||||||
import parser.LL1Parser;
|
import parser.Parser;
|
||||||
import parser.grammar.Grammar;
|
import parser.grammar.Grammar;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -50,7 +50,7 @@ public final class StupsCompiler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(grammar);
|
Parser parser = Parser.fromGrammar(grammar);
|
||||||
|
|
||||||
parser.parse(lexer.getAllTokens(), lexer.getVocabulary());
|
parser.parse(lexer.getAllTokens(), lexer.getVocabulary());
|
||||||
|
|
||||||
|
|||||||
@ -4,13 +4,13 @@ import parser.ast.AST;
|
|||||||
|
|
||||||
import static util.Logger.log;
|
import static util.Logger.log;
|
||||||
|
|
||||||
public class MyParseException extends RuntimeException {
|
public class ParseException extends RuntimeException {
|
||||||
|
|
||||||
public MyParseException(String message) {
|
public ParseException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MyParseException(String message, AST ast) {
|
public ParseException(String message, AST ast) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|
||||||
log("\nAST at last state:\n" + ast);
|
log("\nAST at last state:\n" + ast);
|
||||||
@ -3,9 +3,9 @@ package parser;
|
|||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
import org.antlr.v4.runtime.Vocabulary;
|
import org.antlr.v4.runtime.Vocabulary;
|
||||||
import parser.ast.AST;
|
import parser.ast.AST;
|
||||||
import parser.ast.Node;
|
import parser.ast.ASTNode;
|
||||||
import parser.grammar.Grammar;
|
import parser.grammar.Grammar;
|
||||||
import parser.grammar.LL1GrammarAnalyzer;
|
import parser.grammar.GrammarAnalyzer;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@ -15,27 +15,27 @@ import java.util.List;
|
|||||||
|
|
||||||
import static util.Logger.log;
|
import static util.Logger.log;
|
||||||
|
|
||||||
public class LL1Parser {
|
public class Parser {
|
||||||
|
|
||||||
private final LL1ParsingTable parsetable;
|
private final ParsingTable parsetable;
|
||||||
|
|
||||||
public LL1Parser(LL1ParsingTable parsetable) {
|
public Parser(ParsingTable parsetable) {
|
||||||
this.parsetable = parsetable;
|
this.parsetable = parsetable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LL1Parser fromGrammar(Path path) throws IOException {
|
public static Parser fromGrammar(Path path) throws IOException {
|
||||||
return LL1Parser.fromGrammar(Grammar.fromFile(path));
|
return Parser.fromGrammar(Grammar.fromFile(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LL1Parser fromGrammar(Grammar grammar) {
|
public static Parser fromGrammar(Grammar grammar) {
|
||||||
LL1GrammarAnalyzer analyzer = new LL1GrammarAnalyzer(grammar);
|
GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar);
|
||||||
return new LL1Parser(analyzer.getTable());
|
return new Parser(analyzer.getTable());
|
||||||
}
|
}
|
||||||
|
|
||||||
public AST parse(List<? extends Token> token, Vocabulary voc) {
|
public AST parse(List<? extends Token> token, Vocabulary voc) {
|
||||||
Node root = new Node(this.parsetable.getStartSymbol());
|
ASTNode root = new ASTNode(this.parsetable.getStartSymbol());
|
||||||
AST tree = new AST(root);
|
AST tree = new AST(root);
|
||||||
Deque<Node> stack = new ArrayDeque<>();
|
Deque<ASTNode> stack = new ArrayDeque<>();
|
||||||
stack.push(root);
|
stack.push(root);
|
||||||
|
|
||||||
int inputPosition = 0;
|
int inputPosition = 0;
|
||||||
@ -75,24 +75,24 @@ public class LL1Parser {
|
|||||||
|
|
||||||
System.out.println("Syntaxfehler.");
|
System.out.println("Syntaxfehler.");
|
||||||
|
|
||||||
throw new MyParseException("Invalid terminal on stack: " + top, tree);
|
throw new ParseException("Invalid terminal on stack: " + top, tree);
|
||||||
} else if (prod == null) {
|
} else if (prod == null) {
|
||||||
// Wenn es für das aktuelle Terminal und das Nichtterminal auf dem Stack keine Regel gibt
|
// Wenn es für das aktuelle Terminal und das Nichtterminal auf dem Stack keine Regel gibt
|
||||||
|
|
||||||
System.out.println("Syntaxfehler.");
|
System.out.println("Syntaxfehler.");
|
||||||
|
|
||||||
throw new MyParseException("No prod. for nonterminal " + top + ", terminal " + currentTokenSym, tree);
|
throw new ParseException("No prod. for nonterminal " + top + ", terminal " + currentTokenSym, tree);
|
||||||
} else {
|
} else {
|
||||||
// Wenn das Nichtterminal auf dem Stack durch (s)eine Produktion ersetzt werden kann
|
// Wenn das Nichtterminal auf dem Stack durch (s)eine Produktion ersetzt werden kann
|
||||||
// Hier wird auch der AST aufgebaut
|
// Hier wird auch der AST aufgebaut
|
||||||
|
|
||||||
log("Used: " + top + " -> " + prod);
|
log("Used: " + top + " -> " + prod);
|
||||||
Node pop = stack.pop();
|
ASTNode pop = stack.pop();
|
||||||
|
|
||||||
final String[] split = prod.split(" ");
|
final String[] split = prod.split(" ");
|
||||||
|
|
||||||
for (int i = split.length - 1; i >= 0; i--) {
|
for (int i = split.length - 1; i >= 0; i--) {
|
||||||
Node node = new Node(split[i]);
|
ASTNode ASTNode = new ASTNode(split[i]);
|
||||||
|
|
||||||
if (inputPosition + i < token.size()) {
|
if (inputPosition + i < token.size()) {
|
||||||
// Die Schleife geht in der Eingabe weiter
|
// Die Schleife geht in der Eingabe weiter
|
||||||
@ -100,12 +100,12 @@ public class LL1Parser {
|
|||||||
|
|
||||||
// Die Token mit semantischem Inhalt auswählen
|
// Die Token mit semantischem Inhalt auswählen
|
||||||
if ("IDENTIFIER".equals(split[i]) || split[i].endsWith("_LIT")) {
|
if ("IDENTIFIER".equals(split[i]) || split[i].endsWith("_LIT")) {
|
||||||
node.setValue(currentTok.getText());
|
ASTNode.setValue(currentTok.getText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stack.push(node);
|
stack.push(ASTNode);
|
||||||
pop.addChild(node);
|
pop.addChild(ASTNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package parser;
|
package parser;
|
||||||
|
|
||||||
import parser.grammar.Grammar;
|
import parser.grammar.Grammar;
|
||||||
import parser.grammar.LL1GrammarAnalyzer;
|
import parser.grammar.GrammarAnalyzer;
|
||||||
|
|
||||||
import java.util.AbstractMap.SimpleEntry;
|
import java.util.AbstractMap.SimpleEntry;
|
||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
@ -12,18 +12,18 @@ import java.util.Map.Entry;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class LL1ParsingTable {
|
public class ParsingTable {
|
||||||
|
|
||||||
private final Grammar grammar;
|
private final Grammar grammar;
|
||||||
private final Map<Entry<String, String>, String> parsetable;
|
private final Map<Entry<String, String>, String> parsetable;
|
||||||
|
|
||||||
public LL1ParsingTable(Grammar grammar, Map<Entry<String, String>, String> parsetable) {
|
public ParsingTable(Grammar grammar, Map<Entry<String, String>, String> parsetable) {
|
||||||
this.grammar = grammar;
|
this.grammar = grammar;
|
||||||
this.parsetable = parsetable;
|
this.parsetable = parsetable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LL1ParsingTable fromGrammar(Grammar grammar) {
|
public static ParsingTable fromGrammar(Grammar grammar) {
|
||||||
LL1GrammarAnalyzer analyzer = new LL1GrammarAnalyzer(grammar);
|
GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar);
|
||||||
return analyzer.getTable();
|
return analyzer.getTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6,13 +6,13 @@ import java.util.Objects;
|
|||||||
|
|
||||||
public class AST {
|
public class AST {
|
||||||
|
|
||||||
private final Node root;
|
private final ASTNode root;
|
||||||
|
|
||||||
public AST(Node root) {
|
public AST(ASTNode root) {
|
||||||
this.root = root;
|
this.root = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node getRoot() {
|
public ASTNode getRoot() {
|
||||||
return this.root;
|
return this.root;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ public class AST {
|
|||||||
|
|
||||||
public void preprocess(Grammar grammar) {
|
public void preprocess(Grammar grammar) {
|
||||||
ASTCompacter.clean(this, grammar);
|
ASTCompacter.clean(this, grammar);
|
||||||
ExpressionBalancer.balance(this);
|
ASTBalancer.balance(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -6,9 +6,9 @@ import java.util.Collections;
|
|||||||
|
|
||||||
import static util.Logger.log;
|
import static util.Logger.log;
|
||||||
|
|
||||||
public final class ExpressionBalancer {
|
public final class ASTBalancer {
|
||||||
|
|
||||||
private ExpressionBalancer() {}
|
private ASTBalancer() {}
|
||||||
|
|
||||||
public static void balance(AST tree) {
|
public static void balance(AST tree) {
|
||||||
flip(tree);
|
flip(tree);
|
||||||
@ -25,8 +25,8 @@ public final class ExpressionBalancer {
|
|||||||
flip(tree.getRoot());
|
flip(tree.getRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void flip(Node root) {
|
private static void flip(ASTNode root) {
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
flip(child);
|
flip(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,12 +41,12 @@ public final class ExpressionBalancer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Es wird solange rotiert bis die letzte "Rotation" durchgeführt wurde
|
// Es wird solange rotiert bis die letzte "Rotation" durchgeführt wurde
|
||||||
private static void leftPrecedence(Node root) {
|
private static void leftPrecedence(ASTNode root) {
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
leftPrecedence(child);
|
leftPrecedence(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node expr = getExpr(root);
|
ASTNode expr = getExpr(root);
|
||||||
|
|
||||||
if (expr == null || root.getChildren().size() != 2 || !root.getValue().isEmpty()) {
|
if (expr == null || root.getChildren().size() != 2 || !root.getValue().isEmpty()) {
|
||||||
return;
|
return;
|
||||||
@ -60,9 +60,9 @@ public final class ExpressionBalancer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Die Letzte Rotation ist keine richtige Rotation, dort wird false zurückgegeben
|
// Die Letzte Rotation ist keine richtige Rotation, dort wird false zurückgegeben
|
||||||
private static boolean specialLeftRotate(Node root) {
|
private static boolean specialLeftRotate(ASTNode root) {
|
||||||
Node left = root.getChildren().get(0);
|
ASTNode left = root.getChildren().get(0);
|
||||||
Node right = root.getChildren().get(1);
|
ASTNode right = root.getChildren().get(1);
|
||||||
|
|
||||||
// Verhindert Wurzel mit nur einem EXPR-Child (nach oben "hängende" Wurzel)
|
// Verhindert Wurzel mit nur einem EXPR-Child (nach oben "hängende" Wurzel)
|
||||||
if (endOfExpr(right)) {
|
if (endOfExpr(right)) {
|
||||||
@ -72,7 +72,7 @@ public final class ExpressionBalancer {
|
|||||||
return false; // Braucht keine weitere Rotation
|
return false; // Braucht keine weitere Rotation
|
||||||
}
|
}
|
||||||
|
|
||||||
Node insertLeft = new Node(root.getName());
|
ASTNode insertLeft = new ASTNode(root.getName());
|
||||||
insertLeft.setValue(right.getValue()); // Operation wird linksvererbt
|
insertLeft.setValue(right.getValue()); // Operation wird linksvererbt
|
||||||
insertLeft.setChildren(left, right.getChildren().get(0));
|
insertLeft.setChildren(left, right.getChildren().get(0));
|
||||||
|
|
||||||
@ -82,8 +82,8 @@ public final class ExpressionBalancer {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Node getExpr(Node root) {
|
private static ASTNode getExpr(ASTNode root) {
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
if (child.getName().equals("EXPR")) {
|
if (child.getName().equals("EXPR")) {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ public final class ExpressionBalancer {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean endOfExpr(Node root) {
|
private static boolean endOfExpr(ASTNode root) {
|
||||||
return root.getChildren().size() == 1;
|
return root.getChildren().size() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,8 +108,8 @@ public final class ExpressionBalancer {
|
|||||||
operatorPrecedence(tree.getRoot());
|
operatorPrecedence(tree.getRoot());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void operatorPrecedence(Node root) {
|
public static void operatorPrecedence(ASTNode root) {
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
operatorPrecedence(child);
|
operatorPrecedence(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,8 +118,8 @@ public final class ExpressionBalancer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean preceding(Node root) {
|
private static boolean preceding(ASTNode root) {
|
||||||
Node op = getExpr(root);
|
ASTNode op = getExpr(root);
|
||||||
|
|
||||||
if (op == null || !root.getName().equals("EXPR") || root.getValue().isEmpty()) {
|
if (op == null || !root.getName().equals("EXPR") || root.getValue().isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
@ -134,11 +134,11 @@ public final class ExpressionBalancer {
|
|||||||
|| (logHigh.contains(root.getValue()) && logLow.contains(op.getValue()));
|
|| (logHigh.contains(root.getValue()) && logLow.contains(op.getValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void simpleRightRotate(Node root) {
|
private static void simpleRightRotate(ASTNode root) {
|
||||||
Node left = root.getChildren().get(0);
|
ASTNode left = root.getChildren().get(0);
|
||||||
Node right = root.getChildren().get(1);
|
ASTNode right = root.getChildren().get(1);
|
||||||
|
|
||||||
Node insertRight = new Node(root.getName());
|
ASTNode insertRight = new ASTNode(root.getName());
|
||||||
insertRight.setValue(root.getValue());
|
insertRight.setValue(root.getValue());
|
||||||
insertRight.setChildren(left.getChildren().get(1), right);
|
insertRight.setChildren(left.getChildren().get(1), right);
|
||||||
|
|
||||||
@ -53,11 +53,11 @@ public final class ASTCompacter {
|
|||||||
return compacted;
|
return compacted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int compact(Node root, Grammar grammar) {
|
private static int compact(ASTNode root, Grammar grammar) {
|
||||||
int compacted = 0;
|
int compacted = 0;
|
||||||
Collection<Node> toRemove = new HashSet<>();
|
Collection<ASTNode> toRemove = new HashSet<>();
|
||||||
|
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
if (grammar.hasCompact(root.getName())
|
if (grammar.hasCompact(root.getName())
|
||||||
&& root.getChildren().size() == 1) {
|
&& root.getChildren().size() == 1) {
|
||||||
|
|
||||||
@ -91,11 +91,11 @@ public final class ASTCompacter {
|
|||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int removeNullable(Node root, Grammar grammar) {
|
private static int removeNullable(ASTNode root, Grammar grammar) {
|
||||||
int removed = 0;
|
int removed = 0;
|
||||||
Collection<Node> toRemove = new HashSet<>();
|
Collection<ASTNode> toRemove = new HashSet<>();
|
||||||
|
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
if (grammar.hasNullable(child.getName())
|
if (grammar.hasNullable(child.getName())
|
||||||
&& child.getValue().isEmpty()
|
&& child.getValue().isEmpty()
|
||||||
&& !child.hasChildren()) {
|
&& !child.hasChildren()) {
|
||||||
@ -125,11 +125,11 @@ public final class ASTCompacter {
|
|||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int removeEpsilon(Node root, Grammar grammar) {
|
private static int removeEpsilon(ASTNode root, Grammar grammar) {
|
||||||
int removed = 0;
|
int removed = 0;
|
||||||
Collection<Node> toRemove = new HashSet<>();
|
Collection<ASTNode> toRemove = new HashSet<>();
|
||||||
|
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
if (child.getName().equals(grammar.getEpsilonSymbol()) && !child.hasChildren()) {
|
if (child.getName().equals(grammar.getEpsilonSymbol()) && !child.hasChildren()) {
|
||||||
log("Removing " + root.getName() + " -> " + child.getName());
|
log("Removing " + root.getName() + " -> " + child.getName());
|
||||||
toRemove.add(child);
|
toRemove.add(child);
|
||||||
@ -155,13 +155,13 @@ public final class ASTCompacter {
|
|||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int removeRedundant(Node root) {
|
private static int removeRedundant(ASTNode root) {
|
||||||
int removed = 0;
|
int removed = 0;
|
||||||
Collection<Node> toRemove = new HashSet<>();
|
Collection<ASTNode> toRemove = new HashSet<>();
|
||||||
|
|
||||||
Collection<String> removable = Arrays.asList("IF", "ELSE", "WHILE", "ASSIGN");
|
Collection<String> removable = Arrays.asList("IF", "ELSE", "WHILE", "ASSIGN");
|
||||||
|
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
if (removable.contains(child.getName()) && !child.hasChildren()) {
|
if (removable.contains(child.getName()) && !child.hasChildren()) {
|
||||||
log("Removing " + root.getName() + " -> " + child.getName());
|
log("Removing " + root.getName() + " -> " + child.getName());
|
||||||
toRemove.add(child);
|
toRemove.add(child);
|
||||||
@ -182,7 +182,7 @@ public final class ASTCompacter {
|
|||||||
log("-".repeat(100));
|
log("-".repeat(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void renameEXPR(Node root) {
|
private static void renameEXPR(ASTNode root) {
|
||||||
String newName = switch (root.getName()) {
|
String newName = switch (root.getName()) {
|
||||||
case "EXPR_2", "EXPR_F" -> "EXPR";
|
case "EXPR_2", "EXPR_F" -> "EXPR";
|
||||||
default -> root.getName();
|
default -> root.getName();
|
||||||
@ -194,7 +194,7 @@ public final class ASTCompacter {
|
|||||||
|
|
||||||
root.setName(newName);
|
root.setName(newName);
|
||||||
|
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
renameEXPR(child);
|
renameEXPR(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,12 +206,12 @@ public final class ASTCompacter {
|
|||||||
log("-".repeat(100));
|
log("-".repeat(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void moveOperatorToEXPR(Node root) {
|
private static void moveOperatorToEXPR(ASTNode root) {
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
moveOperatorToEXPR(child);
|
moveOperatorToEXPR(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node op = getOp(root);
|
ASTNode op = getOp(root);
|
||||||
|
|
||||||
if (op == null || !"EXPR".equals(root.getName())) {
|
if (op == null || !"EXPR".equals(root.getName())) {
|
||||||
return;
|
return;
|
||||||
@ -222,9 +222,9 @@ public final class ASTCompacter {
|
|||||||
root.getChildren().remove(op);
|
root.getChildren().remove(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Node getOp(Node root) {
|
private static ASTNode getOp(ASTNode root) {
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
Node op = switch (child.getName()) {
|
ASTNode op = switch (child.getName()) {
|
||||||
case "ADD", "SUB", "MUL", "DIV", "MOD" -> child;
|
case "ADD", "SUB", "MUL", "DIV", "MOD" -> child;
|
||||||
case "NOT", "AND", "OR" -> child;
|
case "NOT", "AND", "OR" -> child;
|
||||||
case "LESS", "LESS_EQUAL", "GREATER", "GREATER_EQUAL", "EQUAL", "NOT_EQUAL" -> child;
|
case "LESS", "LESS_EQUAL", "GREATER", "GREATER_EQUAL", "EQUAL", "NOT_EQUAL" -> child;
|
||||||
@ -245,12 +245,12 @@ public final class ASTCompacter {
|
|||||||
log("-".repeat(100));
|
log("-".repeat(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void moveIdentifierToASSIGNMENT(Node root) {
|
private static void moveIdentifierToASSIGNMENT(ASTNode root) {
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
moveIdentifierToASSIGNMENT(child);
|
moveIdentifierToASSIGNMENT(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node id = getId(root);
|
ASTNode id = getId(root);
|
||||||
|
|
||||||
if (id == null || !"ASSIGNMENT".equals(root.getName())) {
|
if (id == null || !"ASSIGNMENT".equals(root.getName())) {
|
||||||
return;
|
return;
|
||||||
@ -261,8 +261,8 @@ public final class ASTCompacter {
|
|||||||
root.getChildren().remove(id);
|
root.getChildren().remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Node getId(Node root) {
|
private static ASTNode getId(ASTNode root) {
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
if (child.getName().equals("IDENTIFIER")) {
|
if (child.getName().equals("IDENTIFIER")) {
|
||||||
return child;
|
return child;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,26 +6,26 @@ import java.util.Iterator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class Node {
|
public class ASTNode {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private String value;
|
private String value;
|
||||||
private List<Node> children = new ArrayList<>();
|
private List<ASTNode> children = new ArrayList<>();
|
||||||
|
|
||||||
public Node(String name) {
|
public ASTNode(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.value = "";
|
this.value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addChild(Node node) {
|
public void addChild(ASTNode ASTNode) {
|
||||||
this.children.add(node);
|
this.children.add(ASTNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasChildren() {
|
public boolean hasChildren() {
|
||||||
return !this.children.isEmpty();
|
return !this.children.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Node> getChildren() {
|
public List<ASTNode> getChildren() {
|
||||||
return this.children;
|
return this.children;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +54,19 @@ public class Node {
|
|||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setChildren(List<ASTNode> children) {
|
||||||
|
this.children = children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildren(ASTNode... children) {
|
||||||
|
this.children = new ArrayList<>();
|
||||||
|
this.children.addAll(Arrays.asList(children));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
private void print(StringBuilder buffer, String prefix, String childrenPrefix) {
|
private void print(StringBuilder buffer, String prefix, String childrenPrefix) {
|
||||||
buffer.append(prefix);
|
buffer.append(prefix);
|
||||||
buffer.append(this.name);
|
buffer.append(this.name);
|
||||||
@ -63,8 +76,8 @@ public class Node {
|
|||||||
}
|
}
|
||||||
buffer.append('\n');
|
buffer.append('\n');
|
||||||
|
|
||||||
for (Iterator<Node> it = this.children.listIterator(); it.hasNext(); ) {
|
for (Iterator<ASTNode> it = this.children.listIterator(); it.hasNext(); ) {
|
||||||
Node next = it.next();
|
ASTNode next = it.next();
|
||||||
if (it.hasNext()) {
|
if (it.hasNext()) {
|
||||||
next.print(buffer, childrenPrefix + "├── ", childrenPrefix + "│ ");
|
next.print(buffer, childrenPrefix + "├── ", childrenPrefix + "│ ");
|
||||||
} else {
|
} else {
|
||||||
@ -75,32 +88,19 @@ public class Node {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (obj instanceof Node) {
|
if (obj instanceof ASTNode) {
|
||||||
return this.name.equals(((Node) obj).name)
|
return this.name.equals(((ASTNode) obj).name)
|
||||||
&& this.value.equals(((Node) obj).value)
|
&& this.value.equals(((ASTNode) obj).value)
|
||||||
&& this.children.equals(((Node) obj).children);
|
&& this.children.equals(((ASTNode) obj).children);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChildren(List<Node> children) {
|
|
||||||
this.children = children;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChildren(Node... children) {
|
|
||||||
this.children = new ArrayList<>();
|
|
||||||
this.children.addAll(Arrays.asList(children));
|
|
||||||
}
|
|
||||||
|
|
||||||
public long size() {
|
public long size() {
|
||||||
int s = 0;
|
int s = 0;
|
||||||
|
|
||||||
for (Node child : this.children) {
|
for (ASTNode child : this.children) {
|
||||||
s += child.size();
|
s += child.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
package parser.grammar;
|
|
||||||
|
|
||||||
public enum Actions {
|
|
||||||
COMPACT,
|
|
||||||
NULLABLE
|
|
||||||
}
|
|
||||||
@ -9,8 +9,8 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static parser.grammar.Actions.COMPACT;
|
import static parser.grammar.GrammarActions.COMPACT;
|
||||||
import static parser.grammar.Actions.NULLABLE;
|
import static parser.grammar.GrammarActions.NULLABLE;
|
||||||
import static util.Logger.log;
|
import static util.Logger.log;
|
||||||
|
|
||||||
public class Grammar {
|
public class Grammar {
|
||||||
@ -96,7 +96,7 @@ public class Grammar {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
// Check for action validity
|
// Check for action validity
|
||||||
List<String> enumActions = Arrays.stream(Actions.values())
|
List<String> enumActions = Arrays.stream(GrammarActions.values())
|
||||||
.map(action -> action.toString().toLowerCase())
|
.map(action -> action.toString().toLowerCase())
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
for (String flag : flagList) {
|
for (String flag : flagList) {
|
||||||
|
|||||||
8
src/main/java/parser/grammar/GrammarActions.java
Normal file
8
src/main/java/parser/grammar/GrammarActions.java
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package parser.grammar;
|
||||||
|
|
||||||
|
public enum GrammarActions {
|
||||||
|
COMPACT, // Ersetzt Node mit Child, wenn es nur ein Child gibt
|
||||||
|
NULLABLE, // Entfernt Node, wenn dieser keinen Inhalt hat
|
||||||
|
MOVE, // TODO: Setzt den Child-Namen als Parent-Value und löscht das Child
|
||||||
|
RENAME // TODO: Führt eine Umbenennung durch
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
package parser.grammar;
|
package parser.grammar;
|
||||||
|
|
||||||
import parser.LL1ParsingTable;
|
import parser.ParsingTable;
|
||||||
|
|
||||||
import java.util.AbstractMap;
|
import java.util.AbstractMap;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -16,16 +16,16 @@ import static util.Logger.log;
|
|||||||
import static util.Logger.logIfTrue;
|
import static util.Logger.logIfTrue;
|
||||||
import static util.Logger.logNullable;
|
import static util.Logger.logNullable;
|
||||||
|
|
||||||
public class LL1GrammarAnalyzer {
|
public class GrammarAnalyzer {
|
||||||
|
|
||||||
private final Grammar grammar;
|
private final Grammar grammar;
|
||||||
|
|
||||||
private final Map<String, Set<String>> first;
|
private final Map<String, Set<String>> first;
|
||||||
private final Map<String, Set<String>> follow;
|
private final Map<String, Set<String>> follow;
|
||||||
|
|
||||||
private final LL1ParsingTable table;
|
private final ParsingTable table;
|
||||||
|
|
||||||
public LL1GrammarAnalyzer(Grammar grammar) {
|
public GrammarAnalyzer(Grammar grammar) {
|
||||||
this.grammar = grammar;
|
this.grammar = grammar;
|
||||||
|
|
||||||
log("Analyzing Grammar:\n");
|
log("Analyzing Grammar:\n");
|
||||||
@ -214,7 +214,7 @@ public class LL1GrammarAnalyzer {
|
|||||||
return followOut;
|
return followOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LL1ParsingTable initParseTable() {
|
private ParsingTable initParseTable() {
|
||||||
Map<Map.Entry<String, String>, String> tableOut = new HashMap<>();
|
Map<Map.Entry<String, String>, String> tableOut = new HashMap<>();
|
||||||
|
|
||||||
log("Parsetable Aufstellen:");
|
log("Parsetable Aufstellen:");
|
||||||
@ -265,7 +265,7 @@ public class LL1GrammarAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final LL1ParsingTable table = new LL1ParsingTable(this.grammar, tableOut);
|
final ParsingTable table = new ParsingTable(this.grammar, tableOut);
|
||||||
|
|
||||||
log("\n" + table);
|
log("\n" + table);
|
||||||
log("-".repeat(100) + "\n");
|
log("-".repeat(100) + "\n");
|
||||||
@ -347,7 +347,7 @@ public class LL1GrammarAnalyzer {
|
|||||||
return this.follow;
|
return this.follow;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LL1ParsingTable getTable() {
|
public ParsingTable getTable() {
|
||||||
return this.table;
|
return this.table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package typechecker;
|
package typechecker;
|
||||||
|
|
||||||
import parser.ast.AST;
|
import parser.ast.AST;
|
||||||
import parser.ast.Node;
|
import parser.ast.ASTNode;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -48,14 +48,14 @@ public class SymbolTable {
|
|||||||
return new SymbolTable(tableOut);
|
return new SymbolTable(tableOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void scanTree(Node root, Map<String, String> table) {
|
private static void scanTree(ASTNode root, Map<String, String> table) {
|
||||||
for (Node child : root.getChildren()) {
|
for (ASTNode child : root.getChildren()) {
|
||||||
scanTree(child, table);
|
scanTree(child, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("DECLARATION".equals(root.getName())) {
|
if ("DECLARATION".equals(root.getName())) {
|
||||||
Node left = root.getChildren().get(0);
|
ASTNode left = root.getChildren().get(0);
|
||||||
Node right = root.getChildren().get(1);
|
ASTNode right = root.getChildren().get(1);
|
||||||
|
|
||||||
log("Adding Entry " + right.getValue() + " -> " + left.getName());
|
log("Adding Entry " + right.getValue() + " -> " + left.getName());
|
||||||
String oldEntry = table.put(right.getValue(), left.getName());
|
String oldEntry = table.put(right.getValue(), left.getName());
|
||||||
|
|||||||
8
src/main/java/typechecker/TypeMismatchException.java
Normal file
8
src/main/java/typechecker/TypeMismatchException.java
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package typechecker;
|
||||||
|
|
||||||
|
public class TypeMismatchException extends RuntimeException {
|
||||||
|
|
||||||
|
public TypeMismatchException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +0,0 @@
|
|||||||
package typechecker;
|
|
||||||
|
|
||||||
public class WrongTypeException extends RuntimeException {
|
|
||||||
|
|
||||||
public WrongTypeException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -5,8 +5,8 @@ import org.antlr.v4.runtime.CharStreams;
|
|||||||
import org.antlr.v4.runtime.Lexer;
|
import org.antlr.v4.runtime.Lexer;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import parser.ast.AST;
|
import parser.ast.AST;
|
||||||
|
import parser.ast.ASTBalancer;
|
||||||
import parser.ast.ASTCompacter;
|
import parser.ast.ASTCompacter;
|
||||||
import parser.ast.ExpressionBalancer;
|
|
||||||
import parser.grammar.Grammar;
|
import parser.grammar.Grammar;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -34,7 +34,7 @@ class Demo {
|
|||||||
void demoClean() throws URISyntaxException, IOException {
|
void demoClean() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
Grammar grammar = Grammar.fromFile(path);
|
Grammar grammar = Grammar.fromFile(path);
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(grammar);
|
Parser parser = Parser.fromGrammar(grammar);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("General.stups");
|
Lexer lex = this.initLexer("General.stups");
|
||||||
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
||||||
@ -46,15 +46,15 @@ class Demo {
|
|||||||
void demoLeftPrecedence() throws URISyntaxException, IOException {
|
void demoLeftPrecedence() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
Grammar grammar = Grammar.fromFile(path);
|
Grammar grammar = Grammar.fromFile(path);
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(grammar);
|
Parser parser = Parser.fromGrammar(grammar);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("General.stups");
|
Lexer lex = this.initLexer("General.stups");
|
||||||
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
||||||
|
|
||||||
ASTCompacter.clean(tree, grammar);
|
ASTCompacter.clean(tree, grammar);
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
System.out.println("Before left-precedence:\n" + tree);
|
System.out.println("Before left-precedence:\n" + tree);
|
||||||
ExpressionBalancer.leftPrecedence(tree);
|
ASTBalancer.leftPrecedence(tree);
|
||||||
System.out.println("After left-precedence:\n" + tree);
|
System.out.println("After left-precedence:\n" + tree);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,16 +62,16 @@ class Demo {
|
|||||||
void demoOperatorPrecedence() throws URISyntaxException, IOException {
|
void demoOperatorPrecedence() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
Grammar grammar = Grammar.fromFile(path);
|
Grammar grammar = Grammar.fromFile(path);
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(grammar);
|
Parser parser = Parser.fromGrammar(grammar);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("General.stups");
|
Lexer lex = this.initLexer("General.stups");
|
||||||
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
||||||
|
|
||||||
ASTCompacter.clean(tree, grammar);
|
ASTCompacter.clean(tree, grammar);
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
ExpressionBalancer.leftPrecedence(tree);
|
ASTBalancer.leftPrecedence(tree);
|
||||||
System.out.println("Before operator-precedence:\n" + tree);
|
System.out.println("Before operator-precedence:\n" + tree);
|
||||||
ExpressionBalancer.operatorPrecedence(tree);
|
ASTBalancer.operatorPrecedence(tree);
|
||||||
System.out.println("After operator-precedence:\n" + tree);
|
System.out.println("After operator-precedence:\n" + tree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@ class LexerParserGrammarTest {
|
|||||||
@Test
|
@Test
|
||||||
void testEmptyFile() throws URISyntaxException, IOException {
|
void testEmptyFile() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(path);
|
Parser parser = Parser.fromGrammar(path);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("EmptyFile.stups");
|
Lexer lex = this.initLexer("EmptyFile.stups");
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ class LexerParserGrammarTest {
|
|||||||
@Test
|
@Test
|
||||||
void testEmptyMain() throws URISyntaxException, IOException {
|
void testEmptyMain() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(path);
|
Parser parser = Parser.fromGrammar(path);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("EmptyMain.stups");
|
Lexer lex = this.initLexer("EmptyMain.stups");
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ class LexerParserGrammarTest {
|
|||||||
@Test
|
@Test
|
||||||
void testGeneralComment() throws URISyntaxException, IOException {
|
void testGeneralComment() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(path);
|
Parser parser = Parser.fromGrammar(path);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("GeneralComment.stups");
|
Lexer lex = this.initLexer("GeneralComment.stups");
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ class LexerParserGrammarTest {
|
|||||||
@Test
|
@Test
|
||||||
void tesMultiDecl() throws URISyntaxException, IOException {
|
void tesMultiDecl() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(path);
|
Parser parser = Parser.fromGrammar(path);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("MultipleDeclarations.stups");
|
Lexer lex = this.initLexer("MultipleDeclarations.stups");
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ class LexerParserGrammarTest {
|
|||||||
@Test
|
@Test
|
||||||
void testDeclarationAssignment() throws URISyntaxException, IOException {
|
void testDeclarationAssignment() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(path);
|
Parser parser = Parser.fromGrammar(path);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("DeclarationAssignment.stups");
|
Lexer lex = this.initLexer("DeclarationAssignment.stups");
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ class LexerParserGrammarTest {
|
|||||||
@Test
|
@Test
|
||||||
void testExpr() throws URISyntaxException, IOException {
|
void testExpr() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(path);
|
Parser parser = Parser.fromGrammar(path);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("Expr.stups");
|
Lexer lex = this.initLexer("Expr.stups");
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ class LexerParserGrammarTest {
|
|||||||
@Test
|
@Test
|
||||||
void testGeneralWhile() throws URISyntaxException, IOException {
|
void testGeneralWhile() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(path);
|
Parser parser = Parser.fromGrammar(path);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("GeneralWhile.stups");
|
Lexer lex = this.initLexer("GeneralWhile.stups");
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ class LexerParserGrammarTest {
|
|||||||
@Test
|
@Test
|
||||||
void testGeneralIfElse() throws URISyntaxException, IOException {
|
void testGeneralIfElse() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(path);
|
Parser parser = Parser.fromGrammar(path);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("GeneralIfElse.stups");
|
Lexer lex = this.initLexer("GeneralIfElse.stups");
|
||||||
|
|
||||||
|
|||||||
@ -4,22 +4,22 @@ import org.junit.jupiter.api.Test;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
class ExpressionBalancerTest {
|
class ASTBalancerTest {
|
||||||
|
|
||||||
//EXPR
|
//EXPR
|
||||||
//├── EXPR: SUB
|
//├── EXPR: SUB
|
||||||
//| └── INTEGER_LIT: 2
|
//| └── INTEGER_LIT: 2
|
||||||
//└── INTEGER_LIT: 1
|
//└── INTEGER_LIT: 1
|
||||||
private static AST tree1() {
|
private static AST tree1() {
|
||||||
AST tree = new AST(new Node("EXPR"));
|
AST tree = new AST(new ASTNode("EXPR"));
|
||||||
|
|
||||||
Node right = new Node("INTEGER_LIT");
|
ASTNode right = new ASTNode("INTEGER_LIT");
|
||||||
right.setValue("1");
|
right.setValue("1");
|
||||||
|
|
||||||
Node left = new Node("EXPR");
|
ASTNode left = new ASTNode("EXPR");
|
||||||
left.setValue("SUB");
|
left.setValue("SUB");
|
||||||
|
|
||||||
Node lleft = new Node("INTEGER_LIT");
|
ASTNode lleft = new ASTNode("INTEGER_LIT");
|
||||||
lleft.setValue("2");
|
lleft.setValue("2");
|
||||||
left.setChildren(lleft);
|
left.setChildren(lleft);
|
||||||
|
|
||||||
@ -29,21 +29,21 @@ class ExpressionBalancerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static AST tree2() {
|
private static AST tree2() {
|
||||||
AST tree = new AST(new Node("EXPR"));
|
AST tree = new AST(new ASTNode("EXPR"));
|
||||||
|
|
||||||
Node right = new Node("INTEGER_LIT");
|
ASTNode right = new ASTNode("INTEGER_LIT");
|
||||||
right.setValue("1");
|
right.setValue("1");
|
||||||
|
|
||||||
Node left = new Node("EXPR");
|
ASTNode left = new ASTNode("EXPR");
|
||||||
left.setValue("SUB");
|
left.setValue("SUB");
|
||||||
|
|
||||||
Node lleft = new Node("EXPR");
|
ASTNode lleft = new ASTNode("EXPR");
|
||||||
lleft.setValue("SUB");
|
lleft.setValue("SUB");
|
||||||
|
|
||||||
Node lright = new Node("INTEGER_LIT");
|
ASTNode lright = new ASTNode("INTEGER_LIT");
|
||||||
lright.setValue("2");
|
lright.setValue("2");
|
||||||
|
|
||||||
Node llleft = new Node("INTEGER_LIT");
|
ASTNode llleft = new ASTNode("INTEGER_LIT");
|
||||||
llleft.setValue("3");
|
llleft.setValue("3");
|
||||||
|
|
||||||
lleft.setChildren(llleft);
|
lleft.setChildren(llleft);
|
||||||
@ -55,21 +55,21 @@ class ExpressionBalancerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static AST tree3() {
|
private static AST tree3() {
|
||||||
AST tree = new AST(new Node("EXPR"));
|
AST tree = new AST(new ASTNode("EXPR"));
|
||||||
|
|
||||||
Node right = new Node("INTEGER_LIT");
|
ASTNode right = new ASTNode("INTEGER_LIT");
|
||||||
right.setValue("1");
|
right.setValue("1");
|
||||||
|
|
||||||
Node left = new Node("EXPR");
|
ASTNode left = new ASTNode("EXPR");
|
||||||
left.setValue("SUB");
|
left.setValue("SUB");
|
||||||
|
|
||||||
Node lleft = new Node("EXPR");
|
ASTNode lleft = new ASTNode("EXPR");
|
||||||
lleft.setValue("MUL");
|
lleft.setValue("MUL");
|
||||||
|
|
||||||
Node lright = new Node("INTEGER_LIT");
|
ASTNode lright = new ASTNode("INTEGER_LIT");
|
||||||
lright.setValue("2");
|
lright.setValue("2");
|
||||||
|
|
||||||
Node llleft = new Node("INTEGER_LIT");
|
ASTNode llleft = new ASTNode("INTEGER_LIT");
|
||||||
llleft.setValue("3");
|
llleft.setValue("3");
|
||||||
|
|
||||||
lleft.setChildren(llleft);
|
lleft.setChildren(llleft);
|
||||||
@ -85,7 +85,7 @@ class ExpressionBalancerTest {
|
|||||||
AST tree = tree1();
|
AST tree = tree1();
|
||||||
System.out.println("Before:\n" + tree);
|
System.out.println("Before:\n" + tree);
|
||||||
|
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
System.out.println("After:\n" + tree);
|
System.out.println("After:\n" + tree);
|
||||||
|
|
||||||
assertThat(tree.getRoot().getChildren().get(0).getName()).isEqualTo("INTEGER_LIT");
|
assertThat(tree.getRoot().getChildren().get(0).getName()).isEqualTo("INTEGER_LIT");
|
||||||
@ -97,8 +97,8 @@ class ExpressionBalancerTest {
|
|||||||
AST tree = tree1();
|
AST tree = tree1();
|
||||||
System.out.println("Before:\n" + tree);
|
System.out.println("Before:\n" + tree);
|
||||||
|
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
System.out.println("After:\n" + tree);
|
System.out.println("After:\n" + tree);
|
||||||
|
|
||||||
assertThat(tree).isEqualTo(tree1());
|
assertThat(tree).isEqualTo(tree1());
|
||||||
@ -109,7 +109,7 @@ class ExpressionBalancerTest {
|
|||||||
AST tree = tree2();
|
AST tree = tree2();
|
||||||
System.out.println("Before:\n" + tree);
|
System.out.println("Before:\n" + tree);
|
||||||
|
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
System.out.println("After:\n" + tree);
|
System.out.println("After:\n" + tree);
|
||||||
|
|
||||||
assertThat(tree.getRoot().getChildren().get(0).getName()).isEqualTo("INTEGER_LIT");
|
assertThat(tree.getRoot().getChildren().get(0).getName()).isEqualTo("INTEGER_LIT");
|
||||||
@ -123,8 +123,8 @@ class ExpressionBalancerTest {
|
|||||||
AST tree = tree2();
|
AST tree = tree2();
|
||||||
System.out.println("Before:\n" + tree);
|
System.out.println("Before:\n" + tree);
|
||||||
|
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
System.out.println("After:\n" + tree);
|
System.out.println("After:\n" + tree);
|
||||||
|
|
||||||
assertThat(tree).isEqualTo(tree2());
|
assertThat(tree).isEqualTo(tree2());
|
||||||
@ -133,10 +133,10 @@ class ExpressionBalancerTest {
|
|||||||
@Test
|
@Test
|
||||||
void testTree1LeftPrecedence() {
|
void testTree1LeftPrecedence() {
|
||||||
AST tree = tree1();
|
AST tree = tree1();
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
System.out.println("Before:\n" + tree);
|
System.out.println("Before:\n" + tree);
|
||||||
|
|
||||||
ExpressionBalancer.leftPrecedence(tree);
|
ASTBalancer.leftPrecedence(tree);
|
||||||
System.out.println("After:\n" + tree);
|
System.out.println("After:\n" + tree);
|
||||||
|
|
||||||
assertThat(tree.size()).isEqualTo(3);
|
assertThat(tree.size()).isEqualTo(3);
|
||||||
@ -146,10 +146,10 @@ class ExpressionBalancerTest {
|
|||||||
@Test
|
@Test
|
||||||
void testTree2LeftPrecedence() {
|
void testTree2LeftPrecedence() {
|
||||||
AST tree = tree2();
|
AST tree = tree2();
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
System.out.println("Before:\n" + tree);
|
System.out.println("Before:\n" + tree);
|
||||||
|
|
||||||
ExpressionBalancer.leftPrecedence(tree);
|
ASTBalancer.leftPrecedence(tree);
|
||||||
System.out.println("After:\n" + tree);
|
System.out.println("After:\n" + tree);
|
||||||
|
|
||||||
assertThat(tree.size()).isEqualTo(5);
|
assertThat(tree.size()).isEqualTo(5);
|
||||||
@ -159,15 +159,15 @@ class ExpressionBalancerTest {
|
|||||||
@Test
|
@Test
|
||||||
void testTree2OperatorPrecedence() {
|
void testTree2OperatorPrecedence() {
|
||||||
AST tree = tree2();
|
AST tree = tree2();
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
ExpressionBalancer.leftPrecedence(tree);
|
ASTBalancer.leftPrecedence(tree);
|
||||||
System.out.println("Before:\n" + tree);
|
System.out.println("Before:\n" + tree);
|
||||||
|
|
||||||
AST tree1 = tree2();
|
AST tree1 = tree2();
|
||||||
ExpressionBalancer.flip(tree1);
|
ASTBalancer.flip(tree1);
|
||||||
ExpressionBalancer.leftPrecedence(tree1);
|
ASTBalancer.leftPrecedence(tree1);
|
||||||
|
|
||||||
ExpressionBalancer.operatorPrecedence(tree);
|
ASTBalancer.operatorPrecedence(tree);
|
||||||
System.out.println("After:\n" + tree);
|
System.out.println("After:\n" + tree);
|
||||||
|
|
||||||
assertThat(tree).isEqualTo(tree1);
|
assertThat(tree).isEqualTo(tree1);
|
||||||
@ -176,13 +176,13 @@ class ExpressionBalancerTest {
|
|||||||
@Test
|
@Test
|
||||||
void testTree3OperatorPrecedence() {
|
void testTree3OperatorPrecedence() {
|
||||||
AST tree = tree3();
|
AST tree = tree3();
|
||||||
ExpressionBalancer.flip(tree);
|
ASTBalancer.flip(tree);
|
||||||
ExpressionBalancer.leftPrecedence(tree);
|
ASTBalancer.leftPrecedence(tree);
|
||||||
System.out.println("Before:\n" + tree);
|
System.out.println("Before:\n" + tree);
|
||||||
|
|
||||||
assertThat(tree.getRoot().getValue()).isEqualTo("MUL");
|
assertThat(tree.getRoot().getValue()).isEqualTo("MUL");
|
||||||
|
|
||||||
ExpressionBalancer.operatorPrecedence(tree);
|
ASTBalancer.operatorPrecedence(tree);
|
||||||
System.out.println("After:\n" + tree);
|
System.out.println("After:\n" + tree);
|
||||||
|
|
||||||
assertThat(tree.size()).isEqualTo(5);
|
assertThat(tree.size()).isEqualTo(5);
|
||||||
@ -4,7 +4,7 @@ import lexer.StupsLexer;
|
|||||||
import org.antlr.v4.runtime.CharStreams;
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
import org.antlr.v4.runtime.Lexer;
|
import org.antlr.v4.runtime.Lexer;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import parser.LL1Parser;
|
import parser.Parser;
|
||||||
import parser.grammar.Grammar;
|
import parser.grammar.Grammar;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -34,7 +34,7 @@ class ASTCompacterTest {
|
|||||||
void testRemoveEpsilon() throws URISyntaxException, IOException {
|
void testRemoveEpsilon() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
Grammar grammar = Grammar.fromFile(path);
|
Grammar grammar = Grammar.fromFile(path);
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(grammar);
|
Parser parser = Parser.fromGrammar(grammar);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("GeneralOperator.stups");
|
Lexer lex = this.initLexer("GeneralOperator.stups");
|
||||||
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
||||||
@ -47,7 +47,7 @@ class ASTCompacterTest {
|
|||||||
void testCompact() throws URISyntaxException, IOException {
|
void testCompact() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
Grammar grammar = Grammar.fromFile(path);
|
Grammar grammar = Grammar.fromFile(path);
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(grammar);
|
Parser parser = Parser.fromGrammar(grammar);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("GeneralOperator.stups");
|
Lexer lex = this.initLexer("GeneralOperator.stups");
|
||||||
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
||||||
@ -60,7 +60,7 @@ class ASTCompacterTest {
|
|||||||
void testRemoveNullable() throws URISyntaxException, IOException {
|
void testRemoveNullable() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
Grammar grammar = Grammar.fromFile(path);
|
Grammar grammar = Grammar.fromFile(path);
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(grammar);
|
Parser parser = Parser.fromGrammar(grammar);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("GeneralOperator.stups");
|
Lexer lex = this.initLexer("GeneralOperator.stups");
|
||||||
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
||||||
@ -74,7 +74,7 @@ class ASTCompacterTest {
|
|||||||
void testClean() throws URISyntaxException, IOException {
|
void testClean() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
Grammar grammar = Grammar.fromFile(path);
|
Grammar grammar = Grammar.fromFile(path);
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(grammar);
|
Parser parser = Parser.fromGrammar(grammar);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("GeneralOperator.stups");
|
Lexer lex = this.initLexer("GeneralOperator.stups");
|
||||||
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
||||||
|
|||||||
@ -8,7 +8,7 @@ class ASTTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testOneNode() {
|
void testOneNode() {
|
||||||
Node root = new Node("Wurzel");
|
ASTNode root = new ASTNode("Wurzel");
|
||||||
|
|
||||||
AST tree = new AST(root);
|
AST tree = new AST(root);
|
||||||
System.out.println(tree);
|
System.out.println(tree);
|
||||||
@ -18,9 +18,9 @@ class ASTTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testThreeNodesBinary() {
|
void testThreeNodesBinary() {
|
||||||
Node root = new Node("Wurzel");
|
ASTNode root = new ASTNode("Wurzel");
|
||||||
Node childA = new Node("A");
|
ASTNode childA = new ASTNode("A");
|
||||||
Node childB = new Node("B");
|
ASTNode childB = new ASTNode("B");
|
||||||
|
|
||||||
root.addChild(childA);
|
root.addChild(childA);
|
||||||
root.addChild(childB);
|
root.addChild(childB);
|
||||||
@ -33,9 +33,9 @@ class ASTTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testThreeNodesLinear() {
|
void testThreeNodesLinear() {
|
||||||
Node root = new Node("Wurzel");
|
ASTNode root = new ASTNode("Wurzel");
|
||||||
Node childA = new Node("A");
|
ASTNode childA = new ASTNode("A");
|
||||||
Node childB = new Node("B");
|
ASTNode childB = new ASTNode("B");
|
||||||
|
|
||||||
root.addChild(childA);
|
root.addChild(childA);
|
||||||
childA.addChild(childB);
|
childA.addChild(childB);
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package parser.grammar;
|
|||||||
|
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import parser.LL1ParsingTable;
|
import parser.ParsingTable;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -10,7 +10,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
class LL1GrammarAnalyzerTest {
|
class GrammarAnalyzerTest {
|
||||||
|
|
||||||
private static Grammar grammar0;
|
private static Grammar grammar0;
|
||||||
private static Grammar grammar1;
|
private static Grammar grammar1;
|
||||||
@ -108,7 +108,7 @@ class LL1GrammarAnalyzerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFirstGrammar0() {
|
void testFirstGrammar0() {
|
||||||
LL1GrammarAnalyzer analyzer = new LL1GrammarAnalyzer(grammar0);
|
GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar0);
|
||||||
|
|
||||||
assertThat(analyzer.getFirst().get("S")).containsOnly("i", "a");
|
assertThat(analyzer.getFirst().get("S")).containsOnly("i", "a");
|
||||||
assertThat(analyzer.getFirst().get("E")).containsOnly("b");
|
assertThat(analyzer.getFirst().get("E")).containsOnly("b");
|
||||||
@ -116,7 +116,7 @@ class LL1GrammarAnalyzerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFirstGrammar1() {
|
void testFirstGrammar1() {
|
||||||
LL1GrammarAnalyzer analyzer = new LL1GrammarAnalyzer(grammar1);
|
GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar1);
|
||||||
|
|
||||||
assertThat(analyzer.getFirst().get("E")).containsOnly("id", "(");
|
assertThat(analyzer.getFirst().get("E")).containsOnly("id", "(");
|
||||||
assertThat(analyzer.getFirst().get("E2")).containsOnly("+", grammar1.getEpsilonSymbol());
|
assertThat(analyzer.getFirst().get("E2")).containsOnly("+", grammar1.getEpsilonSymbol());
|
||||||
@ -127,7 +127,7 @@ class LL1GrammarAnalyzerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFirstGrammar2() {
|
void testFirstGrammar2() {
|
||||||
LL1GrammarAnalyzer analyzer = new LL1GrammarAnalyzer(grammar2);
|
GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar2);
|
||||||
|
|
||||||
assertThat(analyzer.getFirst().get("X")).containsOnly("c", "a", grammar2.getEpsilonSymbol());
|
assertThat(analyzer.getFirst().get("X")).containsOnly("c", "a", grammar2.getEpsilonSymbol());
|
||||||
assertThat(analyzer.getFirst().get("Y")).containsOnly("c", grammar2.getEpsilonSymbol());
|
assertThat(analyzer.getFirst().get("Y")).containsOnly("c", grammar2.getEpsilonSymbol());
|
||||||
@ -136,7 +136,7 @@ class LL1GrammarAnalyzerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFollowGrammar0() {
|
void testFollowGrammar0() {
|
||||||
LL1GrammarAnalyzer analyzer = new LL1GrammarAnalyzer(grammar0);
|
GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar0);
|
||||||
|
|
||||||
assertThat(analyzer.getFollow().get("S")).containsOnly("$");
|
assertThat(analyzer.getFollow().get("S")).containsOnly("$");
|
||||||
assertThat(analyzer.getFollow().get("E")).containsOnly("t");
|
assertThat(analyzer.getFollow().get("E")).containsOnly("t");
|
||||||
@ -144,7 +144,7 @@ class LL1GrammarAnalyzerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFollowGrammar1() {
|
void testFollowGrammar1() {
|
||||||
LL1GrammarAnalyzer analyzer = new LL1GrammarAnalyzer(grammar1);
|
GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar1);
|
||||||
|
|
||||||
assertThat(analyzer.getFollow().get("E")).containsOnly(")", "$");
|
assertThat(analyzer.getFollow().get("E")).containsOnly(")", "$");
|
||||||
assertThat(analyzer.getFollow().get("E2")).containsOnly(")", "$");
|
assertThat(analyzer.getFollow().get("E2")).containsOnly(")", "$");
|
||||||
@ -155,7 +155,7 @@ class LL1GrammarAnalyzerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testFollowGrammar2() {
|
void testFollowGrammar2() {
|
||||||
LL1GrammarAnalyzer analyzer = new LL1GrammarAnalyzer(grammar2);
|
GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar2);
|
||||||
|
|
||||||
assertThat(analyzer.getFollow().get("X")).containsOnly("a", "c", "d");
|
assertThat(analyzer.getFollow().get("X")).containsOnly("a", "c", "d");
|
||||||
assertThat(analyzer.getFollow().get("Y")).containsOnly("a", "c", "d");
|
assertThat(analyzer.getFollow().get("Y")).containsOnly("a", "c", "d");
|
||||||
@ -164,8 +164,8 @@ class LL1GrammarAnalyzerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testTableGrammar1() {
|
void testTableGrammar1() {
|
||||||
LL1GrammarAnalyzer analyzer = new LL1GrammarAnalyzer(grammar1);
|
GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar1);
|
||||||
LL1ParsingTable table = analyzer.getTable();
|
ParsingTable table = analyzer.getTable();
|
||||||
|
|
||||||
assertThat(table.get("E", "id")).isEqualTo("T E2");
|
assertThat(table.get("E", "id")).isEqualTo("T E2");
|
||||||
assertThat(table.get("E", "(")).isEqualTo("T E2");
|
assertThat(table.get("E", "(")).isEqualTo("T E2");
|
||||||
@ -4,7 +4,7 @@ import lexer.StupsLexer;
|
|||||||
import org.antlr.v4.runtime.CharStreams;
|
import org.antlr.v4.runtime.CharStreams;
|
||||||
import org.antlr.v4.runtime.Lexer;
|
import org.antlr.v4.runtime.Lexer;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import parser.LL1Parser;
|
import parser.Parser;
|
||||||
import parser.ast.AST;
|
import parser.ast.AST;
|
||||||
import parser.grammar.Grammar;
|
import parser.grammar.Grammar;
|
||||||
import typechecker.SymbolAlreadyDefinedException;
|
import typechecker.SymbolAlreadyDefinedException;
|
||||||
@ -38,7 +38,7 @@ class SymbolTableTest {
|
|||||||
void testSingleSymbol() throws URISyntaxException, IOException {
|
void testSingleSymbol() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
Grammar grammar = Grammar.fromFile(path);
|
Grammar grammar = Grammar.fromFile(path);
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(grammar);
|
Parser parser = Parser.fromGrammar(grammar);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("SingleSymbol.stups");
|
Lexer lex = this.initLexer("SingleSymbol.stups");
|
||||||
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
||||||
@ -54,7 +54,7 @@ class SymbolTableTest {
|
|||||||
void testMultipleSymbol() throws URISyntaxException, IOException {
|
void testMultipleSymbol() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
Grammar grammar = Grammar.fromFile(path);
|
Grammar grammar = Grammar.fromFile(path);
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(grammar);
|
Parser parser = Parser.fromGrammar(grammar);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("MultipleSymbol.stups");
|
Lexer lex = this.initLexer("MultipleSymbol.stups");
|
||||||
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
||||||
@ -75,7 +75,7 @@ class SymbolTableTest {
|
|||||||
void testExistingSymbol() throws URISyntaxException, IOException {
|
void testExistingSymbol() throws URISyntaxException, IOException {
|
||||||
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
Path path = Paths.get(this.getClass().getClassLoader().getResource("exampleGrammars/Grammar.grammar").toURI());
|
||||||
Grammar grammar = Grammar.fromFile(path);
|
Grammar grammar = Grammar.fromFile(path);
|
||||||
LL1Parser parser = LL1Parser.fromGrammar(grammar);
|
Parser parser = Parser.fromGrammar(grammar);
|
||||||
|
|
||||||
Lexer lex = this.initLexer("ExistingSymbol.stups");
|
Lexer lex = this.initLexer("ExistingSymbol.stups");
|
||||||
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
AST tree = parser.parse(lex.getAllTokens(), lex.getVocabulary());
|
||||||
|
|||||||
Reference in New Issue
Block a user