コンピュータプログラミングにおいて、インタープリタパターンは言語内の文を評価する方法を指定する設計パターンです。基本的な考え方は、特殊なコンピュータ言語内の各記号(終端記号または非終端記号)ごとにクラスを用意することです。言語内の文の構文木は複合パターンのインスタンスであり、クライアントのために文を評価(解釈)するために使用されます。[1] :243 複合パターンも参照してください。
概要
インタプリタ [2]デザインパターン は、 柔軟で再利用可能なオブジェクト指向ソフトウェア、つまり実装、変更、テスト、再利用が容易なオブジェクトを設計するために、繰り返し発生する設計上の問題を解決する方法を記述した、よく知られている23のGoFデザインパターンの1つです。
インタープリター設計パターンはどのような問題を解決できますか?
出典: [3]
- 単純な言語の文法を定義する必要がある
- その言語の文章を解釈できるようにするためです。
問題が頻繁に発生する場合、その問題を簡単な言語 (ドメイン固有言語) の文として表現し、インタープリタがその文を解釈して問題を解決できるようにすることが考えられます。
たとえば、多くの異なるまたは複雑な検索式を指定する必要がある場合、それらをクラスに直接実装 (ハードワイヤリング) すると、クラスが特定の式にコミットされ、クラスから独立して (クラスを変更することなく) 新しい式を指定したり、既存の式を変更したりすることができなくなるため、柔軟性がなくなります。
インタープリタ設計パターンはどのようなソリューションを記述しますか?
Expressionクラス階層を定義し、操作を実装することで、単純な言語の文法を定義しますinterpret()。Expressionインスタンスで構成された抽象構文木 (AST) によって言語内の文を表します。interpret()AST を呼び出して文を解釈します。
式オブジェクトは、
抽象構文木と呼ばれる複合/ツリー構造に再帰的に構成されます(複合パターンを参照)。
インタープリタ パターンでは、抽象構文木の構築方法は説明されていません。これは、クライアントによって手動で行うことも、パーサーによって自動的に行うこともできます。
下記の UML クラス図とオブジェクト図も参照してください。
用途
- SQLなどの特殊なデータベースクエリ言語。
- 通信プロトコルを記述するためによく使用される特殊なコンピュータ言語。
- ほとんどの汎用コンピュータ言語は、実際にはいくつかの専門言語を組み込んでいます[引用が必要]。
構造
UML クラスとオブジェクト図

上記のUML クラス図では、クラスは式を解釈するための
Client共通インターフェースを参照します。
クラスには子がなく、式を直接解釈します。
クラスは子式のコンテナ ( ) を維持し、解釈要求をこれらのコンテナに転送します。
AbstractExpressioninterpret(context)TerminalExpressionNonTerminalExpressionexpressionsexpressions
オブジェクトコラボレーション図は、実行時の相互作用を示しています。Clientオブジェクトは、抽象構文木に解釈要求を送信します。要求は、ツリー構造の下のすべてのオブジェクトに転送されます (実行されます)。
オブジェクトNonTerminalExpression( ntExpr1,ntExpr2) は、要求を子式に転送します。
オブジェクトTerminalExpression( tExpr1,tExpr2,…) は、解釈を直接実行します。
UML クラス図
例
この C++11 実装は、この本の C++98 以前のサンプル コードに基づいています。
#include <iostream> #include <map> #include <cstring>
クラスContext ;
クラスBooleanExp { public : BooleanExp () = default ; virtual ~ BooleanExp () = default ; virtual bool assess ( Context & ) = 0 ; virtual BooleanExp * replace ( const char * , BooleanExp & ) = 0 ; virtual BooleanExp * copy () const = 0 ; };
クラスVariableExp ;
クラスContext { public : Context () : m () {} bool lookup ( const VariableExp * key ) { return m . at ( key ); } void assignment ( VariableExp * key , bool value ) { m [ key ] = value ; } private : std :: map < const VariableExp * , bool > m ; };
class VariableExp : public BooleanExp { public : VariableExp ( const char * name_ ) : name ( nullptr ) { name = strdup ( name_ ); } virtual ~ VariableExp () = default ; virtual bool assess ( Context & aContext ) { return aContext.lookup ( this ); } virtual BooleanExp * replace ( const char * name_ , BooleanExp & exp ) { if ( 0 == strcmp ( name_ , name )) { return exp.copy ( ); } else { return new VariableExp ( name ) ; } } virtual BooleanExp * copy () const { return new VariableExp ( name ); } VariableExp ( const VariableExp & ) = delete ; // 3つのルールVariableExp & operator = ( const VariableExp & ) = delete ; private : char * name ; } ;
クラスAndExp : public BooleanExp { public : AndExp ( BooleanExp * op1 , BooleanExp * op2 ) : operand1 ( nullptr ), operand2 ( nullptr ) { operand1 = op1 ; operand2 = op2 ; } virtual ~ AndExp () = default ; virtual bool assess ( Context & aContext ) { return operand1 -> assess ( aContext ) && operand2 -> assess ( aContext ); } virtual BooleanExp * replace ( const char * name_ , BooleanExp & exp ) { return new AndExp ( operand1 -> replace ( name_ , exp ), operand2 -> replace ( name_ , exp ) ); } virtual BooleanExp * copy () const { return new AndExp ( operand1 -> copy (), operand2 -> copy () ); } AndExp ( const AndExp & ) = delete ; // 3 つのルールAndExp & operator = ( const AndExp & ) = delete ; private : BooleanExp * operand1 ; BooleanExp * operand2 ; };
int main () { BooleanExp *式;コンテキストcontext ; VariableExp * x = new VariableExp ( "X" ); VariableExp * y = new VariableExp ( "Y" );式= new AndExp ( x , y );
context.assign ( x , false ) ; context.assign ( y , true ); bool result = expression - > evaluate ( context ) ; std :: cout << result << ' \n' ;
context.assign ( x , true ); context.assign ( y , true ); result = expression - > evaluate ( context ) ; std :: cout << result << ' \n ' ; }
プログラムの出力は次のとおりです。
0
1
参照
参考文献
- ^ ガンマ、エリック、ヘルム、リチャード、ジョンソン、ラルフ、ブリサイドス、ジョン (1994)。デザインパターン: 再利用可能なオブジェクト指向ソフトウェアの要素。Addison-Wesley。ISBN 0-201-63361-2。
- ^ Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides (1994)。デザインパターン: 再利用可能なオブジェクト指向ソフトウェアの要素。Addison Wesley。pp. 243ff。ISBN 0-201-63361-2。
{{cite book}}: CS1 maint: multiple names: authors list (link) - ^ 「インタープリタ設計パターン - 問題、解決法、適用性」w3sDesign.com . 2017 年 8 月 12 日閲覧。
- ^ 「インタープリタ設計パターン - 構造とコラボレーション」w3sDesign.com 。 2017 年 8 月 12 日閲覧。
