En programación informática , el patrón intérprete es un patrón de diseño que especifica cómo evaluar oraciones en un lenguaje. La idea básica es tener una clase para cada símbolo ( terminal o no terminal ) en un lenguaje informático especializado . El árbol sintáctico de una oración en el lenguaje es una instancia del patrón compuesto y se utiliza para evaluar (interpretar) la oración para un cliente. [ 1 ] : 243 Véase también Patrón compuesto .
Descripción general
El patrón de diseño Intérprete [ 2 ] es uno de los veintitrés patrones de diseño GoF bien conocidos que describen cómo resolver problemas de diseño recurrentes para diseñar software orientado a objetos flexible y reutilizable, es decir, objetos que son más fáciles de implementar, cambiar, probar y reutilizar.
¿Qué problemas puede resolver el patrón de diseño Intérprete?
Fuente: [ 3 ]
- Se debe definir una gramática para un lenguaje simple.
- para que las oraciones en ese idioma puedan ser interpretadas.
Cuando un problema se presenta con mucha frecuencia, se podría considerar representarlo como una oración en un lenguaje simple ( Lenguajes Específicos de Dominio ) para que un intérprete pueda resolver el problema interpretando la oración.
Por ejemplo, cuando se deben especificar muchas expresiones de búsqueda diferentes o complejas. Implementarlas (integrarlas directamente) en una clase es inflexible porque compromete a la clase a expresiones específicas e imposibilita especificar nuevas expresiones o modificar las existentes de forma independiente (sin tener que modificar) la clase.
¿Qué solución describe el patrón de diseño Intérprete?
- Defina una gramática para un lenguaje simple definiendo una
Expressionjerarquía de clases e implementando unainterpret()operación. - Representar una oración en el lenguaje mediante un árbol de sintaxis abstracta (AST) compuesto por
Expressioninstancias. - Interpreta una oración llamando
interpret()al AST.
Los objetos de expresión se componen recursivamente en una estructura compuesta/de árbol que se denomina árbol de sintaxis abstracta (véase el patrón Composite ). El patrón Interpreter no describe cómo construir un árbol de sintaxis abstracta. Esto puede hacerse manualmente por un cliente o automáticamente por un analizador sintáctico .
Véase también el diagrama de clases y objetos UML que aparece a continuación.
Usos
- Lenguajes de consulta de bases de datos especializados como SQL .
- Lenguajes informáticos especializados que se utilizan con frecuencia para describir protocolos de comunicación.
- La mayoría de los lenguajes de programación de propósito general incorporan en realidad varios lenguajes especializados .
Estructura
Diagrama de clases y objetos UML

En el diagrama de clases UML anterior , la clase se refiere a la interfaz común para interpretar una expresión . La clase no tiene hijos e interpreta una expresión directamente. La clase mantiene un contenedor de expresiones hijas ( ) y reenvía las solicitudes de interpretación a estas . ClientAbstractExpressioninterpret(context)TerminalExpressionNonTerminalExpressionexpressionsexpressions
El diagrama de colaboración de objetos muestra las interacciones en tiempo de ejecución: El Clientobjeto envía una solicitud de interpretación al árbol de sintaxis abstracta. La solicitud se reenvía a (se ejecuta en) todos los objetos hacia abajo en la estructura del árbol. Los NonTerminalExpressionobjetos ( ntExpr1,ntExpr2) reenvían la solicitud a sus expresiones hijas. Los TerminalExpressionobjetos ( ) realizan la interpretación directamente.tExpr1,tExpr2,…
Diagrama de clases UML
![]()
Ejemplo
Esta implementación en C++23 se basa en el código de ejemplo anterior a C++98 que aparece en el libro.
importar std ;using String = std :: string ; template < typename K , typename V > using TreeMap = std :: map < K , V > ; template < typename T > using UniquePtr = std :: unique_ptr <T> ;clase BooleanExpression { public : BooleanExpression ( ) = default ; virtual ~ BooleanExpression ( ) = default ; virtual bool evaluate ( Context & ) = 0 ; virtual UniquePtr <BooleanExpression> replace ( String & , BooleanExpression & ) = 0 ; virtual UniquePtr <BooleanExpression> copy ( ) const = 0 ; } ;clase VariableExpression ;clase Contexto { privado : TreeMap < const VariableExpression * , bool > m ; público : Context () = default ;[[ nodiscard ]] bool lookup ( const VariableExpression * key ) const { return m . at ( key ); }void assign ( VariableExpression * key , bool value ) { m [ key ] = value ; } };clase VariableExpression : public BooleanExpression { private : String name ; public : VariableExpression ( const String & name ) : name { name } {}virtual ~ VariableExpression () = default ;[[ nodiscard ]] virtual bool evaluate ( Context & context ) const { return context . lookup ( this ); }[[ nodiscard ]] virtual UniquePtr < VariableExpression > replace ( const String & name , BooleanExpression & exp ) { if ( this -> name == name ) { return std :: make_unique < VariableExpression > ( exp . copy ()); } else { return std :: make_unique < VariableExpression > ( name ); } }[[ nodiscard ]] virtual UniquePtr < BooleanExpression > copy () const { return std :: make_unique < BooleanExpression > ( name ); }VariableExpression ( const VariableExpression & ) = delete ; VariableExpression & operator = ( const VariableExpression & ) = delete ; };clase AndExpression : public BooleanExpression { private : UniquePtr < BooleanExpression > operand1 ; UniquePtr < BooleanExpression > operand2 ; public : AndExpression ( UniquePtr < BooleanExpression > op1 , UniquePtr < BooleanExpression > op2 ) : operand1 { std :: move ( op1 )}, operand { std :: move ( op2 )} {}virtual ~ AndExpression () = default ;[[ nodiscard ]] virtual bool evaluate ( Context & context ) const { return operand1 -> evaluate ( context ) && operand2 -> evaluate ( context ); }[[ nodiscard ]] virtual UniquePtr < BooleanExpression > replace ( const String & name , BooleanExpression & exp ) const { return std :: make_unique < AndExpression > ( operand1 -> replace ( name , exp ), operand2 -> replace ( name , exp ) ); }[[ nodiscard ]] virtual UniquePtr < BooleanExpression > copy () const { return std :: make_unique < AndExpression > ( operand1 -> copy (), operand2 -> copy ()); }AndExpression ( const AndExpression & ) = delete ; AndExpression & operator = ( const AndExpression & ) = delete ; };int main ( int argc , char * argv []) { UniquePtr < BooleanExpression > expression ; Context context ; UniquePtr < VariableExpression > x = std :: make_unique < VariableExpression > ( "X" ); UniquePtr < VariableExpression > y = std :: make_unique < VariableExpression > ( "Y" ); UniquePtr < BooleanExpression > expression ; = std :: make_unique < AndExpression > ( x , y );contexto.assign ( x.get (), false ) ; contexto.assign ( y.get ( ) , true ) ; bool resultado = expresión- > evaluar ( contexto ) ; std :: println ( "{ } " , resultado ) ;contexto.assign ( x.get ( ), true ) ; contexto.assign ( y.get (), true ) ; resultado = expresión- > evaluar ( contexto ) ; std :: println ( " { } " , resultado ) ; return 0 ; }La salida del programa es:
0 1Véase también
Referencias
- ↑ Gamma, Erich ; Helm, Richard ; Johnson, Ralph; Vlissides, John (1994). Patrones de diseño: Elementos de software orientado a objetos reutilizable . Addison-Wesley. ISBN 0-201-63361-2.
- ↑ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). Patrones de diseño: Elementos de software orientado a objetos reutilizable . Addison Wesley. pp. 243 y ss . ISBN 0-201-63361-2.
{{cite book}}: CS1 maint: varios nombres: lista de autores ( enlace ) - ↑ "El patrón de diseño Intérprete: problema, solución y aplicabilidad" . w3sDesign.com . Consultado el 12 de agosto de 2017 .
- ↑ "El patrón de diseño Intérprete: Estructura y Colaboración" . w3sDesign.com . Consultado el 12 de agosto de 2017 .
Enlaces externos
- patrones de diseño de software