implement ll1-nonrecursive-descent-parser

This commit is contained in:
ChUrl
2020-12-01 16:13:45 +01:00
parent 09bff8edf1
commit f3b9b5ecf5
5 changed files with 279 additions and 0 deletions

View File

@ -0,0 +1,16 @@
package parser;
import java.util.List;
public interface ILL1ParsingTable {
List<String> get(String nonterminal, String terminal);
String getStartSymbol();
List<String> getNonterminals();
List<String> getTerminals();
String getEpsilon();
}

View File

@ -0,0 +1,52 @@
package parser;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.List;
public class LL1Parser {
private final ILL1ParsingTable parsetable;
public LL1Parser(ILL1ParsingTable parsetable) {
this.parsetable = parsetable;
}
public boolean parse(List<String> token) {
Deque<String> stack = new ArrayDeque<>();
stack.push(this.parsetable.getStartSymbol());
int current = 0;
System.out.println("\nParsing " + token + ":");
while (!stack.isEmpty()) {
String top = stack.peek();
// Wenn auf dem Stack mehr Nichtterminale liegen als Terminale in der Eingabe vorhanden sind
if (current >= token.size()) {
throw new MyParseException("Input too long");
}
List<String> prod = this.parsetable.get(top, token.get(current));
if (top.equals(token.get(current))) {
stack.pop();
current++;
} else if (this.parsetable.getTerminals().contains(top)) {
throw new MyParseException("Invalid terminal on stack: " + top);
} else if (prod == null) {
throw new MyParseException("No prod. for nonterminal " + top + " and terminal " + token.get(current));
} else {
System.out.println(top + " -> " + prod);
stack.pop();
for (int i = prod.size() - 1; i >= 0; i--) {
stack.push(prod.get(i));
}
}
}
return true;
}
}

View File

@ -0,0 +1,52 @@
package parser;
import java.util.AbstractMap.SimpleEntry;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class LL1ParsingTable implements ILL1ParsingTable {
private final String start;
private final List<String> terminals;
private final List<String> nonterminals;
private final String epsilon;
private final Map<Entry<String, String>, ? extends List<String>> parsetable;
public LL1ParsingTable(List<String> nonterminals,
List<String> terminals,
String start,
String epsilon,
Map<Entry<String, String>, ? extends List<String>> parsetable) {
this.start = start;
this.terminals = terminals;
this.nonterminals = nonterminals;
this.epsilon = epsilon;
this.parsetable = parsetable;
}
@Override
public List<String> get(String nonterminal, String terminal) {
return this.parsetable.get(new SimpleEntry<>(nonterminal, terminal));
}
@Override
public String getStartSymbol() {
return this.start;
}
@Override
public List<String> getNonterminals() {
return this.nonterminals;
}
@Override
public List<String> getTerminals() {
return this.terminals;
}
@Override
public String getEpsilon() {
return this.epsilon;
}
}

View File

@ -0,0 +1,8 @@
package parser;
public class MyParseException extends RuntimeException {
public MyParseException(String message) {
super(message);
}
}