-
Notifications
You must be signed in to change notification settings - Fork 0
Interpreter
Roberto Fronteddu edited this page Jan 16, 2023
·
1 revision
The Interpreter is a Behavioral Design Pattern. The interpreter allows us to represent the rules of language or grammar in a data structure and then interpret sentences in t that language.
- We want to process a simple "language" with rules or grammar.
- Abstract expression: Interface that forms the base for expressions.
- TerminalExpresion: Leaf node, implements interpret operation
- NonTerminalExpression: Contains other expressions, when we call interpret here, it's going to call interpret in all its children.
- Context: Object that holds information needed by the interpreter.
- Study the rules of the language for which we want to build an interpreter
- Define abstract class or interface to represent an expression and define a method in it that interprets the expression.
- EWach rule in the class becomes an expression. Expressions that do not need other expressions to interpret become terminal expressions.
- Create non-terminal expression classes which contain other expressions. They will in turn call interpret() on their children as well as perform interpretation of their own if needed.
- Building the abstract syntax tree using these classes can be done by the client itself or we can create a separate class to do it.
- The client will then use this tree to interpret a sentence
- A context is passed to the interpreter. It typically will have the sentence to be interpreted and optionally may be used by the interpreter to store any values that expressions need to modify or populate.
- Each class in this pattern represents a rule in the language. Classes also provide a method to interpret an expression.
- This pattern doesn't tell how to do the actual parse and build the syntax tree.
- Context objects can be used to store and access the state of the interpreter.
- You can use the visitor pattern to interpret instead of adding methods in the expression classes. If you do this you can place each operation in a separate class.
- You can use the flyweight pattern for terminal expression since they can often be reused.
- Represents language rules or grammar as an object structure.
- Has access to properties it needs to do the interpretation
- Represents operations to be performed on an object structure.
- We need an observable and observer functionality to gain access to the properties.
- Class per rule can quickly result in a large number of classes, even for moderately complex grammar -> Not suitable for languages with complex grammar rules
- Very specific to interpreting a language.
- java.util.regex.Pattern. A Pattern instance is created with an internal abstract syntax tree, representing the grammar rules when compile is called. We can then check a sentence against this grammar using the Matcher class.
- javax.el.Expression: Classing supporting the Unified Expression Language (EL), see Expression, ExpressionFactory, ELResolver.