[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:
@@ -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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class XParser {
|
||||
|
||||
public XParser(TokenBuffer in) {
|
||||
//TODO Initialization
|
||||
}
|
||||
private final TokenBuffer in;
|
||||
private long comparecount = 0;
|
||||
|
||||
public Tree parseProgram() {
|
||||
//TODO Parser
|
||||
return null;
|
||||
}
|
||||
private final Set<Integer> PlusMinus;
|
||||
private final Set<Integer> MultDiv;
|
||||
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user