Interpreter

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
m (Reverted edits by Ebybymic (Talk); changed back to last version by Marina)
 
(11 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 +
The interpreter pattern is specific implementation of the [[Composite|composite pattern]] generally used for language parsing. In the interpreter pattern a class is produced for each symbol in the language. A statement can then be broken down into a syntax tree of these classes which can in turn be used to interpret the statement.
 +
 +
==Use When==
 +
You should use Interpreter when there is a language that you need to interpret and when the statements of the language can be represented as abstract syntax trees. It works best when:
 +
* the grammar of the language is simple. Otherwise, the class hierarchy for the grammar becomes large and complex.
 +
* the grammar is stable and known when developing the class structure. The interpreter pattern could not be used if the grammar is user definable, for example.
 +
* efficiency is not essential.
 +
 +
==Structure==
 +
 +
[[Image:Interpreter.jpg]]
 +
 +
(from [http://en.wikipedia.org/wiki/Interpreter_pattern wikipedia])
 +
 +
==Participants==
 +
===Abstract Expression===
 +
This class defines the interpret() operation which is implemented by all nodes in the abstract syntax tree.
 +
 +
===Terminal Expression===
 +
This class implements the interpret() operation. A separate class or subclass is needed for each terminal symbol.
 +
 +
===Nonterminal Expression===
 +
This class also implements the interpret() operation which typically calls itself recursively for all parts the nonterminal is composed of. A separate class or subclass of this is required for each rule in the grammar.
 +
 +
===Context===
 +
This class contains information that's global to the interpreter.
 +
 +
===Client===
 +
This class builds the abstract syntax tree (from Terminals and Nonterminals) for one statement in the language defined by the grammar. It then goes on to invoke the interpret() operation.
 +
 +
==Consequences==
 +
*Interpreter makes it easy to change and extend the grammar using inheritance.
 +
*Implementing the grammar is easy because the nodes in the abstract syntax tree have similar interpretations and are usually easy to write. Often, writing these classes can be automated using a compiler or parser generator.
 +
*It is hard to maintain complex grammar using Interpreter because it defines at least one class for every rule in the grammar. This can soon lead to a huge number of classes.
 +
*It is easy to add new ways to interpret an expression.
 +
 +
== Related Patterns ==
 +
* [[Composite]]: The abstract syntax tree uses a [[Composite]] pattern.
 +
* [[Flyweight]]: This pattern can be used to share the terminal symbols.
 +
* [[Iterator]]: This pattern can be used to traverse the Interpreter structure.
 +
* [[Visitor]]: This pattern can be used to collect the behavior for all abstract syntax tree nodes in one class.
 +
 
[[Category:Design Patterns]]
 
[[Category:Design Patterns]]
 
[[Category:Behavioural Patterns]]
 
[[Category:Behavioural Patterns]]
  
 
{{design patterns}}
 
{{design patterns}}

Latest revision as of 03:22, 25 November 2010

The interpreter pattern is specific implementation of the composite pattern generally used for language parsing. In the interpreter pattern a class is produced for each symbol in the language. A statement can then be broken down into a syntax tree of these classes which can in turn be used to interpret the statement.

Contents

Use When

You should use Interpreter when there is a language that you need to interpret and when the statements of the language can be represented as abstract syntax trees. It works best when:

  • the grammar of the language is simple. Otherwise, the class hierarchy for the grammar becomes large and complex.
  • the grammar is stable and known when developing the class structure. The interpreter pattern could not be used if the grammar is user definable, for example.
  • efficiency is not essential.

Structure

Interpreter.jpg

(from wikipedia)

Participants

Abstract Expression

This class defines the interpret() operation which is implemented by all nodes in the abstract syntax tree.

Terminal Expression

This class implements the interpret() operation. A separate class or subclass is needed for each terminal symbol.

Nonterminal Expression

This class also implements the interpret() operation which typically calls itself recursively for all parts the nonterminal is composed of. A separate class or subclass of this is required for each rule in the grammar.

Context

This class contains information that's global to the interpreter.

Client

This class builds the abstract syntax tree (from Terminals and Nonterminals) for one statement in the language defined by the grammar. It then goes on to invoke the interpret() operation.

Consequences

  • Interpreter makes it easy to change and extend the grammar using inheritance.
  • Implementing the grammar is easy because the nodes in the abstract syntax tree have similar interpretations and are usually easy to write. Often, writing these classes can be automated using a compiler or parser generator.
  • It is hard to maintain complex grammar using Interpreter because it defines at least one class for every rule in the grammar. This can soon lead to a huge number of classes.
  • It is easy to add new ways to interpret an expression.

Related Patterns

  • Composite: The abstract syntax tree uses a Composite pattern.
  • Flyweight: This pattern can be used to share the terminal symbols.
  • Iterator: This pattern can be used to traverse the Interpreter structure.
  • Visitor: This pattern can be used to collect the behavior for all abstract syntax tree nodes in one class.


Personal tools