(11 april 2016 T03.1 ) Obligatorisk uppgift: Numerisk kalkylator Följande klasser skall ingå Calculator Stokenizer Parser Till stor del given. Kompletteras bara med exceptionhantering. Given - skall användas (i oförändrat skick)! En mall ( ParserTemplate ) given SyntaxException EvaluationException
(11 april 2016 T03.2 ) Klassen Calculator Huvudklass för kalkylatorn. Innehåller konstruktor, statement (med en hjälpmetod) samt main-metoden. public class Calculator { private Parser parser; private Stokenizer tokenizer; private Map<String, Double> variables; public Calculator(Stokenizer tokenizer) { this.tokenizer = tokenizer; variables = new TreeMap<String, Double>(); variables.put("pi", Math.PI); variables.put("e", Math.E); variables.put("ans", new Double(0.)); parser = new Parser(tokenizer, variables);
(11 april 2016 T03.3 ) Kalylatorns main-metod public static void main(string[] args) throws IOException { System.out.println("Numerical calculator version 2016-04-10"); Calculator calc = new Calculator(new Stokenizer()); while (true) { statement();
(11 april 2016 T03.4 ) Kalylatorns statement-metod public void statement() { try { calc.line(); catch (SyntaxException syntaxexception) { throw syntaxexception; catch (EvaluationException evaluationexception) { throw evaluationexception; Röd kod ska ersättas med kod som ger felutskrift och ser till att tokenizern positioneras till slutet på raden
(11 april 2016 T03.5 ) Hjälpmetod till statement private void line() { do { System.out.print("> "); tokenizer.nexttoken(); while (tokenizer.iseol()); // Skip empty lines statement EOL quit vars file filename assignment EOL String command = tokenizer.gettoken(); // First token if (command.equals("quit") tokenizer.iseos()) { System.out.println("Bye!"); System.exit(0); else if (command.equals("vars")) { System.out.println(variables); tokenizer.nexttoken(); else { double parsed = parser.assignment(); System.out.println(parsed); variables.put("ans", new Double(parsed)); if (!tokenizer.iseol()) { throw new SyntaxException("Expected EOL");
(11 april 2016 T03.6 ) Syntaxdiagram: Specifikation för Parser-klassen assignment expression expression term = word + term factor Obs: Hette tidigare factor ( assignment ) * / word ( exp factor log sin cos variable number
(11 april 2016 T03.7 ) Syntaxdiagram: Alternativ för -metoden ( assignment ) ( assignment ) exp ( word ( log exp sin log cos sin cos variable number number word Blir renare att koda...
(11 april 2016 T03.8 ) Parser-mallen public class ParserTemplate { private Stokenizer tokenizer; private Map<String, Double> variables; private TreeSet<String> functions; public ParserTemplate(Stokenizer tokenizer, Map<String,Double> variables) { this.tokenizer = tokenizer; this.variables = variables; functions = new TreeSet<String>(); functions.add("sin"); functions.add("cos"); functions.add("exp"); functions.add("log");
(11 april 2016 T03.9 ) Parser-mallen public double assignment() { double result = expression(); return result; public double expression() { double sum = term(); return sum; public double term() { double prod = factor(); return prod; public double factor() { return ();
(11 april 2016 T03.10 ) Parser-mallen public double () { double result = 99999; if (tokenizer.isnumber()) { result = tokenizer.getnumber(); tokenizer.nexttoken(); else { throw new SyntaxException(" not complete yet: " + tokenizer.gettoken()); return result;
(11 april 2016 T03.11 ) Tips om hantering av funktionsanropen Funktionsanropen har alla samma syntax: funktionsnamn(assignment) Hanteringen av argumentet (syntaxkontroll av och evaluering) bör alltså göras gemensamt på ett ställe. Inget klipp och klistrande av kod, alltså! För att underlätta det har parsern försetts med ett TreeSet<String> functions som innehåller funktionsnamnen. Följande kod passar då in någonstans i... else if (funtions.contains(tokenizer.gettoken()) { result = functionhandler(tokenizer.gettoken()) else if {...
(11 april 2016 T03.12 ) - ny version att koda efter ( assignment ) ( function name number word
(11 april 2016 T03.13 ) Hjälpmetoden functionhandler double functionhandler(string functionname) { tokenizer.nexttoken(); // Pass the function name if (tokenizer.getchar()!= ( ) throw new SyntaxException(...); double argument = (); // Handles the parentheses if (functionname.equals("exp")) return Math.exp(argument); else if (... )... else if (... )...... Metoden utnyttjar alltså för kontrollen av högerparentesen.
(11 april 2016 T03.14 ) Var kan syntaxfel upptäckas? assignment expression = word
(11 april 2016 T03.15 ) Var kan syntaxfel upptäckas? assignment expression = word
(11 april 2016 T03.16 ) Var kan syntaxfel upptäckas? ( assignment ) word ( exp log sin cos variable number
(11 april 2016 T03.17 ) Var kan syntaxfel upptäckas? ( assignment ) word ( exp log sin cos variable number
(11 april 2016 T03.18 ) Var kan syntaxfel upptäckas? statement EOL quit EOL vars file filename assignment
(11 april 2016 T03.19 ) Var kan syntaxfel upptäckas? statement EOL quit EOL vars file filename assignment