This essay has been submitted by a student. This is not an example of the work written by our professional essay writers.
Abstract:- TheÂ InterpreterÂ pattern is used to model a grammar using a set of classes that represent possible expressions within the grammar. For instance, for the algebraic expression 4 + 4, anÂ AddExpressionÂ class can be used to represent the expression. Included in theÂ AddExpressionÂ class would be a reference to the two operands and the capacity to evaluate the expression and return a value based on the two operands.
1.INTRODUCTION: WHAT IS INTERPRETER DESIGN PATTERN?:
The interpreter pattern is aÂ Gang of Four design pattern. This is aÂ behaviouralÂ pattern as it defines a manner for controlling communication betweenÂ classesÂ or entities. The interpreter pattern is used to define the grammar for instructions that form part of a language or notation, whilst allowing the grammar to be easily extended.
The interpreter pattern performs activities base upon a hierarchy of expressions. Each expression isÂ terminal, meaning that it is a standalone structure that can be immediately evaluated, orÂ non-terminal, meaning that it is composed of one or more expressions. The tree structure is similar to that defined by theÂ composite design pattern, with terminal expressions being leaf objects and non-terminal expressions being composites. The tree contains the expressions to be evaluated and is usually generated by aÂ parser. The parser itself is not a part of the interpreter pattern.
The interpreter design pattern is useful for simple languages where performance is not critical. As the grammar becomes more complex, the number of different expression types, each represented by its own class, can become unwieldy and lead to unmanageable class hierarchies. This can also slow the processing of the expressions. For these reasons, the pattern is considered to be inefficient and is rarely used. However, it should not be discounted for some situations.
An example of the use of the interpreter design pattern could be the processing of mathematical problems provided in a simplifiedÂ Polish notation. This notation defines a mathematical operator followed by two values, for example "+ 5 6". In this case, the + symbol indicates that the two following values should be summed, giving 11. The notation allows multiple operators and values to be included in the string, for example "+ - 6 5 7". In this case, the subtraction would be applied to the 6 and 5 to give 1. The addition would then be applied to the calculated 1 and the 7 for a final result of 8. Polish notation is useful because it does not require the use of parentheses to avoid ambiguity.
2.INTENT OF INTERPRETER DESIGN PATTERN:
Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in theÂ language.
Map a domain to a language, the language to a grammar, and the grammar to a hierarchical object-orientedÂ design.
A class of problems occurs repeatedly in a well-defined and well-understood domain. If the domain were characterized with a "language", then problems could be easily solved with an interpretationÂ "engine".
The Interpreter pattern discusses: defining a domain language (i.e. problem characterization) as a simple language grammar, representing domain rules as language sentences, and interpreting these sentences to solve the problem. The pattern uses a class to represent each grammar rule. And since grammars are usually hierarchical in structure, an inheritance hierarchy of rule classes mapsÂ nicely.
An abstract base class specifies the methodÂ interpret(). Each concrete subclass implementsÂ interpret()Â by accepting (as an argument) the current state of the language stream, and adding its contribution to the problem solvingÂ process.
The structure of the project follows the general structure of a parser in compiler terms. At a high level, a parser transforms a character sequence in a well-defined grammar into an intermediate data structure that can be evaluated at a later point while varying its input. At a lower level, the first step in the parsing process is to transform the character sequence into a token sequence. This step is called lexical analysis. The next step is to transform the token sequence into the intermediate data structure that can be evaluated.
TheÂ AXTokenizerÂ class is responsible for transforming the initial character sequence into a token sequence. If the character sequence is not a valid token sequence, an exception is thrown. If the character sequence is a valid token sequence, the next step is general validation performed by theÂ AXValidatorÂ class.
Once a valid token sequence is obtained, theÂ ExpressionFactoryÂ is used to create a sequence ofExpressionÂ objects from the token sequence. The expression sequence is then evaluated by code in theAXParserÂ class to produce anÂ ExpressionÂ object that represents the input algebraic expression by means of a tree ofÂ ExpressionÂ objects. This expression tree is the intermediate data structure produced by the parser. TheÂ ExpressionContextÂ class serves as the input to the expression tree and is passed down to the leaf expressions for evaluation by means of substitution.
Interpreter suggests modeling the domain with a recursive grammar. Each rule in the grammar is either a 'composite' (a rule that references other rules) or a terminal (a leaf node in a tree structure). Interpreter relies on the recursive traversal of the Composite pattern to interpret the 'sentences' it is asked toÂ process.
The classes and/or objects participating in this pattern are:
AbstractExpressionÂ Â (Expression):declares an interface for executing an operation
TerminalExpressionÂ Â ( ThousandExpression, HundredExpression, TenExpression, OneExpression ):implements an Interpret operation associated with terminal symbols in the grammar.An instance is required for every terminal symbol in the sentence.
NonterminalExpressionÂ Â ( not used ):one such class is required for every rule R ::= R1R2...Rn in the grammar.Maintains instance variables of type AbstractExpression for each of the symbols R1 through Rn.Implements an Interpret operation for nonterminal symbols in the grammar. Interpret typically calls itself recursively on the variables representing R1 through Rn.
ContextÂ Â (Context):contains information that is global to the interpreter
ClientÂ Â (InterpreterApp):builds (or is given) an abstract syntax tree representing a particular sentence in the language that the grammar defines. The abstract syntax tree is assembled from instances of the NonterminalExpression and TerminalExpression classes.I nvokes the Interpret operation.
The Interpreter pattern defines a grammatical representation for a language and an interpreter to interpret the grammar. Musicians are examples of Interpreters. The pitch of a sound and its duration can be represented in musical notation on a staff. This notation provides the language of music. Musicians playing the music from the score are able to reproduce the original pitch and duration of each soundÂ represented.
1.Decide if a "little language" offers a justifiable return onÂ investment.
2.Define a grammar for theÂ language.
3.Map each production in the grammar to aÂ class.
4.Organize the suite of classes into the structure of the CompositeÂ pattern.
5.Define anÂ interpret(Context)Â method in the CompositeÂ hierarchy.
6.TheÂ ContextÂ object encapsulates the current state of the input and output as the former is parsed and the latter is accumulated. It is manipulated by each grammar class as the "interpreting" process transforms the input into theÂ output.
a.Considered in its most general form (i.e. an operation distributed over a class hierarchy based on the Composite pattern), nearly every use of the Composite pattern will also contain the Interpreter pattern. But the Interpreter pattern should be reserved for those cases in which you want to think of this class hierarchy as defining aÂ language.
b.Interpreter can use State to define parsingÂ contexts.
c.The abstract syntax tree of Interpreter is a Composite (therefore Iterator and Visitor are alsoÂ applicable).
d.Terminal symbols within Interpreter's abstract syntax tree can be shared withÂ Flyweight.
e.The pattern doesn't address parsing. When the grammar is very complex, other techniques (such as a parser) are moreÂ appropriate.
8. ADVANTAGES OF THE INTERPRETER PATTERN:
The Interpreter design pattern not only adds overhead, it also gives you some additional possibilities. For example, imagine that the expression contains not only numbers and operators, but also variables. Expression value may vary according to values assigned to variables.
When using a traditional parser, the expression would have to be parsed each time the variables values are changed. With the Interpreter pattern, the situation is much more comfortable. Once the Abstract Syntax Tree is built, it may be reused many times. All you have to do is to provide the interpreter with up-to-date variables values. Remember - current conditions in which the interpreter is working (e.g. variables values) are called aÂ context. Replace the context, keep the syntax tree and spare CPU cycles.
9. USES FOR THE INTERPRETER PATTERN:
1.Specialized database query languages such asÂ SQL.
2.Specialized computer languages which are often used to describe communication protocols.
3.Most general-purpose computer languages actually incorporate several specialized languages.
10. OTHER APPLICATIONS:
By using the Interpreter design pattern to parse RPN expressions, we didn't make a revolution. Take into account, though, that some applications of the Interpreter have made a big and well-deserved career. The Interpreter is being used to evaluate expressions written in highly specialized languages, like SQL (Structured Query Language).
I'm sure we all have encountered such situations in our programming career when expressing operations and dependencies in the programming language of your choice seemed unnatural and required writing similar code many times and spreading it across the source code.