slight cleanup
This commit is contained in:
@ -1,7 +1,6 @@
|
||||
package parser;
|
||||
|
||||
import parser.grammar.Grammar;
|
||||
import parser.grammar.GrammarAnalyzer;
|
||||
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.Collections;
|
||||
@ -11,10 +10,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ParsingTable {
|
||||
|
||||
private static final Pattern X = Pattern.compile("X");
|
||||
private final Grammar grammar;
|
||||
private final Map<Entry<String, String>, String> parsetable;
|
||||
|
||||
@ -23,11 +24,6 @@ public class ParsingTable {
|
||||
this.parsetable = Collections.unmodifiableMap(parsetable);
|
||||
}
|
||||
|
||||
public static ParsingTable fromGrammar(Grammar grammar) {
|
||||
final GrammarAnalyzer analyzer = new GrammarAnalyzer(grammar);
|
||||
return analyzer.getTable();
|
||||
}
|
||||
|
||||
public String get(String nonterminal, String terminal) {
|
||||
return this.parsetable.get(new SimpleEntry<>(nonterminal, terminal));
|
||||
}
|
||||
@ -86,7 +82,7 @@ public class ParsingTable {
|
||||
output.append(" ".repeat(margins.get("NTERM")))
|
||||
.append("| ");
|
||||
for (String terminal : inputSymbols) {
|
||||
format.format("%-Xs ".replaceAll("X", String.valueOf(margins.get(terminal))), terminal);
|
||||
format.format(X.matcher("%-Xs ").replaceAll(String.valueOf(margins.get(terminal))), terminal);
|
||||
}
|
||||
output.append("|\n");
|
||||
|
||||
@ -100,11 +96,11 @@ public class ParsingTable {
|
||||
.append("\n");
|
||||
|
||||
for (String nonterminal : this.grammar.getNonterminals()) {
|
||||
format.format("%-Xs| ".replaceAll("X", String.valueOf(margins.get("NTERM"))), nonterminal);
|
||||
format.format(X.matcher("%-Xs| ").replaceAll(String.valueOf(margins.get("NTERM"))), nonterminal);
|
||||
|
||||
for (String terminal : inputSymbols) {
|
||||
final String prod = this.parsetable.get(new SimpleEntry<>(nonterminal, terminal));
|
||||
format.format("%-Xs ".replaceAll("X", String.valueOf(margins.get(terminal))), prod == null ? " ".repeat(9) : prod);
|
||||
format.format(X.matcher("%-Xs ").replaceAll(String.valueOf(margins.get(terminal))), prod == null ? " ".repeat(9) : prod);
|
||||
}
|
||||
output.append("|\n");
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import parser.grammar.Grammar;
|
||||
import parser.grammar.GrammarAnalyzer;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Collection;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@ -27,6 +28,15 @@ public class StupsParser {
|
||||
return new StupsParser(analyzer.getTable());
|
||||
}
|
||||
|
||||
private static void printSourceLine(int line, Collection<? extends Token> token) {
|
||||
final Optional<String> srcLine = token.stream()
|
||||
.filter(tok -> tok.getLine() == line)
|
||||
.map(Token::getText)
|
||||
.reduce((s1, s2) -> s1 + " " + s2);
|
||||
|
||||
srcLine.ifPresent(s -> System.out.println(" :: " + s));
|
||||
}
|
||||
|
||||
public AST parse(List<? extends Token> token, Vocabulary voc) {
|
||||
System.out.println(" - Parsing program...");
|
||||
final ASTNode root = new ASTNode(this.parsetable.getStartSymbol(), 0);
|
||||
@ -72,14 +82,14 @@ public class StupsParser {
|
||||
// Wenn das Terminal auf dem Stack nicht mit der aktuellen Eingabe übereinstimmt
|
||||
|
||||
System.out.println("\nLine " + currentLine + " Syntaxerror: Expected " + top + " but found " + currentTokenSym);
|
||||
this.printSourceLine(currentLine, token);
|
||||
StupsParser.printSourceLine(currentLine, token);
|
||||
|
||||
throw new ParseException("Invalid terminal on stack: " + top, tree);
|
||||
} else if (prod == null) {
|
||||
// Wenn es für das aktuelle Terminal und das Nichtterminal auf dem Stack keine Regel gibt
|
||||
|
||||
System.out.println("\nLine " + currentLine + " Syntaxerror: Didn't expect " + currentTokenSym);
|
||||
this.printSourceLine(currentLine, token);
|
||||
StupsParser.printSourceLine(currentLine, token);
|
||||
|
||||
throw new ParseException("No prod. for nonterminal " + top + ", terminal " + currentTokenSym, tree);
|
||||
} else {
|
||||
@ -117,13 +127,4 @@ public class StupsParser {
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
private void printSourceLine(int line, List<? extends Token> token) {
|
||||
final Optional<String> srcLine = token.stream()
|
||||
.filter(tok -> tok.getLine() == line)
|
||||
.map(Token::getText)
|
||||
.reduce((s1, s2) -> s1 + " " + s2);
|
||||
|
||||
srcLine.ifPresent(s -> System.out.println(" :: " + s));
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import parser.grammar.Grammar;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static util.Logger.log;
|
||||
|
||||
@ -153,7 +152,7 @@ public final class ASTCompacter {
|
||||
}
|
||||
|
||||
private static void valueToValue(ASTNode root, Grammar grammar) {
|
||||
final Set<ASTNode> toRemove = new HashSet<>();
|
||||
final Collection<ASTNode> toRemove = new HashSet<>();
|
||||
|
||||
for (ASTNode child : root.getChildren()) {
|
||||
valueToValue(child, grammar);
|
||||
|
@ -13,6 +13,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static parser.grammar.GrammarAction.DELCHILD;
|
||||
@ -26,6 +27,8 @@ import static util.Logger.log;
|
||||
|
||||
public class Grammar {
|
||||
|
||||
private static final Pattern EPS = Pattern.compile("EPS");
|
||||
private static final Pattern ARROW = Pattern.compile("->");
|
||||
private final Set<String> terminals;
|
||||
private final Set<String> nonterminals;
|
||||
private final String startSymbol;
|
||||
@ -86,7 +89,7 @@ public class Grammar {
|
||||
final Map<String, List<String>> valToValMappings = new HashMap<>();
|
||||
final Map<String, List<String>> delChildMappings = new HashMap<>();
|
||||
|
||||
for (GrammarAction action : GrammarAction.values()) {
|
||||
for (GrammarAction action : values()) {
|
||||
actions.put(action, new HashSet<>());
|
||||
}
|
||||
|
||||
@ -117,8 +120,7 @@ public class Grammar {
|
||||
// Parse Grammar Rules + Actions
|
||||
|
||||
// "S[...] -> E T2 | EPS" wird zu leftside = "S[...]" und rightside = "E T2 | eps"
|
||||
final String[] split = line.replaceAll("EPS", epsilonSymbol)
|
||||
.split("->");
|
||||
final String[] split = ARROW.split(EPS.matcher(line).replaceAll(epsilonSymbol));
|
||||
String leftside = split[0].trim();
|
||||
final String rightside = split[1].trim();
|
||||
|
||||
|
@ -241,10 +241,6 @@ public class GrammarAnalyzer {
|
||||
|
||||
final Set<String> followLeftside = this.follow(leftside);
|
||||
|
||||
// log(leftside + " -> " + rightside);
|
||||
// log("First: " + firstRightside);
|
||||
// log("Follow: " + followLeftside + "\n");
|
||||
|
||||
if (firstRightside.contains(this.grammar.getEpsilonSymbol())) {
|
||||
// 2. If epsilon in first(a), then...
|
||||
|
||||
|
@ -37,18 +37,18 @@ public class TypeTable {
|
||||
Map.entry("EQUAL", "BOOLEAN_TYPE"),
|
||||
Map.entry("NOT_EQUAL", "BOOLEAN_TYPE"));
|
||||
|
||||
this.methodArgumentTable = Map.ofEntries(Map.entry("ADD", Arrays.asList("INTEGER_TYPE")),
|
||||
Map.entry("SUB", Arrays.asList("INTEGER_TYPE")),
|
||||
Map.entry("MUL", Arrays.asList("INTEGER_TYPE")),
|
||||
Map.entry("DIV", Arrays.asList("INTEGER_TYPE")),
|
||||
Map.entry("MOD", Arrays.asList("INTEGER_TYPE")),
|
||||
Map.entry("AND", Arrays.asList("BOOLEAN_TYPE")),
|
||||
Map.entry("OR", Arrays.asList("BOOLEAN_TYPE")),
|
||||
Map.entry("NOT", Arrays.asList("BOOLEAN_TYPE")),
|
||||
Map.entry("LESS", Arrays.asList("INTEGER_TYPE")),
|
||||
Map.entry("LESS_EQUAL", Arrays.asList("INTEGER_TYPE")),
|
||||
Map.entry("GREATER", Arrays.asList("INTEGER_TYPE")),
|
||||
Map.entry("GREATER_EQUAL", Arrays.asList("INTEGER_TYPE")),
|
||||
this.methodArgumentTable = Map.ofEntries(Map.entry("ADD", Collections.singletonList("INTEGER_TYPE")),
|
||||
Map.entry("SUB", Collections.singletonList("INTEGER_TYPE")),
|
||||
Map.entry("MUL", Collections.singletonList("INTEGER_TYPE")),
|
||||
Map.entry("DIV", Collections.singletonList("INTEGER_TYPE")),
|
||||
Map.entry("MOD", Collections.singletonList("INTEGER_TYPE")),
|
||||
Map.entry("AND", Collections.singletonList("BOOLEAN_TYPE")),
|
||||
Map.entry("OR", Collections.singletonList("BOOLEAN_TYPE")),
|
||||
Map.entry("NOT", Collections.singletonList("BOOLEAN_TYPE")),
|
||||
Map.entry("LESS", Collections.singletonList("INTEGER_TYPE")),
|
||||
Map.entry("LESS_EQUAL", Collections.singletonList("INTEGER_TYPE")),
|
||||
Map.entry("GREATER", Collections.singletonList("INTEGER_TYPE")),
|
||||
Map.entry("GREATER_EQUAL", Collections.singletonList("INTEGER_TYPE")),
|
||||
Map.entry("EQUAL", Arrays.asList("INTEGER_TYPE", "BOOLEAN_TYPE", "STRING_TYPE")),
|
||||
Map.entry("NOT_EQUAL", Arrays.asList("INTEGER_TYPE", "BOOLEAN_TYPE", "STRING_TYPE")));
|
||||
}
|
||||
@ -64,7 +64,7 @@ public class TypeTable {
|
||||
return new TypeTable(tableOut);
|
||||
}
|
||||
|
||||
private static void scanTree(ASTNode root, Map<String, String> table) {
|
||||
private static void scanTree(ASTNode root, Map<? super String, String> table) {
|
||||
for (ASTNode child : root.getChildren()) {
|
||||
scanTree(child, table);
|
||||
}
|
||||
|
Reference in New Issue
Block a user