定義:言語が与えられ、その文法の表現を定義し、表現を使用して言語の文を解釈する通訳を定義します。
タイプ:行動パターン
クラス図:
インタープリターモードは比較的まれに使用されないモードであり、このモードをこれまで使用したことがありません。インタープリターモードを見てみましょう。
インタープリターモードの構造
抽象通訳者:すべての具体的な表現を実装する抽象インターフェイス(または要約クラス)を宣言します。インターフェイスは、主に説明操作と呼ばれる解釈()メソッドです。特定の解釈タスクは、さまざまな実装クラスによって完了し、特定のインタープリターはターミネーターインタープリターターミナルエクスポンションと非末端インタープリターの非末端発現によって完了します。
ターミネーター式:文法の要素に関連する解釈操作を実装します。通常、通訳パターンにはターミネーター式は1つだけですが、異なるターミネーターに対応する複数のインスタンスがあります。ターミネーターの半分は、文法の操作ユニットです。たとえば、R1とR2がターミネーターである単純な式R = R1+R2があり、R1とR2を解析する対応する通訳者がターミネーターです。
非末端表現:文法の各ルールは、非末端式に対応します。非末端式は、一般に、文法のオペレーターまたはその他のキーワードです。たとえば、式r = r1 + r2では、 +は非末端特性であり、解析 +の通訳は非末端特性です。非末端式は、論理の複雑さに応じて増加し、原則として各文法ルールは非末端式に対応します。
環境の役割:この役割のタスクは、一般に、r = r1+r2などの文法内の各ターミネーターに対応する特定の値を保存するために使用されます。 100をR1に、200をR2に割り当てます。この情報は、環境の役割に保存する必要があります。多くの場合、MAPを使用して、環境の役割で十分に機能します。
例
追加、減算、乗算、除算の例を示しましょう。実装のアイデアは、「Java and Pattern」の例に由来しています。各役割の機能は、上記の仕様に従って実装されます。
//コンテキスト(環境)の役割、ハッシュマップを使用して、変数に対応する数値を保存します。 public void addvalue(変数x、int y){integer yi = new Integer(y); ValueMap.put(x、yi); } public int lookupValue(変数x){int i =((integer)valuemap.get(x))。intvalue();私を返します。 }} //抽象表現の役割インターフェイスを使用して、抽象クラス式{public abstract int rittent(context con); } //ターミネーター式ロールクラス定数式式{private int i; public constant(int i){this.i = i; } public int relutte(Context Con){return i; }} class変数は式{public int relutte(context con){//解釈メソッドを呼び出す変数オブジェクトです。 }} //非ターミネーター式ロールクラスの追加式式{プライベート式の左、右;パブリックアドレス(左の式、式右){this.left = left; this.right = right; } public int relutte(context con){return left.interpret(con) + right.interpret(con); }} class Subtractは式{プライベート式の左、右; public subtract(式の左、式右){this.left = left; this.right = right; } public int relutte(context con){return left.interpret(con) - right.interpret(con); }} class Multiply extendess式{プライベート式の左、右; public Multiply(expression Left、Expression Right){this.left = left; this.right = right; } public int relutte(context con){return left.interpret(con) * right.interpret(con); }} class divisionは式{プライベート式の左、右;パブリック部門(左、式右式){this.left = left; this.right = right; } public int relutte(context con){try {return left.interpret(con) / right.interpret(con); } catch(arithmeticexception ae){system.out.println( "divorc is 0!"); return -11111; }}} //プログラムをテストし、(a*b)/(a-b+2)public class test {private static expression ex;プライベート静的コンテキストCON; public static void main(string [] args){con = new Context(); //変数と定数を設定します変数a = new変数();変数b = new変数();定数c = new定数(2); //変数con.addvalue(a、5)を割り当てます。 con.addvalue(b、7); //操作文の構造を分析し、Ex = new Multiply(a、b)、new add(new Subtract(a、b)、c))を構築します。 System.out.println( "操作結果は次のとおりです。 }}インタープリターモードの利点と短所
インタープリターは、シンプルな構文分析ツールです。その最も重要な利点は、その拡張性です。構文ルールを変更するには、対応する非末端文字を変更する必要があります。構文を拡張する場合、非末端文字を追加するだけです。
ただし、通訳パターンによりクラスが拡大され、各構文は非末端式を生成する必要があります。構文ルールが比較的複雑な場合、多数のクラスファイルが生成される可能性があり、メンテナンスに多くの問題が発生します。同時に、再帰コール方法が採用されるため、各非末端発現はそれ自体に関連する式のみを気にします。各式は最終結果を知る必要があり、再帰的でなければなりません。オブジェクト指向の言語であろうとプロセス指向の言語であろうと、再帰は推奨されない方法です。多くのループと再帰の使用により、効率は無視できない問題です。特に、解析の複雑で長い構文を解釈するために使用される場合、効率は耐えられません。
インタープリターモードに適用されるシナリオ
次の場合には、インタープリターモードを使用できます。
SQLステートメントなど、単純な構文ルールがあります。 SQLステートメントに基づいてRM変換を実行する必要がある場合は、インタープリターパターンを使用してステートメントを解釈できます。
追加、減算、乗算、分割の4つの操作など、いくつかの反復的な問題ですが、数式は毎回異なります。 A+BC*D、時には*B+CDなどである場合があります。式は絶えず変化していますが、それらはすべて、加算、減算、乗算、および分割の4つの非末端文字によって接続されています。この時点で、インタープリターモードを使用できます。
注意すべきこと
インタープリターモードは、維持するには面倒すぎるため、実際にはまれに使用されないモードです。多くの非ターミナル通訳者が事前に文法のルールに精通していない場合、または文法が特に簡単である場合、その論理を理解することは困難であると想像してください。インタープリターモードは、効率、パフォーマンス、メンテナンスなどの問題を引き起こす可能性があるため、実際のシステム開発ではめったに使用されません。