¿Cómo hacer un intérprete de ecuaciones matemáticas en QuickBASIC? Parte 2

¿Cómo hacer un intérprete de ecuaciones matemáticas en QuickBASIC? Parte 2


Imagen generada usando Bing Image Creator


Para ver la primera parte de este artículo puedes usar este enlace: Parte 1


Introducción

En la pasada entrega de este tutorial comenté su intención, como su título indica esta consiste en elaborar un intérprete de ecuaciones matemáticas usando QuickBASIC 4.5; dicho intérprete podría servirnos después para hacer una calculadora capaz de resolver ecuaciones matemáticas introducidas por el usuario en un entorno MS-DOS.

Por lo pronto nos limitamos a mencionar el software a utilizar en el desarrollo del intérprete y a comentar sobre algún asunto más relacionado con la teoría, sin embargo, nos faltó hablar en más detalles de la gramática de las expresiones matemáticas si bien mencionamos algo sobre la importancia de tenerla presente.

En esta parte del artículo vamos a empezar a abordar lo relacionado con esto último, y definir la gramática de las expresiones matemáticas; como veremos después esta gramática es fácilmente traducida a código en un lenguaje de programación capaz de reconocer e interpretar ecuaciones matemáticas válidas.


La representación general de la gramática de las expresiones matemáticas

Por ahora sabemos como la notación comúnmente usada para expresar o describir una gramática de un lenguaje de programación es conocida como BNF (Backus-Naur Form), debido a los nombres de los autores de dicha notación como hemos visto nombrados John W. Backus y Peter Naur.

La gramática de una expresión matemática es un subconjunto de la gramática de un lenguaje de programación, como mismo una expresión matemática es un subconjunto de un lenguaje de programación más general, y con ella se describen todos los elementos de una expresión matemática y los símbolos válidos por medio de los cuales se los representa.

La línea a continuación puede ser un buen comienzo para empezar a definir en BNF cómo está compuesta una expresión matemática válida.

<expression> ::= <term> [<add_op> <term>]*

La notación antes expuesta nos revela como una expresión matemática no es nada más que un término, opcionalmente (los corchetes significan opcional) seguido de otros términos (un "*" significa cero o más), relacionados entre sí por medio de un operador, en este caso un operador de suma o de resta ("+" o "-").

Pero como se darán cuenta, ahora nos encontramos con otra incógnita.


¿Qué es un término?

La notación para describir un término de una expresión matemática es como sigue:

<term> ::= <factor> [<mul_op> <factor>]*

La línea antes expuesta define cómo está compuesto un término, o sea, un término es un factor, una vez más seguido opcionalmente por cero o más factores.

En cambio, esta vez los factores están relacionados por un operador para la multiplicación o la división ("*" o "/").

Nota: En este texto no tratamos un operador de elevación a potencia puesto eso será hecho por medio de una función y por eso no lo incluiremos en la gramática.


¿Qué es un factor?

Por fin, en su definición más simple, un factor a su vez podría ser una expresión completa delimitada por paréntesis como en:

<factor> ::= (<expression>)

La última línea mostrada nos da una idea de la naturaleza recursiva de una expresión matemática, puesto esta se compone de términos, a su vez compuestos de factores, a su vez compuestos por una expresión entre paréntesis, y con esto seguro se han llevado por lo menos una idea.

Pero debemos tener en cuenta algo más, un factor no se limita a esto, también podría ser un elemento más simple, como un número, o una variable, entre otras cosas más, por lo cual una definición más completa de factor sería (el símbolo barra vertical "|" se utiliza como un operador lógico OR):

<factor> ::= <number> | (<expression>) | <variable>

En todo caso, como seguro se habrán dado cuenta, la definición de factor expuesta arriba también sigue siendo básica, porque un factor también podría ser una llamada a una función, una constante, etc., y todavía deberíamos seguir definiendo número, variable, puesto todos ellos son elementos compuestos por símbolos y el analizador lexicográfico tiene la necesidad de toda esa información para poder identificarlos o reconocerlos de modo correcto.

Nota: Las constantes no se tuvieron en cuenta porque como se comentó antes vamos a representarlas como variables.

En realidad en lugar de variable en ese lugar podría ir identifier, símbolo más general para incluir tanto una variable como una constante, o una palabra reservada del lenguaje (no necesario en un intérprete de ecuaciones matemáticas). En este caso una función también sería un identificador seguido de unos paréntesis "(" y ")" dentro de los cuales se definen los parámetros de esta. En nuestro intérprete reconoceremos una función más bien buscando en una tabla de símbolos, como se hace para reconocer palabras reservadas, con lo cual podremos decidir si un identificador es una variable o un nombre de función puesto todas las funciones serán predefinidas o intrínsecas.

La definición más general de un factor sería como sigue:

<factor> ::= <number> | (<expression>) | <identifier> | <function> | <signed_factor>

En otras palabras, un factor puede estar compuesto por un número, o una expresión entre paréntesis, o un identificador (variable o constante), o una función la cual también es un identificador mas terminado por unos paréntesis, y por último podría ser otro factor con signo positivo o negativo.


La gramática de una expresión matemática

En resumen, con lo expuesto hasta este momento, la gramática básica para una expresión matemática usada por nuestro intérprete de ecuaciones matemáticas será como sigue:

<expression> ::= <term> [<add_op> <term>]*
<term> ::= <factor> [<mul_op> <factor>]*
<factor> ::= <number> | (<expression>) | <identifier> | <function> | <signed_factor>

En esta representación nos falta todavía especificar muchos detalles, y eso lo veremos en la siguiente parte del tutorial, donde terminaremos de definir la gramática, y una vez hecho esto, podremos pasar a ver la definición de un analizador lexicográfico, la parte de un intérprete o compilador encargada de reconocer los distintos símbolos válidos y los tokens o lexemas conformados con ellos, y exponer cómo podemos implementarlo usando QuickBASIC.


¿Qué te ha parecido esta segunda parte?

Tú participación aportando ideas, dando sugerencias, o expresando tu crítica constructiva a través de tus comentarios, es importante y fundamental para permitirnos crecer y crear contenidos con cada vez más calidad.

También es importante tu voto si crees vale la pena concederlo.

¡Nos vemos en la siguiente parte de este artículo tutorial!



0
0
0.000
0 comments