詳細なデザインパターンの解釈モード(通訳)とコード例

まず、モードの定義と特性を説明

  定義された通訳(通訳)モード:言語オブジェクトの定義、および言語の文法の定義を分析するため、文の言語を解釈するパーサを再設計しました。言い換えれば、コンパイル言語は、アプリケーションの例を分析します。この発現文法モデルは、インターフェースプロセス、インターフェースコンテキストの特定の説明を実装します。

  文法や文の概念は同じ、「文法」を記述するために同じコンパイラ理論的には、ここで言及した言語の文法規則を意味し、「文は、」言語要素の焦点です。例えば、「私は中国人だ」一つの文章で、多くの中国の文章があり、あなたは視覚言語で文章を記述するための構文木を使用することができます。

第二に、長所と短所モードを説明

  通訳パターンは、モデルクラス、以下の主要な利点のタイプです。

  • グッドスケーラビリティ。インタプリタモードでクラスを使用することは、言語の文法規則を表現と文法は、継承メカニズムによって変更または拡張することができます。
  • 実装が容易。構文木で表現ノード内の各クラスには、その文法を達成することは比較的容易である、似ています。

  モードの主な欠点は、以下に説明します。

  • 効率を低下させます。一般的サイクルと再帰呼び出しの数が多い、より複雑な文章を説明する際に、その速度は非常に遅く、コードあまりにも面倒をデバッグするプロセスで使用されるパターンインタプリタ。
  • クラスは腫れが発生します。各ルールインタプリタモードでは、文法規則が多く含まれている場合、クラスの数は、システムの管理と保守困難で、その結果、大幅に増加し、少なくともクラスを定義します。
  • 該当シーンは比較的小さいです。ソフトウェア開発では、アプリケーションの例は、このモードはめったにに使用されていないので、言語の文法は、非常に小さい定義する必要があります。

第三に、インタプリタモードを達成するために

  一般的に、コンパイルまたはその構造および実装を習得するために、簡単な言語の例を分析に使用されるインタプリタのパターンは、我々は最初の「文法、文章構文木」と他の関連する概念の翻訳原理を理解する必要があります。

  1、文法

  文法の正式なルールは、言語の文法構造を記述するために使用されます。、あまりにも、何が最後の基準がより厳しいものの、何の基準は、例えば、一部の人々は、ガイドラインは完全な愛「の相互魅力、感情的な特異性、いずれの当事者も、経験豊富な愛」だと思うんルールませんが、何か、ルールは、言語がありますそれは機械語や独自の文法規則を持つ自然言語であるかどうか。たとえば、「文」の文法の中国は、以下の通りです。

<文> :: = <件名> <述語> <オブジェクト>
<件名> :: = <代名詞> | <名詞>
<述語> :: = <動詞>
<オブジェクト> :: = <代名詞> | <名詞>
<代名詞>あなた| I |彼
<名詞> 7人の学生Iシャオ夏I英語
<動詞> :: =はい|学習

  注:記号「:: =」とは、「<」と「>」非終端記号同封して、手段「として定義されている」、サラウンドにはターミネーターではありません。

  2、文

  文は、言語の基本単位で、言語から導出することができるターミネーターから構成要素の集合である「文法」。例えば、上記の文法は、それが文であるので「私は大学生である」、導入することができます。

  3、構文木

  構文木は、文のツリー構造であり、それは文の文法構造のレベルを理解するのに有用である、文の導出結果を表します。示すように、構文木「私は、大学の学生です」:

              

  これらの基本から、今インタプリタパターンの構造を導入するのは簡単です。構造および組成同様のパターンがモードを説明するが、それは組み合わせパターンより構成要素を含み、構造モデルの組み合わせがモデルのモードクラスタイプを解釈し、オブジェクトモデルです。

  通訳のパターンは、次の主要な役割で構成されています。

  • 抽象表現(抽象表現)役割:インタプリタがメインの解釈は(解釈あって、インタプリタの動作を説明するインターフェースの規則を定義しました)。
  • ターミネーター式(ターミナル式)ロール:抽象的な表現のサブクラスは、文法内の端末のシンボルに関連付けられた動作を実行するために使用され、文法は、各端末のシンボルは、それに対応する特定の発現端部を有します。
  • 非終端式(非終端式)ロール:抽象的な表現のサブクラスは、非終端記号表現に各ルールの対応に関連した文法を文法非終端動作を実現するために使用されます。
  • 環境(コンテキスト)の役割は:典型的には、一般的にすべての共有データインタプリタを送信するために使用される、インタプリタがここで後者の値を得ることができ、必要なそれぞれの共通インタプリタのデータまたは機能を含みます。
  • クライアント(クライアント):文章や表現の主な仕事は、もちろん、あなたも通訳の通訳の環境ロールを介して間接的にアクセスすることができ、抽象構文木のインタプリタオブジェクトの記述を使用してに解析し、その後、通訳通訳を呼ぶことがあります。

  示すように、パターン構成図インタプリタ。

          

  次のようにコードの構造は次のようになります。 

// のような抽象的な表現
インタフェースAbstractExpression
{
    公共 ;オブジェクト(文字列情報)を解釈     // 解釈
}
 // ターミネータ表現クラス
クラス TerminalExpression 実装のAbstractExpressionを
{
    パブリックオブジェクトの解釈(文字情報)
    {
        // ターミネーター発現の処理
    }
}
// などの非終端表現
クラス NonterminalExpression 実装AbstractExpression
{
    プライベートAbstractExpressionのEXP1。
    プライベートAbstractExpressionのEXP2。
    パブリックオブジェクトの解釈(文字情報)
    {
        // 非終端記号処理式
    }
}
// 環境
クラスのコンテキスト
{
    プライベートAbstractExpressionのEXP。
    公共コンテキスト()
    {
        // データの初期化
    }
     公共 無効操作(文字情報)
    {
        // 関連するクラス式の解釈を呼び出します
    }
}

応用例IVモード

  私たちは、通訳のパターンを使用する「シャオ越トン」バスカードリーダープログラムを設計:それは「韶関」または「カントン」と「老人の場合は、「少越トン」カードリーダーは、バスの乗客の身元を確認できた場合「」女性は、「」子「などがバックル2元に乗り、フリーライドすることができます。

  分析:次のように「解釈モード」のこの例では、より適切な設計、その最初の文法規則のデザインです。

<式> :: = <都市>的<人>
<都市> :: =韶関| 広州
 <人> :: =高齢者|女性|子供

  その後、バスカードリーダープログラムの文法クラス図の設計の規則に従って、次の手順を実行します。

  • 解釈は解釈が含ま抽象的な表現(式)インターフェース、(文字列情報)を定義します。
  • 式は条件を満たすために街を保持するために、抽象表現の解釈インタフェースは(するStringInfo)の解釈を達成するためにどのセット(セット)またはヒトクラスでターミネータ(ターミナル式)クラスを定義し、文字を解析することが決定されかどうかの文字列がセットターミネータです。
  • ターミネーター発現対象人員ターミネーター表現オブジェクトと都市の条件を含む抽象表現のサブクラスであり、非末端式(AndExpressicm)クラスの定義の条件を満足し、かつ解釈達成する(文字列文字列は、市内での条件を満たした者の条件を満たすように分析されているかどうかを決定するために使用する情報)の方法。
  • 表現のターミネーターの完全な初期化に必要なデータインタプリタが含まれており、分析対象の文字列表現オブジェクトを呼び出すように解釈フリーライド(文字情報)のメソッドを定義して最後に、環境の定義(コンテキスト)クラス、説明しました。図に示される構造:

                

  コードは次のように実装されています。

/ * 文法規則
  <式> :: = <都市>的<人>
  <市> :: =韶関|広州
  <人> :: =高齢者|女性|子供
* / 
パブリック・ クラスInterpreterPatternDemo
{
    公共の 静的な 無効メイン(文字列[] args)を
    {
        コンテキスト・バス = 新しいコンテキスト();
        bus.freeRide( "韶関市老人" );
        bus.freeRide( "韶関市青年" );
        bus.freeRide( "広州女性" );
        bus.freeRide( "広州子供" );
        bus.freeRide(「山東省の子供」)。
    }
}
// のような抽象的な表現
インターフェース
{
    パブリック ブール(文字列情報)を解釈します。
}
// ターミネータ表現のクラス
クラス TerminalExpression 実装の
{
    プライベート設定<文字列>セット= 新しい HashSetの<文字列> ();
    公共TerminalExpression(文字列[]データ)
    {
        以下のためにINT iが= 0; I <data.length; I ++ )set.add(データ[I])。
    }
    パブリック ブールは解釈(文字情報)
    {
        もし(set.contains(情報))
        {
            返す ;
        }
        リターン はfalse ;
    }
}
// などの非終端表現
クラス AndExpression 実装の
{
    プライベート式の都市= nullをプライベート式人= nullを公共AndExpression(式都市、表現者)
    {
        この .city = 都市。
        この .person = 人。
    }
    パブリック ブールは解釈(文字情報)
    {
        文字列s [] = info.split( "的" )。       
        戻り city.interpret(S [0])&& person.interpret(S [1 ])。
    }
}
// 環境
クラスのコンテキスト
{
    プライベート文字列[] = {市内"韶関"、 "広州" };
     プライベート文字列[] = { "高齢"者、 "女性"、 "子供" };
     プライベート発現cityPerson、
     公共コンテキスト()
    {
        式の市は = 新しいTerminalExpression(市内)を、
        式の人は = 新しいTerminalExpression(人を)。
        cityPerson = 新しいAndExpression(都市、人)。
    }
    公共 のボイドフリーライド(文字情報)
    {
        ブール OK = cityPerson.interpret(情報を);
         IF(OK)のSystem.out.println(+情報+ "あなたがいる" "これはあなたの乗車無料!" );
         のSystem.out.println(+情報」、あなたはそうではありません人員、この車のチャージバック2元を「無償!)。   
    }
}

  結果は以下の通りであります:

あなたは、あなたがこの車の無料韶関高齢者です!
韶関若者は、あなたは、この車のチャージバック2元フリーの人ではありません!
あなたは広州の女性、これはあなたの乗車は無料です!
広州であなたの子供たち、これはあなたの乗車無料!
山東省の子供は、あなたが自由な人々、この車のチャージバック2元ではありません!

第五に、アプリケーションシナリオのインタプリタモード

  構造と上記説明モードの特性、応用シナリオの以下の分析。

  • 場合は、言語の文法は簡単で、効率の実装が重要な問題ではありません。
  • 問題が再発し、時間を表現するために、単純な言語を使用することができたとき。
  • 所望の言語を解釈し、言語の文は、抽象構文木のように表すことができる場合、例えばXML文書は説明します。

  注:それは効率性、パフォーマンス、および保守の問題につながるため、実際のソフトウェア開発に使用されるインタプリタパターンは、比較的小さいです。あなたがヒットした場合、Javaでの表現の解釈は、このようなExpression4Jやジェップデザインとして使用することができます。

第六は、モード通訳拡大します

  Expression4J、MESP(数学式文字列:プロジェクトの開発では、あなたは発現データ解析および計算になりたい場合は、インタプリタモードのデザインを取ることはありません、Javaは、以下の強力な数式パーサ提供パーサ) などとジェップを、彼らが使いやすい強力ないくつかの複雑な文法を、説明することができます。

  ツールキットの使用を導入し、今の例をJEP。JEPは、Java式パーサー短い、数式を変換し、Javaライブラリを計算するために使用されるJava式パーサ、です。このライブラリによって、ユーザは、入力文字列のような任意の式は、その後、急速にその結果を計算することができます。そしてジェップは、多くの一般的な数学関数と定数が含まれ、ユーザー定義変数、定数と関数をサポートしています。

  ジェップは、任意のディレクトリにパッケージ、アンパック、JEP-xxxjarをするファイルを圧縮し、使用前にダウンロードし、Javaのビルド・パス「ダイアログの」ライブラリ「タブ「Eclipseの中で外部JAR(X)を追加」を選択。.. 。」、パッケージはライブラリーのいずれかを使用するジェッププロジェクトの後に追加されます。

  導入する例として、預金の利息を計算するために、次の。預金金利が計算されます。次のように主レートは、時間= X関心をX、関連するコードは次のようになります。

パブリック クラスJepDemo
{
    公共の 静的な 無効メイン(文字列[] argsが)スローJepExceptionを
    {
        JEP JEP = 新しい新しいJEP();
         // 計算式データ定義 
        預金の文字列の関心を=「主*金利*時間」;
         // 関連する変数の割り当てに 
        jep.addVariable(「主」10000 )。
        jep.addVariable( "利率"、0.038 )。
        jep.addVariable( "時間"、2 );
        jep.parse(預金金利);     // 解析式の 
        オブジェクト計上jep.evaluate =();     // 計算 
        するSystem.out.println( "預金金利:" + 発生主義)。
    }
}

  次のように実行結果は以下のとおりです。

預金の利息:760.0

おすすめ

転載: www.cnblogs.com/jing99/p/12610089.html