定義
インタプリタモデルはクラスの動作モデルです。言語が与えられると、インタプリタモデルはその文法の表現を定義し、同時にインタプリタを提供できます。クライアントはこのインタプリタを使用して言語の文を解釈できます。
意図
言語が与えられ、その文法表現を定義し、インタプリタを定義すると、このインタプリタは識別子を使用してその言語の文を解釈します
主に問題を解決する
いくつかの固定文法の文を説明する通訳を作成する
長所と短所
利点:
- 優れたスケーラビリティと柔軟性
- 式を解釈する新しい方法を追加しました
- 簡単な文法の実装が簡単
短所:
- 使用量の少ないシナリオ
- 複雑な文法のために維持するのがより難しい
- クラスの肥大化を引き起こします
- 再帰呼び出しメソッドを使用すると、効率が低くなります
構造
関係する役割:
- 抽象式(式)の役割:すべての具象式の役割が実装する必要のある抽象インターフェースを宣言します。このインターフェースは主に、解釈操作と呼ばれる解釈メソッドです。
- TerminalExpression(TerminalExpression)ロール:これは特定のロールです
- 抽象表現の役割に必要なインターフェース、主に解釈メソッドを実装しました
- 文法の各終端記号には、それに対応する特定の終端記号があります
- 非終端表現(NonterminalExpression)の役割:これは特定の役割です
- 文法R = R1R2 ... Rnの各ルールには、特定の非終端式クラスが必要です。
- R = R1R2 ... Rnの各シンボルは、静的型式のインスタンス変数を保持します。
- 解釈操作の解釈メソッドを実装すると、解釈操作は、R1R2 ... Rnのシンボルを表す上記のインスタンス変数を再帰的に呼び出します。
- クライアントの役割:抽象構文ツリーを構築し、解釈操作を呼び出します
- コンテキストの役割:変数の真の値など、インタープリターの外部にいくつかのグローバル情報を提供します。
例
抽象表現の役割:
/**
* 这个抽象类代表终结类和非终结类的抽象化
*/
public abstract class Expression {
/** 以环境类为准,本方法解释给定的任何一个表达式 */
public abstract boolean interpret(Context ctx);
/** 检验两个表达式在结构上是否相同 */
public abstract boolean equals(Object o);
/** 返回表达式的hashCode */
public abstract int hashCode();
/** 将表达式转换为字符串 */
public abstract String toString();
}
式の終了の役割:
Constantオブジェクトはブール定数を表します
public class Constant extends Expression {
private boolean value;
public Constant(boolean value) {
this.value = value;
}
/** 解释操作 */
@Override
public boolean interpret(Context ctx) {
return value;
}
/** 检验两个表达式在结构上是否相同 */
@Override
public boolean equals(Object o) {
if (o != null && o instanceof Constant) {
return this.value = ((Constant)o).value;
}
return false;
}
/** 返回表达式的hashCode */
@Override
public int hashCode() {
return (this.toString()).hashCode();
}
/** 将表达式转换为字符串 */
@Override
public String toString(){
return new Boolean(value).toString();
}
}
Variableオブジェクトは、名前付き変数を表します
public class Variable extends Expression {
private String name;
public Variable(String name) {
this.name = name;
}
/** 解释操作 */
@Override
public boolean interpret(Context ctx) {
return ctx.lookup(this);
}
/** 检验两个表达式在结构上是否相同 */
@Override
public boolean equals(Object o) {
if (o != null && o instanceof Variable) {
return this.name.equals(((Variable)o).name);
}
return false;
}
/** 返回表达式的hashCode */
@Override
public int hashCode() {
return (this.toString()).hashCode();
}
/** 将表达式转换为字符串 */
@Override
public String toString() {
return name;
}
}
非終端式の役割:
2つのブール式の論理積演算によって新しいブール式を与える演算を表します。
public class And extends Expression {
private Expression left, right;
public And(Expression left, Expression right) {
this.left = left;
this.right = right;
}
/** 解释操作 */
@Override
public boolean interpret(Context ctx) {
return left.interpret(ctx) && right.interpret(ctx);
}
/** 检验两个表达式在结构上是否相同 */
@Override
public boolean equals(Object o) {
if (o != null && o instanceof And) {
return this.left.equals(((And)o).left) && this.right.equals(((And)o).right);
}
return false;
}
/** 返回表达式的hashCode */
@Override
public int hashCode() {
return (this.toString()).hashCode();
}
/** 将表达式转换为字符串 */
@Override
public String toString() {
return "(" + left.toString() + " AND " + right.toString() + ")";
}
}
2つのブール式による論理OR演算によって新しいブール式を与える演算を表します。
public class Or extends Expression {
private Expression left, right;
public Or(Expression left, Expression right) {
this.left = left;
this.right = right;
}
/** 解释操作 */
@Override
public boolean interpret(Context ctx) {
return left.interpret(ctx) || right.interpret(ctx);
}
/** 检验两个表达式在结构上是否相同 */
@Override
public boolean equals(Object o) {
if (o != null && o instanceof Or) {
return this.left.equals(((Or)o).left) && this.right.equals(((Or)o).right);
}
return false;
}
/** 返回表达式的hashCode */
@Override
public int hashCode() {
return (this.toString()).hashCode();
}
/** 将表达式转换为字符串 */
@Override
public String toString() {
return "(" + left.toString() + " OR " + right.toString() + ")";
}
}
論理否定を介してブール式によって指定された新しいブール式の演算を表します。
public class Not extends Expression {
private Expression exp;
public Not(Expression exp) {
this.exp = exp;
}
/** 解释操作 */
@Override
public boolean interpret(Context ctx) {
return !exp.interpret(ctx);
}
/** 检验两个表达式在结构上是否相同 */
@Override
public boolean equals(Object o) {
if (o != null && o instanceof Not) {
return this.exp.equals(((Not)o).exp);
}
return false;
}
/** 返回表达式的hashCode */
@Override
public int hashCode() {
return (this.toString()).hashCode();
}
/** 将表达式转换为字符串 */
@Override
public String toString() {
return "(Not " + exp.toString() + ")";
}
}
環境クラスは、変数からブール値へのマッピングを定義します。
public class Context {
private HashMap map = new HashMap();
public void assign(Variable var, boolean value) {
map.put(var, new Boolean(value));
}
public boolean lookup(Variable var) {
Boolean value = (Boolean) map.get(var);
if (value == null) {
throw new IllegalArgumentException();
}
return value.booleanValue();
}
}
クライアントの役割:
public class Client {
private static Context ctx;
private static Expression exp;
public static void main(String[] args) {
ctx = new Context();
Variable x = new Variable("x");
Variable y = new Variable("y");
Constant c = new Constant(true);
ctx.assign(x, false);
ctx.assign(y, true);
exp = new Or(new And(c, x), new And(y, new Not(x)));
System.out.println("x= " + x.interpret(ctx));
System.out.println("y= " + y.interpret(ctx));
System.out.println(exp.toString() + " = " + exp.interpret(ctx));
}
}
該当する状況
- システムには説明するための簡単な言語があります
- いくつかの繰り返し発生する問題は、この単純な言語で表現できます
- 効率は主な考慮事項ではありません