package com.jopdesign.wcet.annotations;
import java.util.List;
import java.util.ArrayList;
import com.jopdesign.common.code.LoopBound;
import com.jopdesign.common.code.SymbolicMarker;
public class Parser {
public static final int _EOF = 0;
public static final int _ident = 1;
public static final int _vident = 2;
public static final int _number = 3;
public static final int _string = 4;
public static final int _char = 5;
public static final int _cmpop = 6;
public static final int maxT = 18;
static final boolean T = true;
static final boolean x = false;
static final int minErrDist = 2;
public Token t; // last recognized token
public Token la; // lookahead token
int errDist = minErrDist;
public Scanner scanner;
public Errors errors;
LoopBound result;
public LoopBound getResult()
{
return result;
}
LoopBound
buildLoopBound(String cmpop, LoopBoundExpr bound, SymbolicMarker marker)
{
if(bound == null) return null;
if(cmpop.equals("<=")) bound = bound.relaxLowerBound(0);
if(marker == null) return LoopBound.simpleBound(bound);
else return LoopBound.markerBound(bound, marker);
}
/*--------------------------------------------------------------------*/
public Parser(Scanner scanner) {
this.scanner = scanner;
errors = new Errors();
}
void SynErr (int n) {
if (errDist >= minErrDist) errors.SynErr(la.line, la.col, n);
errDist = 0;
}
public void SemErr (String msg) {
if (errDist >= minErrDist) errors.SemErr(t.line, t.col, msg);
errDist = 0;
}
void Get () {
for (;;) {
t = la;
la = scanner.Scan();
if (la.kind <= maxT) {
++errDist;
break;
}
la = t;
}
}
void Expect (int n) {
if (la.kind==n) Get(); else { SynErr(n); }
}
boolean StartOf (int s) {
return set[s][la.kind];
}
void ExpectWeak (int n, int follow) {
if (la.kind == n) Get();
else {
SynErr(n);
while (!StartOf(follow)) Get();
}
}
boolean WeakSeparator (int n, int syFol, int repFol) {
int kind = la.kind;
if (kind == n) { Get(); return true; }
else if (StartOf(repFol)) return false;
else {
SynErr(n);
while (!(set[syFol][kind] || set[repFol][kind] || set[0][kind])) {
Get();
kind = la.kind;
}
return StartOf(syFol);
}
}
void Annotation() {
String cmpop; LoopBoundExpr expr; SymbolicMarker marker;
Expect(7);
Expect(6);
cmpop = t.val;
expr = Expression();
marker = Context();
result = buildLoopBound(cmpop, expr, marker);
}
LoopBoundExpr Expression() {
LoopBoundExpr expr;
LoopBoundExpr e2;
expr = Expression2();
while (la.kind == 8 || la.kind == 9) {
if (la.kind == 8) {
Get();
e2 = Expression2();
expr = expr.add(e2);
} else {
Get();
e2 = Expression2();
expr = expr.subtract(e2);
}
}
return expr;
}
SymbolicMarker Context() {
SymbolicMarker marker;
marker = null;
if (la.kind == 16) {
Get();
int outerLoop = 1;
if (la.kind == 12) {
Get();
Expect(3);
outerLoop = Integer.parseInt(t.val);
Expect(13);
}
marker = SymbolicMarker.outerLoopMarker(outerLoop);
} else if (la.kind == 17) {
Get();
String markerMethod = null;
if (la.kind == 12) {
Get();
Expect(4);
markerMethod = t.val;
Expect(13);
}
marker = SymbolicMarker.methodMarker(markerMethod);
} else if (la.kind == 0) {
} else SynErr(19);
return marker;
}
LoopBoundExpr Expression2() {
LoopBoundExpr expr;
LoopBoundExpr e2;
expr = Expression3();
while (la.kind == 10 || la.kind == 11) {
if (la.kind == 10) {
Get();
e2 = Expression3();
expr = expr.mul(e2);
} else {
Get();
e2 = Expression3();
expr = expr.idiv(e2);
}
}
return expr;
}
LoopBoundExpr Expression3() {
LoopBoundExpr expr;
expr = null;
if (la.kind == 3) {
Get();
expr = LoopBoundExpr.numericBound(t.val, t.val);
} else if (la.kind == 12) {
Get();
expr = Expression();
Expect(13);
} else if (la.kind == 1) {
Get();
String ident = t.val;
expr = IdentExpression(ident);
} else if (la.kind == 2) {
Get();
String ident = t.val;
expr = ArgExpression(ident);
} else SynErr(20);
return expr;
}
LoopBoundExpr IdentExpression(String ident) {
LoopBoundExpr expr;
expr = null;
if (la.kind == 12) {
ArrayList<LoopBoundExpr> args = new ArrayList<LoopBoundExpr>();
Get();
ExpressionList(args);
Expect(13);
expr = LoopBoundExpr.builtInFunction(ident, args);
} else if (StartOf(1)) {
ArrayList<String> members = new ArrayList<String>(); members.add(ident);
while (la.kind == 14) {
Get();
Expect(1);
members.add(t.val);
}
expr = LoopBoundExpr.constRef(members);
} else SynErr(21);
return expr;
}
LoopBoundExpr ArgExpression(String index) {
LoopBoundExpr expr;
ArrayList<String> members = new ArrayList<String>();
while (la.kind == 14) {
Get();
Expect(1);
members.add(t.val);
}
expr = LoopBoundExpr.argRef(index, members);
return expr;
}
void ExpressionList(List args) {
if (StartOf(2)) {
LoopBoundExpr expr;
expr = Expression();
args.add(expr);
while (la.kind == 15) {
Get();
expr = Expression();
args.add(expr);
}
} else if (la.kind == 13) {
} else SynErr(22);
}
public void Parse() {
la = new Token();
la.val = "";
Get();
Annotation();
Expect(0);
}
private static final boolean[][] set = {
{T,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x, x,x,x,x},
{T,x,x,x, x,x,x,x, T,T,T,T, x,T,T,T, T,T,x,x},
{x,T,T,T, x,x,x,x, x,x,x,x, T,x,x,x, x,x,x,x}
};
} // end Parser
class Errors {
public int count = 0; // number of errors detected
public java.io.PrintStream errorStream = System.out; // error messages go to this stream
public String errMsgFormat = "-- line {0} col {1}: {2}"; // 0=line, 1=column, 2=text
protected void printMsg(int line, int column, String msg) {
StringBuffer b = new StringBuffer(errMsgFormat);
int pos = b.indexOf("{0}");
if (pos >= 0) { b.delete(pos, pos+3); b.insert(pos, line); }
pos = b.indexOf("{1}");
if (pos >= 0) { b.delete(pos, pos+3); b.insert(pos, column); }
pos = b.indexOf("{2}");
if (pos >= 0) b.replace(pos, pos+3, msg);
errorStream.println(b.toString());
}
public void SynErr (int line, int col, int n) {
String s;
switch (n) {
case 0: s = "EOF expected"; break;
case 1: s = "ident expected"; break;
case 2: s = "vident expected"; break;
case 3: s = "number expected"; break;
case 4: s = "string expected"; break;
case 5: s = "char expected"; break;
case 6: s = "cmpop expected"; break;
case 7: s = "\"loop\" expected"; break;
case 8: s = "\"+\" expected"; break;
case 9: s = "\"-\" expected"; break;
case 10: s = "\"*\" expected"; break;
case 11: s = "\"/\" expected"; break;
case 12: s = "\"(\" expected"; break;
case 13: s = "\")\" expected"; break;
case 14: s = "\".\" expected"; break;
case 15: s = "\",\" expected"; break;
case 16: s = "\"outer\" expected"; break;
case 17: s = "\"method\" expected"; break;
case 18: s = "??? expected"; break;
case 19: s = "invalid Context"; break;
case 20: s = "invalid Expression3"; break;
case 21: s = "invalid IdentExpression"; break;
case 22: s = "invalid ExpressionList"; break;
default: s = "error " + n; break;
}
printMsg(line, col, s);
count++;
}
public void SemErr (int line, int col, String s) {
printMsg(line, col, s);
count++;
}
public void SemErr (String s) {
errorStream.println(s);
count++;
}
public void Warning (int line, int col, String s) {
printMsg(line, col, s);
}
public void Warning (String s) {
errorStream.println(s);
}
} // Errors
class FatalError extends RuntimeException {
public static final long serialVersionUID = 1L;
public FatalError(String s) { super(s); }
}