Interpreter¶
Let's suppose:
- in a terminal, in a
bash
shell, we execute the commandls -ltr | grep -i sda
- in the
python
console, we execute the command3 ** 3 + 1
- in the
jshell
console, execute the commandMath.abs(Math.pow(2, 3))
.
Each of the above examples takes some information as input, usually in the form of a string. NThen, these signs are interpreted in a certain agreed way (ie depending on the contract and the capabilities of the technology) and give a specific effect. This behavior describes the use of the interpreter
pattern.
Design¶
In order to use the pattern, we need the following elements:
- common interface that has a method to interpret a certain object. We often call this object context
- implementation of interfaces that can interpret the context in different ways
The pattern does not contain many elements and is as complicated as the interpretation of the context is.
Example¶
The example shows a simple interpreter of mathematical operations. It is based on the ʻInterpreter` interface and its implementation:
PythonStyleWithoutOrderMathOperationsInterpreter
- has the ability to perform addition, subtraction, multiplication, division (without remainder) and exponentiation (Python style, i.e. using**
for this purpose)
class MathOperationAplier:
def apply(self, math_operation, first, second):
if math_operation == '+':
return first + second
elif math_operation == '-':
return first - second
elif math_operation == '*':
return first * second
elif math_operation == '/':
return first / second
elif math_operation == '**':
return first ** second
else:
raise ArithmeticError()
class Interpreter:
def interpret(self, context):
pass
class PythonStyleWithoutOrderMathOperationsInterpreter(Interpreter):
def __init__(self, math_operation_applier):
self._math_operation_applier = math_operation_applier
def interpret(self, context):
split_data = context.strip().split()
if len(split_data) % 2 == 0:
raise ArithmeticError()
value = float(split_data[0])
for i in range(1, len(split_data), 2):
value = self._math_operation_applier.apply(split_data[i], value, float(split_data[i+1]))
return value
def main():
math_operation_applier = MathOperationAplier()
interpreter = PythonStyleWithoutOrderMathOperationsInterpreter(math_operation_applier)
calculation = input('Choose a math operation: ')
value = interpreter.interpret(calculation)
print(value)
if __name__ == '__main__':
main()
The above code for the input arguments: "2 + 3 * 2"
will return the value 10.0
.