Interpreter
JaninaVoigt (Talk | contribs) (→Participants) |
|||
(6 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
− | The interpreter pattern is specific | + | 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== | ==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: | 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 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. | * efficiency is not essential. | ||
Line 17: | Line 18: | ||
===Terminal Expression=== | ===Terminal Expression=== | ||
− | This class implements the interpret() operation. | + | This class implements the interpret() operation. A separate class or subclass is needed for each terminal symbol. |
===Nonterminal Expression=== | ===Nonterminal Expression=== | ||
− | This class also implements the interpret() operation which typically calls itself recursively for all parts the nonterminal is composed of. | + | 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=== | ===Context=== | ||
Line 30: | Line 31: | ||
==Consequences== | ==Consequences== | ||
*Interpreter makes it easy to change and extend the grammar using inheritance. | *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 | + | *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 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. | *It is easy to add new ways to interpret an expression. |
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
(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.
Design patterns | |
---|---|
Creational: Abstract Factory | Builder | Factory Method | Prototype | Singleton |