Interpreter Co je to interpreter interpret Motivace Obecn
Interpreter
Co je to interpreter (interpret) ❏ Motivace ❏ Obecný problém, jehož různé instance je třeba často řešit ❏ Jednotlivé instance lze vyjádřit větami v jednoduchém jazyce ❏ Obecné řešení ❏ Vytvoříme interpret tohoto jazyka ❏ Forma abstraktního syntaktického stromu ❏ Interpretace věty jazyka = řešení dané instance problému
Interpreter - obsah ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Interpreter - ilustrace ❏ Hudebník = interpereter
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Interpret - postfix kalkulačka ❏ Výraz ❏ “ 9 8 7 - +” ❏ Stromová reprezentace ❏ Algoritmus (zjednodušený) ❏ Vytvořit prázdný zásobník. ❏ Vytvoř seznam tokenů rozdělením vstupního řetězce podle mezer ❏ Pro každý token. ❏ Pokud je symbol číslo, tak toto číslo přidej do zásobníku. ❏ Pokud je symbol operátor, vytáhni ze zásobníku příslušný počet čísel a aplikuj operátor, výsledek operátoru vrať do zásobníku. ❏ Pokud je výraz přečten bez chyb a v zásobníku je pouze jedna hodnota, tak hodnota v zásobníku je výsledek výrazu.
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Interpreter – struktura obecně
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Interpreter – účastníci ❏ Abstract. Expression ❏ Deklaruje abstraktní metodu Interpret() ❏ Implementace zajišťuje interpretaci zpracovávaného pojmu ❏ Terminal. Expression ❏ Implementuje metodu Interpret() asociovanou s terminálem gramatiky ❏ Instance pro každý terminální symbol ve vstupu (větě) ❏ Nonterminal. Expression ❏ Implementuje metodu Interpret() neterminálu gramatiky ❏ Třída pro každé pravidlo R: : =R 1 R 2…RN gramatiky ❏ Udržuje instance proměnných typu Abstract. Expression pro každý symbol R 1…RN ❏ Context ❏ Udržuje globální informace ❏ Client ❏ Dostane (vytvoří) abstraktní syntaktický strom reprezentující konkrétní větu jazyka ❏ složený z instancí Nonterminal. Expression a Terminal. Expression ❏ Volá metodu Interpret()
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Interpreter - postfix kalkulačka a interpret public interface Expression { interpret(); }
Interpreter - postfix kalkulačka a interpret ❏ Terminal Expression public class Number. Expression implements Expression{ private int number; public Number. Expression(int number){ this. number=number; } public Number. Expression(String number){ this. number=Integer. parse. Int(number); } @Override public interpret(){ return this. number; } }
Interpreter - postfix kalkulačka a interpret ❏ Nonterminal expression public class Addition. Expression implements Expression { private Expression first. Expression, second. Expression; public Addition. Expression( Expression first. Expression, Expression second. Expression){ this. first. Expression=first. Expression; this. second. Expression=second. Expression; } @Override public interpret(){ return this. first. Expression. interpret() + this. second. Expression. interpret(); } }
Interpreter - postfix kalkulačka a interpret public class Parser. Util { public static boolean is. Operator(String symbol) { return (symbol. equals("+") || symbol. equals("-") || symbol. equals("*")); } public static Expression get. Expression. Object( Expression first. Exp, Expression second. Exp, String symbol){ if(symbol. equals("+")) return new Addition. Expression(first. Exp, second. Exp); else if(symbol. equals("-")) return new Subtraction. Expression(first. Exp, second. Exp); else return new Multiplication. Expression(first. Exp, second. Exp); } }
Interpreter - postfix kalkulačka a interpret public class Expression. Parser { Stack stack = new Stack<>(); public int parse(String str){ String[] token. List = str. split(" "); for (String symbol : token. List) { if (!Parser. Util. is. Operator(symbol)) { Expression number. Exp = new Number. Expression(symbol); stack. push(number. Exp); } else if (Parser. Util. is. Operator(symbol)) { Expression first. Exp = stack. pop(); Expression second. Exp = stack. pop(); Expression operator = Parser. Util. get. Expression. Object(first. Exp, second. Exp, symbol); } } int result = stack. pop(). interpret(); return result; } }
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Interpreter – součásti vzoru Vzor obsahuje: ❏ Gramatiku ❏ Popisující jazyk, v němž budeme přijímat instance problému ❏ Co nejjednodušší ❏ Reprezentaci gramatiky v kódu ❏ Pro každé pravidlo gramatiky specifikuje třídu ❏ Třídy jsou jednotně zastřešeny abstraktním předkem ❏ Vztahy mezi třídami (dědičnost) odpovídají gramatice ❏ Reprezentaci kontextu interpretace Vzor neobsahuje: ❏ Parser pro konstrukci syntaktického stromu instance problému
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Interpreter - JSON ❏ Serializace objektové struktury v nějakém API
Interpreter - JSON ❏ Primitivní typy ❏ String ❏ Int ❏ Kompozitní typy ❏ Objekt ❏ Pole { "name": "RNDr. Filip Zavoral, Ph. D. ", "subjects": [ { "name": "Design Patterns", "semester": "Summer", "code" : "NPRG 024" }, { "name": "Cloud Application Development", "semester": "Summer", "code" : "NSWI 152" } ], "cabinet": { "floor": "2", "room": "203" } }
Interpreter - JSON serializace ❏ Stromová struktura ❏ Nutné projít každý vrchol ❏ Pro serializaci vrcholu je nutné mít serializaci všech podstromů ❏ Rekurzivní průběh serializace
Interpreter - JSON serializace interface JSONSerializable { String to. JSON(); } ❏ Nutné implementovat metodu to. JSON() ❏ Zavoláme serializi na všech potomcích ❏ Ze získaných hodnot poskládáme reprezentaci objektu
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Klasický příklad – gramatika ❏ Příklad: gramatika regulárního výrazu ❏ expression : : = literal | alternation | sequence | repetition | '(' expression ')' ❏ alternation : : = expression '|' expression ❏ sequence : : = expression '&' expression ❏ repetition : : = expression '*' ❏ literal : : = 'a' | 'b' | 'c' |. . . { 'a' | 'b' | 'c' |. . . }*
Klasický příklad – reprezentace gramatiky ❏ Příklad: gramatika regulárního výrazu ❏ expression : : = literal | alternation | sequence | repetition | '(' expression ')' ❏ alternation : : = expression '|' expression ❏ sequence : : = expression '&' expression ❏ repetition : : = expression '*' ❏ literal : : = 'a' | 'b' | 'c' |. . . { 'a' | 'b' | 'c' |. . . }* ❏ Její reprezentace v kódu Třída pro každé pravidlo gramatiky (instance udržují podvýraz), symboly na pravých stranách pravidel jsou v proměnných Abstraktní třída
Klasický příklad – reprezentace vět ❏ Příklad: gramatika regulárního výrazu ❏ expression : : = literal | alternation | sequence | repetition | '(' expression ')' ❏ alternation : : = expression '|' expression ❏ sequence : : = expression '&' expression ❏ repetition : : = expression '*' ❏ literal : : = 'a' | 'b' | 'c' |. . . { 'a' | 'b' | 'c' |. . . }* ❏ Abstraktní syntaktický strom ❏ Každý regulární výraz je reprezentován ❏ abstraktním syntaktickým stromem, ❏ tvořeným instancemi zmíněných tříd
Klasický příklad – reprezentace vět ❏ Příklad: gramatika regulárního výrazu ❏ expression : : = literal | alternation | sequence | repetition | '(' expression ')' ❏ alternation : : = expression '|' expression ❏ sequence : : = expression '&' expression ❏ repetition : : = expression '*' ❏ literal : : = 'a' | 'b' | 'c' |. . . { 'a' | 'b' | 'c' |. . . }* ❏ Abstraktní syntaktický strom ❏ Každý regulární výraz je reprezentován ❏ abstraktním syntaktickým stromem, ❏ tvořeným instancemi zmíněných tříd Reprezentace regulárního výrazu raining & ( dog | cats ) *
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Příklad s booleovskými výrazy v Java(1) ❏ Práce s booleovskými výrazy ❏ Boolean. Exp : : = Variable. Exp | Constant | Or. Exp | And. Exp | Not. Exp | '(' Boolean. Exp ')' ❏ And. Exp : : = Boolean. Exp 'and' Boolean. Exp ❏ Or. Exp : : = Boolean. Exp 'or' Boolean. Exp ❏ Not. Exp : : = 'not' Boolean. Exp ❏ Constant : : = 'true' | 'false' ❏ Variable. Exp : : = 'A' | 'B' |. . . | 'X' | 'Y' | 'Z' Interface pro všechny třídy definující booleovský výraz interface Boolean. Exp { public bool interpret(Context context); }; class Context { public bool lookup(String name); public void assign(Variable. Exp exp, boolean bool); }; Kontext definuje mapování proměnných na booleovské hodnoty tj. konstanty ‘true’ a ‘false’
Příklad s booleovskými výrazy v Java(2) ❏ Třída pro reprezentaci pravidla Variable. Exp : : = 'A' | 'B' |. . . | 'X' | 'Y' | 'Z‘ class Variable. Exp implements Boolean. Exp { private String name; Variable. Exp(String name){ this. name = name; }; public boolean interpret(Context context){ return context. lookup(name); } }; ❏ Třída pro reprezentaci pravidla Constant : : = 'true' | 'false' class Constant implements Boolean. Exp { private boolean bool; Constant(boolean bool){ this. bool = bool; }; public boolean interpret(Context context){ return bool; } };
Příklad s booleovskými výrazy v Java(3) ❏ Třída pro reprezentaci pravidla And. Exp : : = Boolean. Exp 'and' Boolean. Exp class And. Exp implements Boolean. Exp { private Boolean. Exp operand 1; private Boolean. Exp operand 2; And. Exp(Boolean. Exp op 1, Boolean. Exp op 2){ operand 1 = op 1; operand 2 = op 2; }; public boolean interpret(Context context){ return operand 1. interpret(context) && operand 2. interpret(context); }; }; Obdobně také třídy pro pravidla Or. Exp a Not. Exp
Příklad s booleovskými výrazy v Java(4) ❏ Vytvoření instance výrazu a jeho interpretace Boolean. Exp expression; Context context; Vytvoření abstraktního syntaktického stromu pro výraz (true and x) or (y and (not x)) Variable. Exp x = new Variable. Exp("X"); Variable. Exp y = new Variable. Exp("Y"); expression = new Or. Exp( new And. Exp(new Constant(true), x), new And. Exp(y, new Not. Exp(x)) ); Ohodnocení proměnných context. assign(x, false); context. assign(y, true); boolean result = expression. intepret(context); Interpretuje výraz jako true, můžeme změnit ohodnocení a znovu provést interpretaci
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Složitější příklad - kalkulačka ❏ Kalkulačka expression : : = plus | minus | variable | number plus : : = expression '+' expression minus : : = expression '-' expression variable : : = 'a' | 'b' | 'c' |. . . | 'z' digit : : = '0' | '1' |. . . | '9' number : : = digit | digit number
Složitější příklad (2) – kalkulačka (java) import java. util. Map; interface Expression { public interpret(final Map<String, Expression> variables); } class Number implements Expression { private int number; public Number(final int number) { this. number = number; } public interpret(final Map<String, Expression> variables) return number; } } {
Složitější příklad (3) – kalkulačka (java) class Plus implements Expression { Expression left. Operand; Expression right. Operand; public Plus(final Expression left, final Expression right) { left. Operand = left; right. Operand = right; } public interpret(final Map<String, Expression> variables) { return left. Operand. interpret(variables) + right. Operand. interpret(variables); } } class Minus implements Expression { Expression left. Operand; Expression right. Operand; public Minus(final Expression left, final Expression right) { left. Operand = left; right. Operand = right; } public interpret(final Map<String, Expression> variables) { return left. Operand. interpret(variables) right. Operand. interpret(variables); } }
Složitější příklad (4) – kalkulačka (java) class Variable implements Expression { private String name; public Variable(final String name) { this. name = name; } public interpret(final Map<String, Expression> variables) { if (null == variables. get(name)) return 0; return variables. get(name). interpret(variables); } }
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Interpreter – použití s dalšími vzory ❏ Composite ❏ Nejčastější kombinace ❏ Struktura stromu je implementace Composite ❏ Visitor ❏ podobný způsob procházení stromu ❏ oddělena funkcionalita od dat ❏ může nejen vypočítávat nějakou hodnotu, ale i data transformovat ❏ Iterator ❏ Klasické procházení strukturou ❏ Důležitý společný abstraktní předek ❏ Flyweight ❏ Typické pro překladače ❏ Sdílení konstantních výrazů vyhodnocovaných v compile-time
Interpreter – použití s dalšími vzory ❏ Visitor ❏ Můžeme použít pro zvýšení udržitelnosti a možnosti rozšíření metody interpret ❏ S užitím polymorfismu na Visitor můžeme dosáhnout zcela různých interpretací ❏ Příklady: ❏ Aritmetické výrazy a přepínání mezi prefix, postfix a infix notací ❏ Booleovské výrazy – různá chování, např. vyhodnocení pravdivostní hodnoty formule a převod CNF ❏ Konfigurační soubory: převod mezi XML a plain-text formátem ❏. . .
Interpreter - přehled ❏ Ilustrace ❏ Postfix kalkulačka ❏ Interpret ❏ Struktura ❏ Účastníci ❏ Postfix kalkulačka a interpret ❏ Součásti vzoru ❏ Další příklady ❏ JSON ❏ Regulární výrazy ❏ Booleova algebra ❏ Složitější kalkulačka ❏ Použití s dalšími vzory ❏ Shrnutí
Interpreter - shrnutí ❏ Typické použití ❏ Parsery a kompilátory ❏ Omezení použitelnosti ❏ Interpretace jazyka, jehož věty lze vyjádřit abstraktním syntaktickým stromem ❏ Gramatika jazyka je jednoduchá ❏ Složitější gramatiky → nepřehledný kód, exploze tříd ❏ Efektivita není kriticky důležitá ❏ Jinak lépe nekonstruovat syntaktický strom → stavový automat ❏ Výhody ❏ Lehce rozšířitelná/změnitelná gramatika ❏ Jednoduchá implementace gramatiky ❏ Přidávání dalších metod interpretace ❏ Nevýhody ❏ Složitá gramatika těžce udržovatelná
- Slides: 44