Académique Documents
Professionnel Documents
Culture Documents
compilador de
expresiones 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.
Una limitación que tiene esa forma de operar –y que ya se comentaba en aquel texto- es que
resulta lenta. Si es necesario evaluar la misma función miles de veces, por ejemplo, para
dibujar una gráfica punto por punto, entonces se repite miles de veces el seguimiento del
diagrama y la interpretación de las operaciones.
Una posible solución consiste en “compilar” la expresión. Se recorre el diagrama, igual que en
el caso de la interpretación, pero cada vez que hay que realizar una de las operaciones de
cálculo, lo que se hace, en lugar de operar sobre la marcha, es generar código ejecutable que
implemente esa operación.
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 a
disco, para la aplicación concreta que tenemos entre manos es preferible utilizar lo que se
denomina un DynamicMethod, que viene a ser un método generado dinámicamente en
memoria 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 genera
un ensamblado, no se descarga de memoria mientras no se descargue el dominio de aplicación
completo.
1. Definir un delegado que sirva para apuntar a un método del tipo que queremos
generar. En nuestro ejemplo utilizaremos el tipo DelegadoParaEvaluar que sirve
para apuntar a métodos que reciban como argumento un double y devuelvan como
resultado otro double.
4. Llamar al método Emit del generador cuantas veces sea necesario para ir escribiendo
el código de nuestro método dinámico. Esta es la operación que se va realizando
repetidamente cada vez que en el diagrama sintáctico se ve la necesidad de realizar
una operación. Los argumentos de Emit indican cuál es la operación concreta que se
va a realizar.
ultimoSimbolo = ObtenerSiguienteSímbolo();
Expresion();
il.Emit(OpCodes.Ret);
Evaluar = (DelegadoParaEvaluar)evaluador.CreateDelegate(
typeof(DelegadoParaEvaluar));
}
enum Simbolos
{
Ninguno,
Suma, Resta, Multiplicación, División,
AbrirParéntesis, CerrarParéntesis,
Constante, Variable,
FinDeLaExpresión
}
Listado 2
//Se ejecuta una vez, creando el método dinámico
string expresion = "5*x-3*(x+1) ";
Compilador comp = new Compilador(expresion);
Acerca de campusMVP
CampusMVP te ofrece la mejor formación en tecnología Microsoft a través de nuestros cursos online y
nuestros libros especializados, impartidos y escritos por conocidos MVP de Microsoft. Visita nuestra
página y prueba nuestros cursos y libros gratuitamente. www-campusmvp.com