/************************************************************ * This is a recursive descent interpreter for the SLP * * language. This parser uses the SLP lexical analyser * * produced by JavaCC. Before implementing the parser, * * the grammar of the language was converted into the * * following form to allow predictive parsing: * * * * Stm -> id := Exp Stm' * * | print ( ExpList ) Stm' * * Stm' -> ; Stm * * | (empty string) * * Exp -> id Exp' * * | num Exp' * * | ( Stm , Exp ) Exp' * * Exp' -> Binop Exp * * | (empty string) * * ExpList -> Exp ExpList' * * ExpList' -> , ExpList * * | (empty string) * * Binop -> + * * | - * * | * * * | / * * * ************************************************************/ public class SLPRecInt implements SLPTokeniserConstants { public static Token t; public static Table Stm(Table tab) { String id; IntAndTable it; IntListAndTable ilt; if (t.kind == ID) { id = t.image; t = SLPTokeniser.getNextToken(); if (t.kind == ASSIGN) { t = SLPTokeniser.getNextToken(); it = Exp(tab); if (tab == null) tab = new Table(id,it.i,tab); else tab = tab.update(tab,id,it.i); } else error(":="); } else if (t.kind == PRINT) { t = SLPTokeniser.getNextToken(); if (t.kind == LBR) { t = SLPTokeniser.getNextToken(); ilt = ExpList(tab); if (t.kind == RBR) { t = SLPTokeniser.getNextToken(); ilt.il.print(); tab = ilt.t; } else error(")"); } else error("("); } else error("identifier or print"); return Stm_Prime(tab); } public static Table Stm_Prime(Table tab) { if (t.kind == SEMIC) { t = SLPTokeniser.getNextToken(); return Stm(tab); } else return tab; } public static IntAndTable Exp(Table tab) { IntAndTable it=null; if (t.kind == ID) { it = new IntAndTable(tab.lookup(tab,t.image),tab); t = SLPTokeniser.getNextToken(); } else if (t.kind == NUM) { it = new IntAndTable(Integer.parseInt(t.image),tab); t = SLPTokeniser.getNextToken(); } else if (t.kind == LBR) { t = SLPTokeniser.getNextToken(); tab = Stm(tab); if (t.kind == COMMA) { t = SLPTokeniser.getNextToken(); it = Exp(tab); if (t.kind == RBR) { t = SLPTokeniser.getNextToken(); } else error(")"); } else error(","); } else error("identifier, number or ("); return Exp_Prime(it); } public static IntAndTable Exp_Prime(IntAndTable it1) { IntAndTable it2; switch(t.kind) { case PLUS_SIGN: Binop(); it2 = Exp(it1.t); return new IntAndTable(it1.i+it2.i,it2.t); case MINUS_SIGN: Binop(); it2 = Exp(it1.t); return new IntAndTable(it1.i-it2.i,it2.t); case MULT_SIGN: Binop(); it2 = Exp(it1.t); return new IntAndTable(it1.i*it2.i,it2.t); case DIV_SIGN: Binop(); it2 = Exp(it1.t); return new IntAndTable(it1.i/it2.i,it2.t); default: return it1; } } public static IntListAndTable ExpList(Table tab) { IntAndTable it; IntListAndTable ilt; it = Exp(tab); ilt = ExpList_Prime(it.t); return new IntListAndTable(new IntList(it.i,ilt.il),it.t); } public static IntListAndTable ExpList_Prime(Table tab) { if (t.kind == COMMA) { t = SLPTokeniser.getNextToken(); return ExpList(tab); } else return new IntListAndTable(null,tab); } public static void Binop() { t = SLPTokeniser.getNextToken(); } /* * The error routine prints out the line number of the error, * along with the encountered lexeme. The String argument * indicates which tokens were expected in the input. */ public static void error(String msg) { System.out.print("Syntax error at line " + t.beginLine); System.out.println(": encountered " + t.image + " when " + msg + " expected"); System.exit(0); } public static void main(String args[]) { SLPTokeniser tokeniser; /* * Firstly, decide if we're taking input from standard input * or from a file whose name was given as an argument... * (This piece of code is fairly standard) */ if (args.length == 0) { System.out.println("Reading from standard input . . ."); tokeniser = new SLPTokeniser(System.in); } else if (args.length == 1) { try { tokeniser = new SLPTokeniser(new java.io.FileInputStream(args[0])); } catch (java.io.FileNotFoundException e) { System.err.println("File " + args[0] + " not found."); return; } } else { System.out.println("SLP Recursive Descent Interpreter: Usage is one of:"); System.out.println(" java SLPRecInt < inputfile"); System.out.println("OR"); System.out.println(" java SLPRecInt inputfile"); return; } t = SLPTokeniser.getNextToken(); Table tab = Stm(null); } }