(12 september 2018 OU2 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
(12 september 2018 OU2 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);
(12 september 2018 OU2 3 ) Kalylatorns main-metod public static void main(string[] args) throws IOException { System.out.println("Numerical calculator version 2018-09-11"); Calculator calc = new Calculator(new Stokenizer()); while (true) { statement();
(12 september 2018 OU2 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
(12 september 2018 OU2 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 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.(); System.out.println(parsed); variables.put("ans", new Double(parsed)); if (!tokenizer.iseol()) { throw new SyntaxException("Expected EOL");
(12 september 2018 OU2 6 ) Syntaxdiagram: Specifikation för Parser-klassen expression expression term = word + eller term Obs: Hette tidigare factor factor ( ) * eller / function name factor number function name word sin cos exp log
(12 september 2018 OU2 7 ) 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");
(12 september 2018 OU2 8 ) Parser-mallen public double () { 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 ();
(12 september 2018 OU2 9 ) 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;
Tips om hantering av funktionsanropen Funktionsanropen har alla samma syntax: funktionsnamn() function name sin cos exp ( ) log function name number word (12 september 2018 OU2 10 )
(12 september 2018 OU2 11 ) Tips om hantering av funktionsanropen 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 {...
(12 september 2018 OU2 12 ) 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.
(12 september 2018 OU2 13 ) Var kan syntaxfel upptäckas? expression expression term = word + eller term factor ( ) * eller / function name factor number function name word sin cos exp log
(12 september 2018 OU2 14 ) Var kan syntaxfel upptäckas? expression expression term = word + eller term factor ( ) * eller / function name factor function name sin cos exp log number word
(12 september 2018 OU2 15 ) Var kan syntaxfel upptäckas? statement EOL quit EOL vars file filename
(12 september 2018 OU2 16 ) Var kan syntaxfel upptäckas? statement EOL quit EOL vars file filename
(12 september 2018 OU2 17 ) Tips Lägg in undantagshanteringen från början! Se till att följande skrivs ut: Vilken/vilka tokar som förväntades Vilken tok som hittades (gettoken()) Vilken den närmast föregående token var (getprevioustoken()). Det underlättar i hög grad felsökningen i ert program!