[09/10 - LL(I) AST] Add old implementation of "ÜB-Praxis-AST für X" and LL(I) grammar of modifier

This commit is contained in:
2020-05-25 13:26:41 +02:00
parent 0598ac09a7
commit 7863777f8f

View File

@@ -1,25 +1,477 @@
/* **********************************************
* Duale Hochschule Baden-Württemberg Karlsruhe
* Prof. Dr. Jörn Eisenbiegler
*
* Vorlesung Übersetzerbau
* Praxis LL(1)-Parser für X
* - LL1-Parser
*
* **********************************************
*/
package de.dhbw.compiler.xparser; package de.dhbw.compiler.xparser;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
public class XParser { public class XParser {
public XParser(TokenBuffer in) { private final TokenBuffer in;
//TODO Initialization private long comparecount = 0;
}
public Tree parseProgram() { private final Set<Integer> PlusMinus;
//TODO Parser private final Set<Integer> MultDiv;
return null;
}
public XParser(TokenBuffer in) {
this.in = in;
PlusMinus = new HashSet<>();
PlusMinus.add(Token.PLUS);
PlusMinus.add(Token.MINUS);
MultDiv = new HashSet<>();
MultDiv.add(Token.MULT);
MultDiv.add(Token.DIV);
}
public long getComparecount() {
return comparecount;
}
private Tree addLeftAssoziativ(Tree left, Tree op, Tree right, Set<Integer> samePrio) {
if (right.getChildren()
.isEmpty() || !samePrio.contains(right.getToken()
.getType())) {
op.addFirstChild(left);
op.addLastChild(right);
return op;
} else {
Tree leftop = right;
while (samePrio.contains(leftop.getChild(0)
.getToken()
.getType())) {
leftop = leftop.getChild(0);
}
Tree leftright = leftop.getChild(0);
leftop.removeChild(0);
op.addLastChild(leftright);
op.addFirstChild(left);
leftop.addFirstChild(op);
return right;
}
}
public Tree parseToken(int type) {
comparecount++;
try {
Token token = in.nextToken();
if (token.getType() == type) {
return new Tree(token);
} else {
return null;
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/* ---------------------------------------- *
*
* modifier ::= read modifier2 | print | eps.
* modifier2 ::= print | eps.
*/
/* modifier ::= read modifier2 | print | eps. */
public Tree parseModifier() {
switch (in.lookaheadToken().getType()) {
case Token.READ:
Tree read, modifier2;
if ((read = parseToken(Token.READ)) != null
&& (modifier2 = parseModifier2()) != null) {
Tree tree = new Tree(new Token(Token.MODIFIER));
tree.addLastChild(read);
tree.addLastChild(modifier2);
return tree;
} else {
return null;
}
case Token.PRINT:
Tree print;
if ((print = parseToken(Token.PRINT)) != null) {
Tree tree = new Tree(new Token(Token.MODIFIER));
tree.addLastChild(print);
return tree;
} else {
return null;
}
default:
return null;
}
}
/* modifier2 ::= print | eps. */
public Tree parseModifier2() {
if (in.lookaheadToken()
.getType() == Token.PRINT) {
Tree print;
if ((print = parseToken(Token.PRINT)) != null) {
return print;
}
}
return null;
}
public Tree parseType() {
Tree type;
// type ::= int.
if (((type = parseToken(Token.INT)) != null)) {
return type;
}
// type ::= float.
if (((type = parseToken(Token.FLOAT)) != null)) {
return type;
}
// type ::= string.
if (((type = parseToken(Token.STRING)) != null)) {
return type;
}
// fail
return null;
}
public Tree parseDecl() {
// decl ::= modifier id ":" type ";".
Tree modifier, id, type;
if (((modifier = parseModifier()) != null) && ((id = parseToken(Token.ID)) != null) &&
((parseToken(Token.COLON)) != null) && ((type = parseType()) != null) && ((parseToken(Token.SEMICOLON)) != null)) {
Tree tree = new Tree(new Token(Token.DECL));
// tree.addLastChild(modifier);
tree.addLastChild(id);
tree.addLastChild(type);
for (Tree mod : modifier.getChildren()) {
tree.addLastChild(mod);
}
return tree;
}
// fail
return null;
}
public Tree parseExpr3() {
Tree minus, number, id, expr;
Token uminus;
// expr3 ::= "-" int.
if (((minus = parseToken(Token.MINUS)) != null) && ((number = parseToken(Token.INTCONST)) != null)) {
uminus = new Token(Token.UMINUS,
"-",
minus.getToken()
.getLine(),
minus.getToken()
.getColumn());
minus = new Tree(uminus);
minus.addLastChild(number);
return minus;
}
// expr3 ::= int.
if (((number = parseToken(Token.INTCONST)) != null)) {
return number;
}
// expr3 ::= "-" float.
if (((minus = parseToken(Token.MINUS)) != null) && ((number = parseToken(Token.FLOATCONST)) != null)) {
uminus = new Token(Token.UMINUS,
"-",
minus.getToken()
.getLine(),
minus.getToken()
.getColumn());
minus = new Tree(uminus);
minus.addLastChild(number);
return minus;
}
// expr3 ::= float.
if (((number = parseToken(Token.FLOATCONST)) != null)) {
return number;
}
// expr3 ::= string.
if (((number = parseToken(Token.STRINGCONST)) != null)) {
return number;
}
// expr3 ::= id.
if (((id = parseToken(Token.ID)) != null)) {
return id;
}
// expr3 ::= "(" expr ")".
if (((parseToken(Token.LBR)) != null) && ((expr = parseExpr()) != null) && ((parseToken(Token.RBR)) != null)) {
return expr;
}
// fail
return null;
}
public Tree parseExpr2() {
Tree exprl, op, exprr;
// expr2 ::= expr3 "*" expr2.
if (((exprl = parseExpr3()) != null) && ((op = parseToken(Token.MULT)) != null) && ((exprr = parseExpr2()) != null)) {
// left-assoziativ!!
return addLeftAssoziativ(exprl, op, exprr, MultDiv);
}
// expr2 ::= expr3 "/" expr2.
if (((exprl = parseExpr3()) != null) && ((op = parseToken(Token.DIV)) != null) && ((exprr = parseExpr2()) != null)) {
return addLeftAssoziativ(exprl, op, exprr, MultDiv);
}
// expr2 ::= expr3.
if (((exprl = parseExpr3()) != null)) {
return exprl;
}
// fail
return null;
}
public Tree parseExpr() {
Tree exprl, op, exprr;
// expr ::= expr2 "+" expr.
if (((exprl = parseExpr2()) != null) && ((op = parseToken(Token.PLUS)) != null) && ((exprr = parseExpr()) != null)) {
return addLeftAssoziativ(exprl, op, exprr, PlusMinus);
}
// expr ::= expr2 "-" expr.
if (((exprl = parseExpr2()) != null) && ((op = parseToken(Token.MINUS)) != null) && ((exprr = parseExpr()) != null)) {
return addLeftAssoziativ(exprl, op, exprr, PlusMinus);
}
// expr ::= expr2.
if (((exprl = parseExpr2()) != null)) {
return exprl;
}
// fail
return null;
}
public Tree parseAssignStat() {
Tree id, assign, expr;
// assignStat ::= id ":=" expr ";".
if (((id = parseToken(Token.ID)) != null) && ((assign = parseToken(Token.ASSIGN)) != null) &&
((expr = parseExpr()) != null)) {
assign.addLastChild(id);
assign.addLastChild(expr);
return assign;
}
// fail
return null;
}
public Tree parseForStat() {
Tree tfor, init, cond, cont, stat;
// forstat ::= for "(" assignstat cond ";" assignstat ")" stat.
if (((tfor = parseToken(Token.FOR)) != null) && ((parseToken(Token.LBR)) != null) &&
((init = parseAssignStat()) != null) && ((parseToken(Token.SEMICOLON)) != null) && ((cond = parseCond()) != null) &&
((parseToken(Token.SEMICOLON)) != null) && ((cont = parseAssignStat()) != null) &&
((parseToken(Token.RBR)) != null) && ((stat = parseStat()) != null)) {
tfor.addLastChild(init);
tfor.addLastChild(cond);
tfor.addLastChild(cont);
tfor.addLastChild(stat);
return tfor;
}
// fail
return null;
}
public Tree parseWhileStat() {
Tree twhile, cond, stat;
// whilestat ::= while "(" cond ")" stat.
if (((twhile = parseToken(Token.WHILE)) != null) && ((parseToken(Token.LBR)) != null) && ((cond = parseCond()) != null) &&
((parseToken(Token.RBR)) != null) && ((stat = parseStat()) != null)) {
twhile.addLastChild(cond);
twhile.addLastChild(stat);
return twhile;
}
// fail
return null;
}
public Tree parseCondStat() {
Tree tif, cond, thenstat, elsestat;
// condstat ::= if cond then stat else stat.
if (((tif = parseToken(Token.IF)) != null) && ((cond = parseCond()) != null) && ((parseToken(Token.THEN)) != null) &&
((thenstat = parseStat()) != null) && ((parseToken(Token.ELSE)) != null) && ((elsestat = parseStat()) != null)) {
tif.addLastChild(cond);
tif.addLastChild(thenstat);
tif.addLastChild(elsestat);
return tif;
}
// condstat ::= if cond then stat.
if (((tif = parseToken(Token.IF)) != null) && ((cond = parseCond()) != null) && ((parseToken(Token.THEN)) != null) &&
((thenstat = parseStat()) != null)) {
tif.addLastChild(cond);
tif.addLastChild(thenstat);
return tif;
}
// fail
return null;
}
public Tree parseCond() {
Tree left, comp, right;
// cond ::= expr "<" expr.
if (((left = parseExpr()) != null) && ((comp = parseToken(Token.LESS)) != null) && ((right = parseExpr()) != null)) {
comp.addLastChild(left);
comp.addLastChild(right);
return comp;
}
// cond ::= expr ">" expr.
if (((left = parseExpr()) != null) && ((comp = parseToken(Token.MORE)) != null) && ((right = parseExpr()) != null)) {
comp.addLastChild(left);
comp.addLastChild(right);
return comp;
}
// cond ::= expr "=" expr.
if (((left = parseExpr()) != null) && ((comp = parseToken(Token.EQUALS)) != null) && ((right = parseExpr()) != null)) {
comp.addLastChild(left);
comp.addLastChild(right);
return comp;
}
// fail
return null;
}
public Tree parseStat() {
Tree stat;
// stat ::= assignstat.
if (((stat = parseAssignStat()) != null)) {
return stat;
}
// stat ::= condstat.
if (((stat = parseCondStat()) != null)) {
return stat;
}
// stat ::= whilestat.
if (((stat = parseWhileStat()) != null)) {
return stat;
}
// stat ::= forstat.
if (((stat = parseForStat()) != null)) {
return stat;
}
// stat ::= block.
if (((stat = parseBlock()) != null)) {
return stat;
}
// fail
return null;
}
public Tree parseBlock() {
Tree statlist;
// block ::= begin statlist end.
if (((parseToken(Token.BEGIN)) != null) && ((statlist = parseStatlist()) != null) && ((parseToken(Token.END)) != null)) {
return statlist;
}
// fail
return null;
}
public Tree parseStatlist() {
Tree stat;
Tree tree = new Tree(new Token(Token.STATLIST));
// statlist ::= { statwithsemi }.
while (((stat = parseStatwithsemi())) != null) {
tree.addLastChild(stat);
}
return tree;
}
public Tree parseStatwithsemi() {
Tree stat;
// statwithsemi ::= stat ";"
if ((((stat = parseStat())) != null) && ((parseToken(Token.SEMICOLON)) != null)) {
return stat;
}
// fail
return null;
}
/*
* decllist ::= decl decllist.
* decllist ::= eps.
*/
public Tree parseDecllist() {
Tree decl;
Tree tree = new Tree(new Token(Token.DECLLIST));
// decllist ::= { decl }.
while (((decl = parseDecl())) != null) {
tree.addLastChild(decl);
}
return tree;
}
public Tree parseProgram() {
Tree program, id, decllist, block;
// program ::= program id ";" decllist block "." EOF.
if (((program = parseToken(Token.PROGRAM)) != null) && (((id = parseToken(Token.ID))) != null) &&
((parseToken(Token.SEMICOLON)) != null) && ((decllist = parseDecllist()) != null) &&
((block = parseBlock()) != null) && ((parseToken(Token.DOT)) != null) && ((parseToken(Token.EOF)) != null)) {
program.addLastChild(id);
program.addLastChild(decllist);
program.addLastChild(block);
return program;
}
// fail
return null;
}
} }