Narzędzia użytkownika

Narzędzia witryny


interpreter

Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
interpreter [2008/12/07 10:38]
posciak
interpreter [2008/12/07 11:19]
posciak
Linia 34: Linia 34:
 === Podstawowe kroki implementacji === === Podstawowe kroki implementacji ===
  
-  * Tworzenie klas wyrażeń - każde wyrażenie terminalne i nieterminalne jest reprezentowane przez inną klasę pochodną od typu Expression (a właściwie od typów NonterminalExpression i TerminalExpression). Na przykład dla języka wyrażeń arytmetycznych powstaną m.in. klasy WyrażenieSuma,​ WyrażenieRóżnica pochodne od NonterminalExpression i WyrażenieLiczba,​ pochodne od klasy TerminalExpression. Tworzenie klas dla wszystkich możliwych wyrażeń terminalnych może być kłopotliwe ze względu na ich ilość, np. dla wyrażeń arytmetycznych zamiast tworzenia oddzielnej klasy dla każdej możliwej liczby, można stworzyć jedną klasę Liczba, zawierającą jej wartość.+  ​* **Tworzenie klas wyrażeń** - każde wyrażenie terminalne i nieterminalne jest reprezentowane przez inną klasę pochodną od typu Expression (a właściwie od typów NonterminalExpression i TerminalExpression). Na przykład dla języka wyrażeń arytmetycznych powstaną m.in. klasy WyrażenieSuma,​ WyrażenieRóżnica pochodne od NonterminalExpression i WyrażenieLiczba,​ pochodne od klasy TerminalExpression. Tworzenie klas dla wszystkich możliwych wyrażeń terminalnych może być kłopotliwe ze względu na ich ilość, np. dla wyrażeń arytmetycznych zamiast tworzenia oddzielnej klasy dla każdej możliwej liczby, można stworzyć jedną klasę Liczba, zawierającą jej wartość.
  
-  * Tworzenie klasy kontekstu - w przypadku wyrażeń arytmetycznych powinien on przechowywać bieżącą (do tej pory obliczoną) wartość wyrażenia i zależności pomiędzy danym wyrażeniem,​ a jego sąsiadami.+  ​* **Tworzenie klasy kontekstu** - w przypadku wyrażeń arytmetycznych powinien on przechowywać bieżącą (do tej pory obliczoną) wartość wyrażenia i zależności pomiędzy danym wyrażeniem,​ a jego sąsiadami.
  
-  * Tworzenie drzewa zdania - nie jest zaliczane do zagadnienia wzorca interpretera,​ zazwyczaj realizowane przez zewnętrzny parser.+  ​* **Tworzenie drzewa zdania** - nie jest zaliczane do zagadnienia wzorca interpretera,​ zazwyczaj realizowane przez zewnętrzny parser.
  
-  * Definiowanie funkcji interpretującej - zazwyczaj jako metody klasy podstawowej AbstractExpression. Nie zawsze jest konieczne, aby była ona wirtualna (wystarczy, aby korzystała ona z innych metod wirtualnych w danej klasie - patrz przykład poniżej). Jeśli jednak zajdzie taka potrzeba, warto rozpatrzyć możliwość zastosowania wzorca Wizytatora.+  ​* **Definiowanie funkcji interpretującej** - zazwyczaj jako metody klasy podstawowej AbstractExpression. Nie zawsze jest konieczne, aby była ona wirtualna (wystarczy, aby korzystała ona z innych metod wirtualnych w danej klasie - patrz przykład poniżej). Jeśli jednak zajdzie taka potrzeba, warto rozpatrzyć możliwość zastosowania wzorca Wizytatora.
  
 === Opcjonalne zagadnienia ​ === === Opcjonalne zagadnienia ​ ===
-  * Akcje domyślne - przydatne może być określenie domyślnego wyniku interpretacji w klasie podstawowej wyrażenia dla wyrażeń nie mających konkretnego efektu (np. tylko służących do rozwijania podwyrażeń i oddających dalszą kontrolę tym podwyrażeniom). +  ​* **Akcje domyślne** - przydatne może być określenie domyślnego wyniku interpretacji w klasie podstawowej wyrażenia dla wyrażeń nie mających konkretnego efektu (np. tylko służących do rozwijania podwyrażeń i oddających dalszą kontrolę tym podwyrażeniom). 
-  * Wyrażenia współdzielone - możliwe jest wielokrotne użycie instancji danego wyrażenia (np. konkretnej liczby) dla wielu wyrażeń w celu oszczędności pamięci. Na przykład dla wyrażenia "2 + 5 - 2" można dwukrotnie skorzystać z klasy reprezentującej terminal "​2"​. Należy przy tym pamiętać, aby nie zapamiętywać stanu (kontekstu) w klasie wyrażenia, gdyż zazwyczaj jest on różny na różnych etapach interpretacji. +  ​* **Wyrażenia współdzielone** - możliwe jest wielokrotne użycie instancji danego wyrażenia (np. konkretnej liczby) dla wielu wyrażeń w celu oszczędności pamięci. Na przykład dla wyrażenia "2 + 5 - 2" można dwukrotnie skorzystać z klasy reprezentującej terminal "​2"​. Należy przy tym pamiętać, aby nie zapamiętywać stanu (kontekstu) w klasie wyrażenia, gdyż zazwyczaj jest on różny na różnych etapach interpretacji. 
-  * Wielowątkowość - jeśli możliwe jest rozwiązywanie podwyrażeń w oddzielnych wątkach.+  ​* **Wielowątkowość** - jeśli możliwe jest rozwiązywanie podwyrażeń w oddzielnych wątkach. 
 + 
 +===== Przydatność ===== 
 +Wzorzec interpretera działa najlepiej, gdy: 
 +  * gramatyka jest stosunkowo prosta - dla skomplikowanych gramatyk hierarchia klas staje się duża i trudna w utrzymaniu. 
 +  * efektywność nie jest cechą krytyczną  
 +  * istotna jest możliwość łatwej zmiany i rozszerzania gramatyki - wystarczy dodać nowe klasy do hierarchii lub zmodyfikować istniejące 
 + 
 +===== Przykład ===== 
interpreter.txt · ostatnio zmienione: 2008/12/07 11:33 przez posciak