Modo intérprete
definición
El modelo de intérprete es un modelo de comportamiento de una clase. Dado un idioma, el modelo de intérprete puede definir una representación de su gramática y proporcionar un intérprete al mismo tiempo. El cliente puede utilizar este intérprete para interpretar oraciones en el idioma.
intención
Dado un idioma, define su representación gramatical y define un intérprete, este intérprete utiliza el identificador para interpretar oraciones en el idioma.
Principalmente resuelve el problema
Construir un intérprete para explicar oraciones para una gramática fija.
Pros y contras
ventaja:
- Buena escalabilidad y flexibilidad
- Se agregó una nueva forma de interpretar expresiones.
- Fácil de implementar gramática simple
Desventajas:
- Escenarios de menor uso
- Más difícil de mantener para gramática compleja
- Causará expansión de clases
- Usando el método de llamada recursiva, baja eficiencia
estructura
Roles involucrados:
- Rol de expresión abstracta (expresión): declare una interfaz abstracta que todos los roles de expresión concretos deben implementar. Esta interfaz es principalmente un método de interpretación, llamado operación de interpretación
- Rol TerminalExpression (TerminalExpression): este es un rol específico
- Implementó la interfaz requerida por el rol de expresión abstracta, principalmente un método de interpretación
- Cada símbolo terminal en la gramática tiene una expresión terminal específica correspondiente.
- Rol Nonterminal Expression (NonterminalExpression): este es un rol específico
- Cada regla en la gramática R = R1R2 ... Rn requiere una clase de expresión no terminal específica
- Cada símbolo en R = R1R2 ... Rn contiene una variable de instancia de tipo estático Expresión
- Implemente el método de interpretación de la operación de interpretación, y la operación de interpretación llama de forma recursiva a las variables de instancia mencionadas anteriormente que representan los símbolos en R1R2 ... Rn
- Rol del cliente: construir un árbol de sintaxis abstracto, operaciones de interpretación de llamadas
- Rol de contexto: proporcione información global fuera del intérprete, como el valor real de las variables, etc.
Ejemplo
Rol de expresión abstracta:
/**
* 这个抽象类代表终结类和非终结类的抽象化
*/
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();
}
Rol de expresión final:
un objeto constante representa una constante booleana
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();
}
}
Un objeto Variable representa una variable nombrada
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;
}
}
Rol de expresión no terminal:
representa la operación de dar una nueva expresión booleana mediante la operación lógica Y de dos expresiones booleanas:
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() + ")";
}
}
Representa la operación de dar una nueva expresión booleana mediante la operación lógica OR mediante dos expresiones booleanas:
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() + ")";
}
}
Representa la operación de una nueva expresión booleana dada por una expresión booleana mediante negación lógica:
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() + ")";
}
}
La clase de entorno define un mapeo de variables a valores booleanos:
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();
}
}
Rol del cliente:
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));
}
}
Situación aplicable
- El sistema tiene un lenguaje sencillo para explicar
- Algunos problemas recurrentes se pueden expresar en este sencillo lenguaje.
- La eficiencia no es la consideración principal