この記事では、インタープリターパターンに基づいた単純な言語関数を定義するJavaの実装について説明します。次のように、参照のために共有してください。
パターン定義
通訳パターン:言語の文法的表現を与え、言語の文章を解釈するための通訳を定義することです。通訳パターンは、単純な文法の後にパターンデザインを使用してこれらのステートメントを解釈する方法を説明しています。
2番目のモードの例
1パターン分析
このパターンを自分で説明するために言語を設計しました
(1)言語はケースに敏感です(2)言語はプログラムから始まり、終了(3)printlnはラインを印刷し、それを破壊することを意味します(4)(4)…から…から…末端ループへ
言語コンテンツの例は次のとおりです。
プログラムprintln start ... 90から100のiの場合、println end ... end ... end ...
この文の意味は、最初に「start ...」で行の破壊を印刷し、次に「90」、「91」、... "100"でラインブレークを循環し、最後に「end ...」でラインブレークを印刷します。
2この言語はツリー構造を説明しています
3言語通訳のアクティビティ図
4つのコードの例
4.1コンテキスト環境を作成 - コンテキスト
パッケージcom.demo.interpreter.context; import java.util.hashmap; import java.util.iterator; import java.util.map; import java.util.stringtokenizer;/** *コンテキスト環境 * * @author * */public class context {//テキストの最終的な弦楽器文字列の文字列。 //現在のコマンドプライベート文字列CurrentToken; //動的に変更された情報コンテンツプライベート最終マップ<string、object> map = new hashmap <string、object>(); / ** * Constructorセットコンテンツ * * @param Text */ public Context(string text){//スペースを使用してテキストを分離して、this.stringtokenizer = new StringTokenizer(テキスト); } / ***解析テキスト* / public string next(){if(this.stringtokenizer.hasmoretokens()){currentToken = this.stringtokenizer.nextToken(); } else {currentToken = null; } currentTokenを返します。 } / ** *コマンドが正しいかどうかを判断します * * @paramコマンド * @return * / public boolean equalswithcommand(string command){if(command == null ||!command.equals(this.currenttoken)){return false; } trueを返します。 } / ** *現在のコマンドコンテンツを取得 * * @return * / public string getCurrentToken(){return this.currenttoken; } / ** * nodeのコンテンツを取得 * * @return * / public string getTokenContent(string text){string str = text; if(str!= null){//マップ内の動的に変更されたコンテンツを置き換えて、iterator <string> //マップ内の動的変化コンテンツを置き換え、iterator <string> iterator = this.map.keyet()。iterator(); while(iterator.hasnext()){string key = iterator.next();オブジェクトobj = map.get(key); str = str.replaceall(key、obj.tostring()); }} return str; } public void put(string key、object value){this.map.put(key、value); } public void clear(string key){this.map.remove(key); }}4.2式インターフェイス-IEXPressions
パッケージcom.demo.interpreter.express; import com.demo.interpreter.context.context.context;/** * * expression interface * * @author * */public interface iexpressions {/** * parsing * * @param context */public void(Context Context); / ** *実行方法 * * @param Context */ public void relutting();}4.3主な表現 - 進行性概念
パッケージcom.demo.interpreter.express; Import com.demo.interpreter.context.context.context;/** *プログラム式 * * @author * * */public class programexpressionはiexpressionsを実装します{//コンテキスト環境環境プライベート最終コンテキスト; //現在のコマンドプライベート最終静的文字列コマンド= "program"; //次の式を保存するprivate iExpressions式を参照します。 / ** *コンストラクターは、コンテンツを渡す * * @param Text */ public Programexpression(string text){this.context = new Context(text); this.parse(this.context); } @Override public void parse(context context){//最初のコマンドノードthis.context.next(); } / ***実装説明方法* / @Override public void reluttion(){//プログラムで始まるかどうかを決定する場合(!this.context.equalswithcommand(command)){system.out.println( "the '" + command + "は除外されます!"); } else {// this.context.next()をプログラムで開始します。 this.Expressions = new ListExpression(); this.expressions.parse(this.context); // listExpression式は、this.expressions.interpret(); }}}4.4リスト式-listExpression
パッケージcom.demo.interpreter.express; Import java.util.arraylist; Import java.util.iterator; Import com.demo.interpreter.context.context;/** * list expression * * @author * * */public class listexpression Iexpressions {private cuttunt;プライベート最終配列<iexpressions> list = new ArrayList <IExpressions>(); / ** *コンストラクターは、 * * @paramコンテキストに解析されるコンテキストを渡します */ public void parse(context context){this.context = context; // listExpression解析式では、ターミネーター式または例外が(true)を終了するまでステートメント内の各単語を解釈するためのループ{if(this.context.getCurrentToken()== null){//現在のノードを取得します。 nullの場合、end式がsystem.out.println( "エラー:失効 'end'!")が欠落していることを意味します。壊す; } else if(this.context.equalswithcommand( "end")){this.context.next(); //解析は通常ブレークを終了します。 } else {//コマンド式を作成するiExpressions expressions = new CommandExpersion(this.Context); // list.add(expressions)に追加します。 }}} / ***説明method* / @override public void relutte(){//リストリストの各式の説明をループして、iterator <iexpressions> iterator = list.iterator(); while(iterator.hasnext()){(iterator.next())。 }}}4.5コマンド式-CommandExpersion
パッケージcom.demo.interpreter.express; Import com.demo.interpreter.context.context.context;/** * command expression * * @author * */public class commandExpersion IExpressions {private final context Context;プライベートIEXPressions式; / ** * constroumtメソッドは、コンテキストを渡します * * @paramコンテキスト */ public commandexperssion(コンテキストコンテキスト){this.context = context; this.parse(this.context); } public void parse(context context){//現在のコマンドカテゴリを判断すると、元のコマンドのみを区別し、if(this.context.equalswithcommand( "for")){//解析式の式のために作成= new forexpression(this.context); } else {//コンテンツのオリジナルコマンド式を作成する解析式= new PrimitiveExpression(this.Context); }} / ***コンテンツの解析* / @Override public void relutte(){//コンテンツの解析this.expressions.interpret(); }}4.6ループ式 - 外観
パッケージcom.demo.interpreter.express; Import com.demo.interpreter.context.context.context;/** * for expression * * @author * */public class reexpression Iexpressions {private final Context Context; //現在のインデックスキー値プライベート文字列変数を保存します。 //ループプライベートint start_indexの開始位置を保存します。 //ループプライベートint end_indexの終了位置を保存します。プライベートIEXPressions式; / ** *コンストラクターは、 * * @paramコンテキストに解析されるコンテキストを渡します */ public forexpression(コンテキストコンテキスト){this.context = context; this.parse(this.context); } / ***解析式* / @Override public void parse(context context){//最初に現在のノードthis.context.next(); while(true){//ノードを審査するif(this.context.equalswithcommand( "from")){//開始インデックスコンテンツ文字列nextStr = this.context.next(); try {this.start_index = integer.parseint(nextstr); } catch(Exception e){System.out .println( "error:from 'from' expression Error!expressionの形式が正しいことを確認してください!");壊す; } //次のノードthis.context.next(); } else if(this.context.equalswithcommand( "to")){// end index Content string nextstr = this.context.next(); try {this.end_index = integer.parseint(nextstr); } catch(Exception e){system.out .println( "error:after 'to' expression Error!式の形式が正しいことを確認してください!"); } this.context.next();壊す; } else {//現在のインデックス変数のコンテンツを設定if(this.variable == null){this.variable = this.context.getCurrentToken(); } //次のノードthis.context.next(); }} //リストexpression this.Expressions = new ListExpression(); this.expressions.parse(this.context); } / ***説明方法を実装* / @Override public void relutte(){//(int x = this.start_index; x <= this.end_index; x ++){//変数コンテンツthis.context.put( ""+this.variable、x); //説明方法this.expressions.intrepret(); } //使用されている一時変数コンテンツを削除します。context.clear( "" + this.variable); }}4.7基本式 - 原始的発現
パッケージcom.demo.interpreter.express; Import com.demo.interpreter.context.context;/** *最も基本的な式 * * @author * */public class PrimitiveExpressionはiExpressions {private Context Context; //ノード名プライベート文字列tokenName; //テキストコンテンツプライベート文字列テキスト。 / ** *コンストラクターは、 * * @paramコンテキストに解析されるコンテキストを渡します */ public PrimitiveExpression(コンテキストコンテキスト){this.parse(context); } @Override public void parse(context context){this.context = context; this.tokenname = this.context.getCurrentToken(); this.context.next(); if( "println" .equals(this.tokenname)){this.text = this.context.getCurrentToken(); this.context.next(); }} / ***実装説明メソッド* / @Override public void reluttion(){//最初に現在のノードコンテンツを取得するif( "println" .equals(tokenname)){//コンテンツ情報を取得// print content system.out.out.println(this.context.gettokencentent(this.text)); }}}4.8言語通訳を動作させてください-Client
パッケージcom.demo.interpreter; Import com.demo.interpreter.express.iexpressions; Import com.demo.interpreter.express.programexpression;/** * Main Application * */public class client {/** * * @param args */public static Strings) I 90から100のprintln i end println end ... end "; System.out.println( "str:" + str); //プログラム式を作成するiExpressions式= new Programexpression(str); //式の実行を説明します。Interpret(); }}5ランニング結果
str:プログラムprintln start ... 90から100のiのiの場合、println end ... end ...
始める...
90
91
92
93
94
95
96
97
98
99
100
終わり...
3つの設計原則
1「オープンクローズ」原則
2閉鎖変化の原則
4つの使用機会
(1)特定のタイプの問題が高頻度で発生し、ビジネスルールが頻繁に変化し、同様の状況が繰り返し発生します。
(2)ビジネスルールはそれほど複雑ではなく、面倒ではなく、文法規則を抽象化する方が簡単です。
(3)効率は、ソフトウェアシステムで考慮される主な要因ではありません。
5つのインタープリターモード静的クラス図
Java関連のコンテンツを増やすために、このサイトに興味のある読者は、「Javaオブジェクト指向プログラミングに関する紹介と高度なチュートリアル」、「Javaデータ構造とアルゴリズムに関するチュートリアル」、Java Operation domノードスキルの要約」、「Javaファイルの概要、およびJava操作スキルの概要」の概要を見ることができます。
この記事がみんなのJavaプログラミングに役立つことを願っています。