Pythonで実装するInterpreterパターン：文法規則をオブジェクトで表現する構文処理戦略



## 概要

**Interpreter（インタープリター）パターン**は、  
特定の言語や文法（構文規則）に対して、**その構文をオブジェクトとして表現し、評価処理を構造的に実装するデザインパターン**である。

小規模なDSL（ドメイン特化言語）や構文評価エンジンにおいて、  
**構文の追加・拡張が容易で、データとロジックの明快な分離を実現**できる。

---

## 1. なぜInterpreterが必要か？

### ❌ 構文解析・評価処理を1つの関数でベタ書きすると拡張性がない

```python
if expr == "a AND b":
    return context["a"] and context["b"]
```

→ **式が複雑化するほどロジックが破綻していく**

---

### ✅ 各構文をクラスとして分離し、再帰的に評価を実行できる構造にする

```python
expr = And(Variable("a"), Variable("b"))
expr.evaluate(context)
```

→ **式が構文木として構築され、保守・拡張が容易になる**

---

## 2. 基本構造

### ✅ 抽象式（Expression）

```python
class Expression:
    def evaluate(self, context: dict) -> bool:
        raise NotImplementedError
```

---

### ✅ 終端記号（Terminal Expression）

```python
class Variable(Expression):
    def __init__(self, name: str):
        self.name = name

    def evaluate(self, context: dict) -> bool:
        return context[self.name]
```

---

### ✅ 非終端記号（Non-Terminal Expression）

```python
class And(Expression):
    def __init__(self, left: Expression, right: Expression):
        self.left = left
        self.right = right

    def evaluate(self, context: dict) -> bool:
        return self.left.evaluate(context) and self.right.evaluate(context)

class Or(Expression):
    def __init__(self, left: Expression, right: Expression):
        self.left = left
        self.right = right

    def evaluate(self, context: dict) -> bool:
        return self.left.evaluate(context) or self.right.evaluate(context)

class Not(Expression):
    def __init__(self, expr: Expression):
        self.expr = expr

    def evaluate(self, context: dict) -> bool:
        return not self.expr.evaluate(context)
```

---

### ✅ 使用例

```python
# (a AND b) OR NOT c
expr = Or(
    And(Variable("a"), Variable("b")),
    Not(Variable("c"))
)

context = {"a": True, "b": False, "c": False}
result = expr.evaluate(context)
print(f"結果: {result}")
```

出力:
```
結果: True
```

---

## 3. Python的応用：DSLエンジンとしての利用

```python
class Equals(Expression):
    def __init__(self, key: str, value: str):
        self.key = key
        self.value = value

    def evaluate(self, context: dict):
        return context.get(self.key) == self.value

# DSL式: (role == "admin") AND NOT (active == "false")
expr = And(
    Equals("role", "admin"),
    Not(Equals("active", "false"))
)

print(expr.evaluate({"role": "admin", "active": "true"}))  # True
```

→ **条件文をDSLとして安全かつ柔軟に扱える構造を実現可能**

---

## 4. 実務ユースケース

### ✅ ビジネスルールエンジンの実装

→ 条件ルールの構文木化と実行

---

### ✅ 簡易DSL（構成ファイル・クエリ表現）の解釈器

→ 独自構文の評価処理をクラスベースで実装

---

### ✅ パーミッション・フラグの条件表現

→ ユーザー状態に基づく複雑なアクセス制御を柔軟に表現

---

### ✅ 数式エンジン・電卓アプリ

→ 式の構文木を構築し、再帰的に評価

---

## 5. よくある誤用と対策

### ❌ 評価処理をExpressionにべた書きしてしまう

→ ✅ **各式に評価責務を閉じ込め、再帰構造を守る**

---

### ❌ クラス数が増えすぎてメンテナンス性が悪化

→ ✅ **簡易DSLにはパーサやASTとの併用も検討する**

---

### ❌ パフォーマンス重視のシナリオに不向きな適用

→ ✅ **Interpreterは柔軟性・可読性優先。高速化が求められる場合はJITやパーサ生成へ移行**

---

## 結語

**Interpreterパターンとは、“構文規則をオブジェクトに落とし込み、評価を再帰的に解釈する設計”である。**

- 文法要素を構造化して表現し、**柔軟かつ安全にDSLを実行可能**  
- 複雑な式も再帰的評価で簡潔に記述でき、**高い拡張性と可読性を実現**  
- Pythonではクラスの再帰構造やラムダとの組み合わせで、**簡易インタプリタも高速に実装可能**

**Pythonicとは、“文法をロジックとして操作すること”。  
Interpreterパターンはその構文の知性を、設計の評価戦略として取り込む技法である。**