YouTip LogoYouTip

Python Interpreter

Interpreter Pattern is a behavioral design pattern that defines the grammar of a language and builds an interpreter to interpret sentences in that language. Simply put, it acts like a small compiler that can parse and execute expressions following specific syntax rules.\\\\n\\\\n### Core Idea\\\\n\\\\nImagine a calculator scenario: when you input an expression like `"2 + 3 * 4"`, the calculator needs to understand the meaning of this string and calculate it according to mathematical operation rules. The Interpreter Pattern is the design solution that implements this "understanding" and "execution" process.\\\\n\\\\n### Applicable Scenarios\\\\n\\\\nThe Interpreter Pattern is particularly suitable for the following situations:\\\\n\\\\n* When there is a need to interpret and execute a language or expression\\\\n* The grammar is relatively simple and not overly complex\\\\n* Execution efficiency is not a key consideration\\\\n* There is a need to frequently extend the grammar rules of the language\\\\n\\\\n* * *\\\\n\\\\n## Pattern Structure\\\\n\\\\nLet's understand the core components of the Interpreter Pattern through a class diagram:\\\\n\\\\n!(#)\\\\n\\\\n### Component Description\\\\n\\\\n**AbstractExpression**\\\\n\\\\n* Defines the interface for the interpret operation\\\\n* Typically contains an `interpret()` method\\\\n\\\\n**TerminalExpression**\\\\n\\\\n* Implements the interpret operation associated with terminal symbols in the grammar\\\\n* Cannot be broken down into smaller expressions\\\\n\\\\n**NonterminalExpression**\\\\n\\\\n* Implements the interpret operation associated with non-terminal symbols in the grammar\\\\n* Typically contains references to other expressions\\\\n\\\\n**Context**\\\\n\\\\n* Contains global information needed by the interpreter\\\\n* Stores input and output results\\\\n\\\\n* * *\\\\n\\\\n## Basic Syntax and Implementation\\\\n\\\\n### Abstract Expression Class\\\\n\\\\n## Instance\\\\n\\\\nfrom abc import ABC, abstractmethod\\\\n\\\\nclass Expression(ABC):\\\\n\\\\n"""Abstract Expression class, defines the interpret interface"""\\\\n\\\\n@abstractmethod\\\\n\\\\ndef interpret(self, context):\\\\n\\\\n"""Interpret method, implemented by concrete subclasses"""\\\\n\\\\npass\\\\n\\\\n### Terminal Expression\\\\n\\\\n## Instance\\\\n\\\\nclass NumberExpression(Expression):\\\\n\\\\n"""Number Expression - Terminal Expression"""\\\\n\\\\ndef __init__ (self, number):\\\\n\\\\nself.number= number\\\\n\\\\ndef interpret(self, context):\\\\n\\\\n# Directly return the numeric value\\\\n\\\\nreturn self.number\\\\n\\\\ndef __str__ (self):\\\\n\\\\nreturn f"Number({self.number})"\\\\n\\\\n### Nonterminal Expression\\\\n\\\\n## Instance\\\\n\\\\nclass AddExpression(Expression):\\\\n\\\\n"""Addition Expression - Non-terminal Expression"""\\\\n\\\\ndef __init__ (self, left, right):\\\\n\\\\nself.left= left # Left Expression\\\\n\\\\nself.right= right # Right Expression\\\\n\\\\ndef interpret(self, context):\\\\n\\\\n# respectivelyexplainleftRight Expression,thenadd together\\\\n\\\\nreturn self.left.interpret(context) + self.right.interpret(context)\\\\n\\\\ndef __str__ (self):\\\\n\\\\nreturn f"({self.left} + {self.right})"\\\\n\\\\nclass SubtractExpression(Expression):\\\\n\\\\n"""Subtraction Expression - Non-terminal Expression"""\\\\n\\\\ndef __init__ (self, left, right):\\\\n\\\\nself.left= left\\\\n\\\\nself.right= right\\\\n\\\\ndef interpret(self, context):\\\\n\\\\nreturn self.left.interpret(context) - self.right.interpret(context)\\\\n\\\\ndef __str__ (self):\\\\n\\\\nreturn f"({self.left} - {self.right})"\\\\n\\\\nclass MultiplyExpression(Expression):\\\\n\\\\n"""Multiplication Expression - Non-terminal Expression"""\\\\n\\\\ndef __init__ (self, left, right):\\\\n\\\\nself.left= left\\\\n\\\\nself.right= right\\\\n\\\\ndef interpret(self, context):\\\\n\\\\nreturn self.left.interpret(context) * self.right.interpret(context)\\\\n\\\\ndef __str__ (self):\\\\n\\\\nreturn f"({self.left} * {self.right})"\\\\n\\\\n* * *\\\\n\\\\n## Complete Example: Simple Calculator\\\\n\\\\nLet's implement a complete simple calculator to interpret mathematical expressions:\\\\n\\\\n## Instance\\\\n\\\\nclass CalculatorContext:\\\\n\\\\n"""Calculator context, stores calculation-related information"""\\\\n\\\\ndef __init__ (self):\\\\n\\\\nself.variables={}# Store variable values\\\\n\\\\ndef set_variable(self, name, value):\\\\n\\\\n"""Set variable value"""\\\\n\\\\nself.variables= value\\\\n\\\\ndef get_variable(self, name):\\\\n\\\\n"""Get variable value"""\\\\n\\\\nreturn self.variables.get(name,0)\\\\n\\\\nclass VariableExpression(Expression):\\\\n\\\\n"""Variable Expression - Terminal Expression"""\\\\n\\\\ndef __init__ (self, name):\\\\n\\\\nself.name= name\\\\n\\\\ndef interpret(self, context):\\\\n\\\\n# Get variable value from context\\\\n\\\\nreturn context.get_variable(self.name)\\\\n\\\\ndef __str__ (self):\\\\n\\\\nreturn self.name\\\\n\\\\nclass Calculator:\\\\n\\\\n"""Calculator class - constructs and interprets Expressions"""\\\\n\\\\n@staticmethod\\\\n\\\\ndef parse_expression(expression_str, context):\\\\n\\\\n"""\\\\n\\\\n Parse string Expression into an Expression tree\\\\n\\\\n Simplified here; actual applications may require more complex parsers\\\\n\\\\n """\\\\n\\\\n# Simple Expression parsing (for actual projects, dedicated parsing libraries are recommended)\\\\n\\\\n tokens = expression_str.replace('(',' ( ').replace(')',' ) ').split()\\\\n\\\\nreturn Calculator._parse_tokens(tokens)\\\\n\\\\n@staticmethod\\\\n\\\\ndef _parse_tokens(tokens):\\\\n\\\\n"""Recursively parse token list"""\\\\n\\\\nif not tokens:\\\\n\\\\nreturn None\\\\n\\\\ntoken= tokens.pop(0)\\\\n\\\\nif token=='(':\\\\n\\\\n# Start parsing composite Expression\\\\n\\\\n left = Calculator._parse_tokens(tokens)\\\\n\\\\noperator= tokens.pop(0)\\\\n\\\\n right = Calculator._parse_tokens(tokens)\\\\n\\\\n tokens.pop(0)# Remove ')'\\\\n\\\\nif operator=='+':\\\\n\\\\nreturn AddExpression(left, right)\\\\n\\\\nelif operator=='-':\\\\n\\\\nreturn SubtractExpression(left, right)\\\\n\\\\nelif operator=='*':\\\\n\\\\nreturn MultiplyExpression(left, right)\\\\n\\\\nelse:\\\\n\\\\n# Parse basic Expression (number or variable)\\\\n\\\\nif token.isdigit()or(token=='-'and token[1:].isdigit()):\\\\n\\\\nreturn NumberExpression(int(token))\\\\n\\\\nelse:\\\\n\\\\nreturn VariableExpression(token)\\\\n\\\\n# Usage example\\\\n\\\\ndef main():\\\\n\\\\n# Create context\\\\n\\\\n context = CalculatorContext()\\\\n\\\\n context.set_variable('x',10)\\\\n\\\\n context.set_variable('y',5)\\\\n\\\\n# Manually build Expression: (x + 3) * (y - 2)\\\\n\\\\n expression = MultiplyExpression(\\\\n\\\\n AddExpression(VariableExpression('x'), NumberExpression(3)),\\\\n\\\\n SubtractExpression(VariableExpression('y'), NumberExpression(2))\\\\n\\\\n)\\\\n\\\\nprint(f"Expression: {expression}")\\\\n\\\\n result = expression.interpret(context)\\\\n\\\\nprint(f"Result: {result}")# Output: (10 + 3) * (5 - 2) = 39\\\\n\\\\n# Use the parser\\\\n\\\\n simple_expr = AddExpression(NumberExpression(5), NumberExpression(3))\\\\n\\\\nprint(f"Simple Expression: {simple_expr} = {simple_expr.interpret(context)}")\\\\n\\\\nif __name__ =="__main__":\\\\n\\\\n main()\\\\n\\\\n* * *\\\\n\\\\n## Advanced Application: SQL WHERE Condition Interpreter\\\\n\\\\nLet's look at a more practical example - implementing a simplified SQL WHERE condition interpreter:\\\\n\\\\n## Instance\\\\n\\\\nclass SQLContext:\\\\n\\\\n"""SQL Query context"""\\\\n\\\\ndef __init__ (self, record):\\\\n\\\\nself.record= record # Data record\\\\n\\\\ndef get_value(self, field):\\\\n\\\\n"""Get field value"""\\\\n\\\\nreturn self.record.get(field)\\\\n\\\\nclass FieldExpression(Expression):\\\\n\\\\n"""Field Expression"""\\\\n\\\\ndef __init__ (self, field_name):\\\\n\\\\nself.field_name= field_name\\\\n\\\\ndef interpret(self, context):\\\\n\\\\nreturn context.get_value(self.field_name)\\\\n\\\\nclass ConstantExpression(Expression):\\\\n\\\\n"""Constant Expression"""\\\\n\\\\ndef __init__ (self, value):\\\\n\\\\nself.value= value\\\\n\\\\ndef interpret(self, context):\\\\n\\\\nreturn self.value\\\\n\\\\nclass EqualsExpression(Expression):\\\\n\\\\n"""Equality comparison Expression"""\\\\n\\\\ndef __init__ (self, left, right):\\\\n\\\\nself.left= left\\\\n\\\\nself.right= right\\\\n\\\\ndef interpret(self, context):\\\\n\\\\nreturn self.left.interpret(context)==self.right.interpret(context)\\\\n\\\\nclass AndExpression(Expression):\\\\n\\\\n"""AND Expression"""\\\\n\\\\ndef __init__ (self, left, right):\\\\n\\\\nself.left= left\\\\n\\\\nself.right= right\\\\n\\\\ndef interpret(self, context):\\\\n\\\\nreturn self.left.interpret(context)and self.right.interpret(context)\\\\n\\\\nclass OrExpression(Expression):\\\\n\\\\n"""OR Expression"""\\\\n\\\\ndef __init__ (self, left, right):\\\\n\\\\nself.left= left\\\\n\\\\nself.right= right\\\\n\\\\ndef interpret(self, context):\\\\n\\\\nreturn self.left.interpret(context)or self.right.interpret(context)\\\\n\\\\n# Usage example:Simulate SQL WHERE condition filtering\\\\n\\\\ndef sql_demo():\\\\n\\\\n# Mock Data record\\\\n\\\\n records =[\\\\n\\\\n{'name': 'Alice','age': 25,'department': 'Engineering'},\\\\n\\\\n{'name': 'Bob','age': 30,'department': 'Sales'},\\\\n\\\\n{'name': 'Charlie','age': 28,'department': 'Engineering'},\\\\n\\\\n{'name': 'Diana','age': 35,'department': 'Marketing'}\\\\n\\\\n]\\\\n\\\\n# Build WHERE condition: (department = 'Engineering') AND (age > 26)\\\\n\\\\nclass GreaterThanExpression(Expression):\\\\n\\\\ndef __init__ (self, left, right):\\\\n\\\\nself.left= left\\\\n\\\\nself.right= right\\\\n\\\\ndef interpret(self, context):\\\\n\\\\nreturn self.left.interpret(context)>self.right.interpret(context)\\\\n\\\\n# Construct Expression tree\\\\n\\\\n condition = AndExpression(\\\\n\\\\n EqualsExpression(FieldExpression('department'), ConstantExpression('Engineering')),\\\\n\\\\n GreaterThanExpression(FieldExpression('age'), ConstantExpression(26))\\\\n\\\\n)\\\\n\\\\nprint("Records matching conditions:")\\\\n\\\\nfor record in records:\\\\n\\\\n context = SQLContext(record)\\\\n\\\\nif condition.interpret(context):\\\\n\\\\nprint(f"- {record['name']}, {record['age']}Age, {record['department']}")\\\\n\\\\nif __name__ =="__main__":\\\\n\\\\n sql_demo()\\\\n\\\\n* * *\\\\n\\\\n## Pattern Pros and Cons\\\\n\\\\n### Pros\\\\n\\\\n1. **Easy to extend grammar**: You can extend grammar rules simply by adding new expression classes\\\\n2. **Easy to implement**: Each expression class is relatively simple, making it easy to implement and maintain\\\\n3. **High flexibility**: The interpretation method can be dynamically changed\\\\n4. **Conforms to the Open-Closed Principle**: Open for extension, closed for modification\\\\n\\\\n### Cons\\\\n\\\\n1. **Performance issues**: The Interpreter Pattern is usually less efficient, especially for complex grammars\\\\n2. **Increased complexity**: For complex grammars, it generates a large number of classes, increasing system complexity\\\\n3. **Difficult to debug**: Debugging complex expression trees can be quite difficult\\\\n\\\\n* * *\\\\n\\\\n## Best Practices and Considerations\\\\n\\\\n### When to Use\\\\n\\\\n* When the grammar is relatively simple and stable\\\\n* When execution efficiency
← Ai Agent TutorialPython Mediator β†’