Discusión sobre el artículo "Cálculo de expresiones matemáticas (Parte 1). Parsers de descenso recursivo"

 

Artículo publicado Cálculo de expresiones matemáticas (Parte 1). Parsers de descenso recursivo:

En el presente artículo, estudiaremos los principios esenciales del análisis y el cálculo de las expresiones matemáticas. Asimismo, implementaremos los parsers de descenso recursivo que funcionan en los modos de intérprete y de cálculos rápidos basados en un árbol de sintaxis previamente construido.

A la hora de automatizar las tareas comerciales, a veces necesitamos lograr que los algoritmos de cálculo sean flexibles en su estadio de ejecución. Así, por ejemplo, para el ajuste fino de los programas distribuidos en forma cerrada (compilada), podemos organizar la selección del tipo de función objetivo entre un amplio conjunto de combinacioes posibles. En particular, al optimizar el experto o realizar la evaluación rápida del prototipo de un indicador. Entonces, en la ventana de diálogo de propiedades, el usuario tendrá a su disposición no solo los parámetros, sino también la fórmula de cálculo. En estos casos, necesitaremos calcular la expresión matemática según su representación textual, sin cambiar el código MQL del programa.

Para solucionar esta tarea, se utilizan parsers de diferentes tipos, que permiten ejecutar la interpretación de fórmulas sobre la marcha, "compilar" estas en un árbol de sintaxis, generar el llamado código de bytes (secuencia de las instrucciones de cálculo), y ejecutar este posteriormente para calcular el resultado. En el presente artículo, analizaremos varios tipos de parsers y los métodos de cálculo de las expresiones.

Formulando la tarea

Entenderemos por expresión aritmética una secuencia unilateral de elementos de datos, y los operadores que describen las acciones sobre ellos. Como elementos de datos, tendremos números y variables nombradas. Los valores de las variables se podrán asignar y modificar desde el exterior, es decir, no en la propia expresión, sino usando los atributos especiales del analizador. En otras palabras, no habrá un operador de asignación ('=') para almacenar resultados intermedios. La lista de operadores soportados, considerando el orden de prioridad en los cálculos será la siguiente:

  • !, - , + — negación lógica unaria, menos o más
  • () — grupo con ayuda de paréntesis
  • *, /, % — multiplicación, división y división euclidiana
  • +, - — suma y resta
  • >, <, >=, <= — comparación mayor-menor
  • ==, != — comparación igualdad-desigualdad
  • &&, || — Y u O lógico (atención, la prioridad es la misma, se necesitan paréntesis)
  • ?: — operador condicional ternario que permite ramificar los cálculos según las condiciones

Además, permitiremos utilizar en las expresiones las funciones MQL matemáticas estándar, 25 en total. Entre ellas, en particular, tenemos también la función pow, para elevar a una determinada potencia. Por este motivo, en la lista de operadores no existe el operador de potenciación ('^'). Además, el operador '^' permite elevar solo a una potencia entera, mientras que la función no tiene esas limitaciones. Hay también otro matiz que distingue al operador '^' de los otros analizados.

Autor: Stanislav Korotky

Razón de la queja: