implement basic ast generation in parser
This commit is contained in:
@ -1,5 +1,8 @@
|
||||
package parser;
|
||||
|
||||
import util.ast.AST;
|
||||
import util.ast.Node;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
@ -13,40 +16,51 @@ public class LL1Parser {
|
||||
}
|
||||
|
||||
public boolean parse(List<String> token) {
|
||||
Deque<String> stack = new ArrayDeque<>();
|
||||
stack.push(this.parsetable.getStartSymbol());
|
||||
Node root = new Node(this.parsetable.getStartSymbol());
|
||||
AST tree = new AST(root);
|
||||
Deque<Node> stack = new ArrayDeque<>();
|
||||
stack.push(root);
|
||||
|
||||
int current = 0;
|
||||
int currentToken = 0;
|
||||
System.out.println("\nParsing " + token + ":");
|
||||
|
||||
// Parsing
|
||||
while (!stack.isEmpty()) {
|
||||
String top = stack.peek();
|
||||
String top = stack.peek().getName();
|
||||
|
||||
// Wenn auf dem Stack mehr Nichtterminale liegen als Terminale in der Eingabe vorhanden sind
|
||||
if (current >= token.size()) {
|
||||
if (currentToken >= token.size()) {
|
||||
// Wenn auf dem Stack mehr Nichtterminale liegen als Terminale in der Eingabe vorhanden sind
|
||||
throw new MyParseException("Input too long");
|
||||
}
|
||||
List<String> prod = this.parsetable.get(top, token.get(current));
|
||||
List<String> prod = this.parsetable.get(top, token.get(currentToken));
|
||||
|
||||
if (top.equals(token.get(current))) {
|
||||
if (top.equals(token.get(currentToken))) {
|
||||
// Wenn auf dem Stack ein Terminal liegt
|
||||
stack.pop();
|
||||
current++;
|
||||
currentToken++;
|
||||
|
||||
} else if (this.parsetable.getTerminals().contains(top)) {
|
||||
// Wenn das Terminal auf dem Stack nicht mit der aktuellen Eingabe übereinstimmt
|
||||
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));
|
||||
// Wenn es für das aktuelle Terminal und das Nichtterminal auf dem Stack keine Regel gibt
|
||||
throw new MyParseException("No prod. for nonterminal " + top + ", terminal " + token.get(currentToken));
|
||||
|
||||
} else {
|
||||
// Wenn das Nichtterminal auf dem Stack durch (s)eine Produktion ersetzt werden kann
|
||||
// Hier wird auch der AST aufgebaut
|
||||
System.out.println(top + " -> " + prod);
|
||||
stack.pop();
|
||||
Node pop = stack.pop();
|
||||
for (int i = prod.size() - 1; i >= 0; i--) {
|
||||
stack.push(prod.get(i));
|
||||
Node node = new Node(prod.get(i));
|
||||
stack.push(node);
|
||||
pop.addChild(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("\n" + tree);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user