Read without ads and support Scribd by becoming a Scribd Premium Reader.
 
 
Cómo crear uncompilador deexpresiones en.NET
 
Alberto Población
 
 
Cómo crear un compilador de expresiones en .NET
Nivel: Intermedio-Avanzado 
 
por
Alberto Población
 En un artículo anterior Alberto nos daba explicaciones acerca de cómo escribir un intérprete
capaz de tomar en tiempo de ejecución una expresión del tipo “5*x
-
3*(x+1)” y evaluarla para
calcular el resultado.En aquel momento comentábamos que el primer paso consistía en elaborar un diagramasintáctico como el de la figura, y luego escribir código para recorrer las distintas ramas delgráfico interpretando sobre la marcha las operaciones encontradas:Una limitación que tiene esa forma de operar
 –
y que ya se comentaba en aquel texto- es queresulta lenta. Si es necesario evaluar la misma función miles de veces, por ejemplo, paradibujar una gráfica punto por punto, entonces se repite miles de veces el seguimiento deldiagrama y la interpretación de las operaciones.
 
 Una posible solución consiste en
“compilar” la expresión
. Se recorre el diagrama, igual que enel caso de la interpretación, pero cada vez que hay que realizar una de las operaciones decálculo, lo que se hace, en lugar de operar sobre la marcha, es generar código ejecutable queimplemente esa operación.Terminado el diagrama, y generado todo el código, las sucesivas ejecuciones se realizanmediante llamadas a dicho ejecutable,
esta vez a toda velocidad
.Para este fin, vamos a utilizar las clases disponibles en el espacio de nombres
System.Reflection.Emit
. Aunque es posible generar un ensamblado dinámico o salvarlo adisco, para la aplicación concreta que tenemos entre manos es preferible utilizar lo que sedenomina un
DynamicMethod
, que viene a ser un método generado dinámicamente enmemoria y que podemos ejecutar sobre la marcha.
La ventaja del método dinámico es que el
Garbage Collector 
es capaz de liberarlo cuando ya no se necesite
, mientras que si se generaun ensamblado, no se descarga de memoria mientras no se descargue el dominio de aplicacióncompleto.Los pasos necesarios para generar el método dinámico son estos:1.
 
Definir un delegado que sirva para apuntar a un método del tipo que queremosgenerar. En nuestro ejemplo utilizaremos el tipo
DelegadoParaEvaluar
que sirvepara apuntar a métodos que reciban como argumento un
double
y devuelvan comoresultado otro
double
.2.
 
Crear una instancia de la clase
DynamicMethod
, pasándole en el constructor elnombre del método y los
Type
de los argumentos y el resultado.3.
 
Llamar al método
GetILGenerator
del
DynamicMethod
para obtener una instanciadel generador de código
IL (“
Intermediate Language
”).
 4.
 
Llamar al método
Emit
del generador cuantas veces sea necesario para ir escribiendoel código de nuestro método dinámico. Esta es la operación que se va realizandorepetidamente cada vez que en el diagrama sintáctico se ve la necesidad de realizaruna operación. Los argumentos de
Emit
indican cuál es la operación concreta que seva a realizar.5.
 
Llamar al método
CreateDelegate
del
DynamicMethod
para obtener un delegado,que el que finalmente se usa para ejecutar el código generado.En el ejemplo de código que se adjunta como
Listado 1
a continuación, hemos reproducido ensu mayor parte el analizador sintáctico
 
que ya introdujimos en el artículo sobre el intérprete,pero
hemos sustituido las rutinas que ejecutaban las operaciones matemáticas
 (
OperacionSuma
,
OperacionResta
, etc.)
por otras equivalentes que generan código
 mediante
Reflection.Emit
.El
Listado 2
muestra la forma de
realizar la llamada para evaluar una expresión
.
Search History:
Searching...
Result 00 of 00
00 results for result for
  • p.
  • More From This User

    Notes
    Load more