2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで実装するInterpreterパターン:ドメイン言語の構文解釈を実現する構造

Posted at

概要

Interpreter(インタプリタ)パターンは、
ある言語や表現を定義し、その文法構造に基づいて文を解釈・実行するためのデザインパターンである。

主に小規模な**ドメイン固有言語(DSL)**や、
表現の解析・評価・翻訳処理などに用いられ、
構文木を構築し、再帰的に評価することが特徴である。


1. なぜInterpreterが必要か?

❌ DSLや条件式を文字列のままif文で処理

if expression == "A AND B":
    ...

→ 新しい構文を追加するたびにロジックが肥大化し、拡張性が破綻する


✅ 文法と意味論をクラスで明確に構造化し、評価可能にする

expr = And(Variable("A"), Variable("B"))
expr.interpret(context)

構文解析・意味解釈の責務を分離し、再利用と拡張が容易に


2. 基本構造

✅ AbstractExpression(共通インターフェース)

class Expression:
    def interpret(self, context):
        raise NotImplementedError

✅ TerminalExpression(終端記号)

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

    def interpret(self, context):
        return context.get(self.name, False)

✅ NonTerminalExpression(構文ルール)

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

    def interpret(self, context):
        return self.left.interpret(context) and self.right.interpret(context)

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

    def interpret(self, context):
        return self.left.interpret(context) or self.right.interpret(context)

✅ Context(評価用の環境)

context = {
    "A": True,
    "B": False
}

✅ 使用例

expr = And(Variable("A"), Variable("B"))
print(expr.interpret(context))  # → False

expr2 = Or(Variable("A"), Variable("B"))
print(expr2.interpret(context))  # → True

3. Python的応用:構文木の文字列→構造変換(簡易パーサ)

def parse(tokens):
    if len(tokens) == 1:
        return Variable(tokens[0])
    else:
        left = Variable(tokens[0])
        op = tokens[1]
        right = Variable(tokens[2])
        if op == "AND":
            return And(left, right)
        elif op == "OR":
            return Or(left, right)
tokens = "A AND B".split()
expr = parse(tokens)
print(expr.interpret({"A": True, "B": True}))  # True

簡易構文解析器としての活用が可能


4. 実務ユースケース

✅ 独自クエリ言語の設計と評価

→ 例: "name == 'Alice' AND age > 30" のような条件式DSLの処理


✅ ルールエンジンの構文解釈

→ ビジネスルールや制御フローを構文木として定義・評価


✅ 数式エンジン・式の評価機能

→ 数学式・論理式の動的な解釈と再利用


✅ マクロ・テンプレート言語の内部処理

{% if %}{% for %} などの制御構造の内部解釈


5. よくある誤用と対策

❌ 複雑な言語構文に無理してInterpreterを適用

→ ✅ Interpreterは小規模なDSLや制限付き文法に適する。複雑な文法にはParser Generatorを使用


❌ Expressionクラスが状態を持ちすぎる

→ ✅ Expressionは構文と評価の責務のみに留める


❌ Contextの設計が曖昧

→ ✅ Contextはシンプルなキー・バリューマップまたは環境クラスで分離する


結語

Interpreterパターンとは、“文をクラスで表現し、評価可能な構造として解釈する構文的設計”である。

  • 言語的な記述(DSL)を、クラス階層と構文木で明示的に構造化
  • 評価処理をオブジェクト化することで、ルールの再利用・動的生成・拡張が可能に
  • Pythonではシンプルな構文DSLや条件式の評価ロジックを、直感的に構築できる構文設計が可能

Pythonicとは、“コードがそのまま表現になり、意味を持つ”こと。
Interpreterパターンはその設計的な言語化を、構文という形で具現化する知的技法である。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?