Partial solutions to the programming assignments ------------------------------------------------ Example grammar with the 'let' construct and power (^) operator: -> 'let' ID '=' | -> -> | empty -> '-' | -> | empty -> | '^' | ID | NUM | '(' ')' This grammar produces the following parse tree for -a^(-3) / \ / \ \ empty / \ \ - empty / | \ ^ | | a | ( ) / \ / \ \ empty / \ | - empty | | 3 The productions and semantic rules implemented as a recursive descent parser in Java: // expr - parse -> 'let' ID '=' | private static int expr(Hashtable exprin, Hashtable exprout) throws IOException { if (token == tokens.TT_WORD && tokens.sval.equals("let")) { getToken(); String id = tokens.sval; getToken(); // advance to '=' if (token != (int)'=') System.out.println("'=' expected"); getToken(); // advance to int val = expr(exprin, exprout); exprout.put(id, new Integer(val)); return val; } else { Hashtable termout = new Hashtable(); int subtotal = term(exprin, termout); return term_tail(subtotal, termout, exprout); } } The productions (of the first grammar above) and semantic rules implemented as a recursive descent parser in Java: // varfun - parse -> '(' ')' | ID | NUM private static int varfun(Hashtable powerin, Hashtable powerout) throws IOException { int val = 0; if (token == (int)'(') { getToken(); val = expr(powerin, powerout); if (token == (int)')') getToken(); else System.out.println("closing ')' expected"); } else if (token == tokens.TT_WORD) { String id = tokens.sval; getToken(); if (powerin.containsKey(id)) val = ((Integer)powerin.get(id)).intValue(); else System.out.println("identifier '" + id + "' unassigned"); powerout = powerin; } else if (token == tokens.TT_NUMBER) { val = (int)tokens.nval; getToken(); powerout = powerin; } else { System.out.println("power expected"); powerout = powerin; } return val; } } The main method should set up the Hashtables and invoke expr: // set up hashtables Hashtable exprin = new Hashtable(); Hashtable exprout = new Hashtable(); // parse expression and get calculated value: int value = expr(exprin, exprout);