import java.io.*; import java.util.ArrayList; public class RecursiveDescent { public RecursiveDescent() { super(); } /** expr--> term+expr expr--> term */ static boolean expr() throws Exception { int savePointer = pointer; if (term() && nextToken().sym == Calc2Symbol.PLUS && expr()) { System.out.println(" expr-->term + expr"); return true; } pointer = savePointer; if (term()) { System.out.println(" expr-->term"); return true; } pointer = savePointer; return false; } public static void main(String[] args) throws Exception { //construct the token array Calc3Scanner scanner = new Calc3Scanner(new FileInputStream(new File("calc2.input"))); // note that yylex() is the default method to get the next token in scanner that is generated by JLlex. Symbol token; while ((token=scanner.yylex()).sym!= Calc2Symbol.EOF) { System.out.print("<"+token.toString()+ ">"); // check that all the symbols are read in correctly. tokens.add(token); } tokens.add(token); // add EOF as the last token in the array boolean legal= program() && nextToken().sym==Calc2Symbol.EOF; System.out.println(legal); } /** program-->statement program program-->statement */ static boolean program() throws Exception{ int savePointer = pointer; if (statement() && program()) { System.out.println(" program-->statement program"); return true; } pointer = savePointer; if (statement()) { System.out.println(" program-->statement"); return true; } pointer = savePointer; return false; } static boolean statement() throws Exception { int savePointer = pointer; pointer = savePointer; if (assignment() && nextToken().sym == Calc2Symbol.SEMI) { System.out.println(" statement-->assignment;"); return true; } pointer = savePointer; return false; } static int pointer = -1; static ArrayList tokens = new ArrayList(); /** assignment--> ID=exp */ static boolean assignment () throws Exception{ int savePointer= pointer; if (nextToken().sym==Calc2Symbol.ID && nextToken().sym==Calc2Symbol.EQUAL && expr()) { System.out.println(" assignment--> ID=exp"); return true; } pointer = savePointer; return false; } /** exprList --> expr exprList | empty */ static boolean exprList() throws Exception { int savedPointer=pointer; if (expr() && exprList()) return true; pointer = savedPointer; return true; }/** factor --> ID | NUMBER | functionCall | (Expr) */ static boolean factor() throws Exception{ int savePointer = pointer; if (functionCall()) { System.out.println("factor --> functionCall"); return true; } pointer=savePointer; int sym=nextToken().sym; if (sym == Calc2Symbol.ID || sym == Calc2Symbol.NUMBER) { System.out.println(" factor-->ID | NUMBER"); return true; } pointer = savePointer; if (nextToken().sym==Calc2Symbol.LPAREN && expr() && nextToken().sym==Calc2Symbol.RPAREN) return true; pointer = savePointer; return false; } /** functionCall-->ID(exprList) */ static boolean functionCall() throws Exception { int savePointer = pointer; if (nextToken().sym == Calc2Symbol.ID && nextToken().sym == Calc2Symbol.LPAREN && exprList() && nextToken().sym == Calc2Symbol.RPAREN) return true; pointer = savePointer; return false; } static Symbol nextToken() { if (pointer < tokens.size()-1) { pointer++; Symbol token = (Symbol) tokens.get(pointer); System.out.println ("next Token: " + token.toString()); return token; } else return null; } /** term --> factor * term term --> factor */ static boolean term() throws Exception { int savePointer = pointer; if (factor() && nextToken().sym == Calc2Symbol.MULTI && term()) { System.out.println(" term-->factor * term"); return true; } pointer = savePointer; if (factor()) { System.out.println(" term-->factor"); return true; } pointer = savePointer; return false; }}