El patrón de diseño del intérprete es uno de los patrones de diseño de comportamiento . El patrón de intérprete se utiliza para definir una representación gramatical de un idioma y proporciona un intérprete para manejar esta gramática.
- Este patrón implica implementar una interfaz de expresión que indica interpretar un contexto particular. Este patrón se utiliza en el análisis de SQL, el motor de procesamiento de símbolos, etc.
- Este patrón actúa sobre una jerarquía de expresiones. Cada expresión aquí es un terminal o no terminal.
- La estructura de árbol del patrón de diseño del intérprete es algo similar a la definida por el patrón de diseño compuesto, donde las expresiones terminales son objetos hoja y las expresiones no terminales son compuestos.
- El árbol contiene las expresiones a evaluar y generalmente lo genera un analizador. El analizador en sí no es parte del patrón del intérprete.
Por ejemplo:
Aquí está la jerarquía de expresiones para “+ – 9 8 7” :
Implementando el patrón de intérprete
Patrón de diseño de intérprete de diagrama UML
Componentes de diseño
- AbstractExpression (Expresión): declara una operación de interpretación() que todos los Nodes (terminales y no terminales) en el AST anulan.
- TerminalExpression (NumberExpression): implementa la operación interpret() para expresiones de terminal.
- NonterminalExpression (AdditionExpression, SubtractionExpression y MultiplicationExpression): implementa la operación interpret() para todas las expresiones no terminales.
- Contexto (String): Contiene información que es global para el intérprete. Es esta expresión de string con la notación Postfix la que debe interpretarse y analizarse.
- Cliente (ExpressionParser): compila (o se proporciona) el AST ensamblado a partir de TerminalExpression y NonTerminalExpression. El Cliente invoca la operación interpret().
Veamos un ejemplo de patrón de diseño de intérprete.
// Expression interface used to // check the interpreter. interface Expression { boolean interpreter(String con); } // TerminalExpression class implementing // the above interface. This interpreter // just check if the data is same as the // interpreter data. class TerminalExpression implements Expression { String data; public TerminalExpression(String data) { this.data = data; } public boolean interpreter(String con) { if(con.contains(data)) { return true; } else { return false; } } } // OrExpression class implementing // the above interface. This interpreter // just returns the or condition of the // data is same as the interpreter data. class OrExpression implements Expression { Expression expr1; Expression expr2; public OrExpression(Expression expr1, Expression expr2) { this.expr1 = expr1; this.expr2 = expr2; } public boolean interpreter(String con) { return expr1.interpreter(con) || expr2.interpreter(con); } } // AndExpression class implementing // the above interface. This interpreter // just returns the And condition of the // data is same as the interpreter data. class AndExpression implements Expression { Expression expr1; Expression expr2; public AndExpression(Expression expr1, Expression expr2) { this.expr1 = expr1; this.expr2 = expr2; } public boolean interpreter(String con) { return expr1.interpreter(con) && expr2.interpreter(con); } } // Driver class class InterpreterPattern { public static void main(String[] args) { Expression person1 = new TerminalExpression("Kushagra"); Expression person2 = new TerminalExpression("Lokesh"); Expression isSingle = new OrExpression(person1, person2); Expression vikram = new TerminalExpression("Vikram"); Expression committed = new TerminalExpression("Committed"); Expression isCommitted = new AndExpression(vikram, committed); System.out.println(isSingle.interpreter("Kushagra")); System.out.println(isSingle.interpreter("Lokesh")); System.out.println(isSingle.interpreter("Achint")); System.out.println(isCommitted.interpreter("Committed, Vikram")); System.out.println(isCommitted.interpreter("Single, Vikram")); } }
Producción:
true true false true false
En el código anterior, estamos creando una interfaz Expression y clases concretas implementando la interfaz Expression. Se define una clase TerminalExpression que actúa como intérprete principal y otras clases OrExpression , AndExpression se utilizan para crear expresiones combinacionales.
Ventajas
- Es fácil cambiar y ampliar la gramática. Debido a que el patrón usa clases para representar las reglas gramaticales, puede usar la herencia para cambiar o ampliar la gramática. Las expresiones existentes se pueden modificar de forma incremental y las nuevas expresiones se pueden definir como variaciones de las antiguas.
- Implementar la gramática también es fácil. Las clases que definen Nodes en el árbol de sintaxis abstracta tienen implementaciones similares. Estas clases son fáciles de escribir y, a menudo, su generación se puede automatizar con un compilador o un generador de analizadores.
Desventajas
- Las gramáticas complejas son difíciles de mantener. El patrón Intérprete define al menos una clase para cada regla de la gramática. Por lo tanto, las gramáticas que contienen muchas reglas pueden ser difíciles de administrar y mantener.
Este artículo es una contribución de Saket Kumar . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo usando contribuya.geeksforgeeks.org o envíe su artículo por correo a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA