¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Patrones de diseño en C#
  3. El patrón Interpreter
Extrait - Patrones de diseño en C# Los 23 modelos de diseño: descripción y soluciones ilustradas en UML 2 y C# [2ªedición]
Extractos del libro
Patrones de diseño en C# Los 23 modelos de diseño: descripción y soluciones ilustradas en UML 2 y C# [2ªedición] Volver a la página de compra del libro

El patrón Interpreter

Descripción

El patrón Interpreter proporciona un marco para representar mediante objetos la gramática de un lenguaje con el fin de evaluar, interpretándolas, expresiones escritas en este lenguaje.

Ejemplo

Queremos crear un pequeño motor de búsqueda de vehículos con ayuda de expresiones booleanas según la gramática muy sencilla que se muestra a continuación:

expresión ::= término || palabra-clave || (expresión) 
termino ::= factor 'o' factor 
factor ::= expresión 'y' expresión 
palabra-clave ::= 'a'..'z','A'..'Z' {'a'..'z','A'..'Z'}* 

Los símbolos entre comillas son símbolos terminales. Los símbolos no terminales son expresión, término, factor y palabra-clave. El símbolo de partida es expresión.

Vamos a implementar el patrón Interpreter para poder expresar cualquier expresión que responda a esta gramática según un árbol sintáctico constituido por objetos con el objetivo de poder evaluarla e interpretarla.

Tal árbol está constituido únicamente por símbolos terminales. Para simplificar, consideramos que una palabra-clave constituye un símbolo terminal en tanto que es una cadena de caracteres.

La expresión (rojo o gris) y reciente y diesel se representa en el árbol sintáctico de la figura 4-4.1.

images/fig201.PNG

Figura 4-4.1 - Árbol sintáctico correspondiente a la expresión (rojo o gris) y reciente y diesel

La evaluación de tal árbol...

Estructura

1. Diagrama de clases

La figura 4-4.3 describe la estructura genérica del patrón.

Este diagrama de clases muestra que existen dos tipos de sub-expresiones, a saber:

  • los elementos terminales que pueden ser nombres de variables, enteros, nombres reales;

  • los operadores que pueden ser binarios como en el ejemplo, unarios (operador « - ») o que tomen más argumentos como las funciones.

images/figure20-3.png

Figura 4-4.3 - Estructura del patrón Interpreter

2. Participantes

Los participantes del patrón son los siguientes:

  • Expresión es una clase abstracta que representa cualquier tipo de expresión, es decir cualquier nodo del árbol sintáctico.

  • OperadorAbstracto (OperadorBinario) es también una clase abstracta. Describe cualquier nodo de tipo operador, es decir que posea operandos que son subárboles del árbol sintáctico.

  • OperadorConcreto1 y OperadorConcreto2 (OperadorY, OperadorO) son implementaciones del OperadorAbstracto que describen completamente la semántica del operador y por tanto son capaces de evaluarlo.

  • ElementoTerminal es una clase abstracta que describe cualquier nodo correspondiente a un elemento terminal.

  • ElementoTerminalConcreto1 y ElementoTerminalConcreto2 (PalabraClave) son clases concretas que corresponden con un elemento terminal, capaces de evaluar este elemento.

3. Colaboraciones

El cliente construye una expresión bajo la forma de un árbol sintáctico...

Dominios de aplicación

El patrón se utiliza para interpretar expresiones representadas bajo la forma de árboles sintácticos. Se aplica principalmente en los siguientes casos:

  • La gramática de las expresiones es simple.

  • La evaluación no necesita ser rápida.

Si la gramática es compleja, es preferible utilizar analizadores sintácticos especializados. Si la evaluación debe realizarse rápidamente, puede resultar necesario el uso de un compilador.

Ejemplo en C#

A continuación se muestra el código completo de un ejemplo escrito en C# que no sólo permite evaluar un árbol sintáctico sino que también lo construye.

La construcción del árbol sintáctico, llamado análisis sintáctico, también está repartida en las clases, a saber las de la figura 4-4.2 bajo la forma de métodos de clase (métodos precedidos por la palabra reservada static en C#).

El código fuente de la clase Expresion aparece a continuación. La parte relativa a la evaluación se limita a la declaración de la firma del método evalua.

Los métodos siguientePieza, analiza y parsea están dedicados al análisis sintáctico. El método analiza se utiliza para parsear una expresión entera mientras que parsea está dedicado al análisis bien de una palabra-clave o bien de una expresión escrita entre paréntesis.

using System; 
 
public abstract class Expresion 
{ 
    public abstract bool evalua(string descripcion); 
 
    // parte análisis sintáctico 
    protected static string fuente; 
    protected static int indice; 
    protected static string pieza; 
 
    protected static void siguientePieza() 
    { 
        while ((indice < fuente.Length) && (fuente[indice] == 
        ' ')) 
            indice++; 
        if (indice == fuente.Length) 
            pieza = null; 
        else if ((fuente[indice] == '(') || (fuente[indice] == 
        ')')) 
        { 
            pieza = fuente.Substring(indice, 1); 
            indice++; 
        } ...