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