05/04/2022
En el vasto y complejo mundo de la computación, la eficiencia es una búsqueda constante. Cada milisegundo cuenta, especialmente cuando se trata de procesar operaciones matemáticas. Es aquí donde entran en juego las notaciones postfijas y prefijas, técnicas ingeniosas que los compiladores emplean para representar cálculos de una manera más simple y, consecuentemente, con un mejor rendimiento en tiempo de ejecución.

Hace algunos años, mientras organizaba viejos archivos de mi universidad, me topé con un proyecto que me trajo gratos recuerdos. Era un programa sencillo, pero fundamental, diseñado para convertir expresiones infijas a postfijas y, finalmente, evaluarlas. Este proyecto, aunque inicialmente solicitado para consola, se convirtió en una aplicación 100% gráfica gracias a mi deseo de ir un paso más allá. Esta experiencia me permitió profundizar en la lógica detrás de cómo las computadoras procesan las matemáticas, un conocimiento invaluable que hoy comparto contigo.
- Entendiendo las Expresiones Infijas: El Punto de Partida
- ¿Qué son las Expresiones Postfijas? La Solución al Problema
- Reglas para la Conversión de Expresiones Infijas a Postfijas
- Evaluación de Expresiones Postfijas: El Paso Final
- ¿Por qué las Expresiones Postfijas son Cruciales para los Compiladores?
- Comparativa: Infijo vs. Postfijo
- Preguntas Frecuentes sobre Expresiones Postfijas
Entendiendo las Expresiones Infijas: El Punto de Partida
Antes de sumergirnos en el corazón de las expresiones postfijas, es crucial entender su contraparte: las expresiones infijas. Estas son la notación que todos utilizamos en nuestro día a día para representar operaciones matemáticas. En las expresiones infijas, los operadores se colocan entre los operandos. Algunos ejemplos comunes incluyen:
10 + 210 / 610 + 12 * 1210 + (1 + 2)
Una característica distintiva de las notaciones infijas es la necesidad de paréntesis para forzar el orden en que se deben realizar las operaciones. Esto se debe a la existencia de la precedencia de operadores. Por ejemplo, en la expresión 1 + 2 * 3, el operador de multiplicación (*) tiene mayor precedencia que el de suma (+). Por lo tanto, 2 * 3 se evaluará primero (resultando en 6), y luego se sumará 1, dando un resultado final de 7.
Sin embargo, si modificamos ligeramente la expresión a (1 + 2) * 3, el resultado cambia drásticamente. Las operaciones dentro de los paréntesis tienen la máxima prioridad, por lo que 1 + 2 se evaluará primero (resultando en 3), y luego ese resultado se multiplicará por 3, obteniendo un 9. Esta dependencia de paréntesis y reglas de precedencia, aunque intuitiva para los humanos, puede complicar el proceso de análisis para una máquina.

¿Qué son las Expresiones Postfijas? La Solución al Problema
Las operaciones postfijas, también conocidas como notación polaca inversa (RPN por sus siglas en inglés), ofrecen una alternativa elegante para representar las mismas operaciones matemáticas, pero abordando el problema de la precedencia de una manera diferente. En estas expresiones, no existen los paréntesis explícitos, y los operadores se colocan después de sus operandos. Observemos cómo se transforman nuestros ejemplos anteriores:
10 + 2⇒10 2 +10 / 6⇒10 6 /10 + 12 * 12⇒10 12 12 * +10 + (1 + 2)⇒10 1 2 + +
La belleza de las expresiones postfijas radica en que la ecuación se evalúa de forma lineal. Los operadores y operandos están ordenados de tal manera que ya no es necesario tener en cuenta la precedencia de los operadores ni el uso de paréntesis. Esto simplifica enormemente el proceso de análisis y ejecución para un compilador, lo que se traduce en una mayor efectividad en tiempo de ejecución.
Reglas para la Conversión de Expresiones Infijas a Postfijas
Como mencionamos, los compiladores suelen realizar la conversión de expresiones infijas a postfijas para optimizar su procesamiento. Para llevar a cabo esta conversión, es fundamental utilizar una estructura de datos conocida como pila (o stack) y seguir un conjunto de reglas específicas. A continuación, detallamos el proceso con un ejemplo paso a paso.
Proceso de Conversión Utilizando una Pila
Las reglas básicas para la conversión son las siguientes:
- Si el elemento es un operando (un número), se añade directamente al resultado.
- Si el elemento es un operador:
- Si la pila está vacía o el operador actual tiene mayor precedencia que el operador en la cima de la pila, se apila.
- Si el operador actual tiene menor o igual precedencia que el operador en la cima de la pila, se desapilan operadores de la pila y se añaden al resultado hasta que se cumpla la condición anterior, y luego se apila el operador actual.
- Si el elemento es un paréntesis izquierdo (
(), se apila. - Si el elemento es un paréntesis derecho (
)), se desapilan operadores de la pila y se añaden al resultado hasta encontrar un paréntesis izquierdo. El paréntesis izquierdo se desapila pero no se añade al resultado. - Al final de la expresión, si la pila no está vacía, se desapilan todos los operadores restantes y se añaden al resultado.
Ejemplo de Conversión: 10 + (1 + 2) * 2
Analicemos la conversión de la expresión 10 + (1 + 2) * 2 a su forma postfija:
Expresión Infija:10 + (1 + 2) * 2
Pila:[]
Resultado:
- Elemento:
10(Operando)
→ Se añade directamente al resultado.
Resultado:10
Pila:[] - Elemento:
+(Operador)
→ Pila vacía, se apila.
Resultado:10
Pila:[+] - Elemento:
((Paréntesis izquierdo)
→ Se apila.
Resultado:10
Pila:[+, (] - Elemento:
1(Operando)
→ Se añade directamente al resultado.
Resultado:10 1
Pila:[+, (] - Elemento:
+(Operador)
→ Precedencia de+es igual a((se considera menor si está dentro de paréntesis o el siguiente es un paréntesis). Se apila.
Resultado:10 1
Pila:[+, (, +] - Elemento:
2(Operando)
→ Se añade directamente al resultado.
Resultado:10 1 2
Pila:[+, (, +] - Elemento:
)(Paréntesis derecho)
→ Se desapilan operadores hasta el paréntesis izquierdo. Se desapila+.
Resultado:10 1 2 +
Pila:[+, (]
→ Se desapila el((no se añade al resultado).
Resultado:10 1 2 +
Pila:[+] - Elemento:
*(Operador)
→ Precedencia de*es mayor que+. Se apila.
Resultado:10 1 2 +
Pila:[+, *] - Elemento:
2(Operando)
→ Se añade directamente al resultado.
Resultado:10 1 2 + 2
Pila:[+, *] - Fin de la expresión.
→ Se desapilan los operadores restantes de la pila.
→ Se desapila*.
Resultado:10 1 2 + 2 *
Pila:[+]
→ Se desapila+.
Resultado:10 1 2 + 2 * +
Pila:[]
Resultado final de la expresión postfija:10 1 2 + 2 * +
Evaluación de Expresiones Postfijas: El Paso Final
Una vez que tenemos la expresión en formato postfijo, el siguiente paso es evaluarla para obtener el resultado numérico. Este proceso también se apoya en una pila y es sorprendentemente sencillo y eficiente.
Proceso de Evaluación Utilizando una Pila
La evaluación lineal de una expresión postfija sigue estos pasos:
- Se recorre la expresión de izquierda a derecha.
- Si se encuentra un operando (un número), se introduce en la pila.
- Si se encuentra un operador, se sacan los dos últimos valores de la pila (el primero que sale es el segundo operando, el segundo que sale es el primer operando), se aplica el operador a estos dos valores, y el resultado de la operación se introduce nuevamente en la pila.
- Al finalizar el recorrido de la expresión, el único valor que quedará en la pila será el resultado final de la expresión.
Ejemplo de Evaluación: 10 1 2 + 2 * +
Utilicemos la expresión postfija que obtuvimos anteriormente: 10 1 2 + 2 * +
Expresión Postfija:10 1 2 + 2 * +
Pila:[]
- Elemento:
10(Operando)
→ Se introduce en la pila.
Pila:[10] - Elemento:
1(Operando)
→ Se introduce en la pila.
Pila:[10, 1] - Elemento:
2(Operando)
→ Se introduce en la pila.
Pila:[10, 1, 2] - Elemento:
+(Operador)
→ Se sacan2y1. Se realiza1 + 2 = 3. Se introduce3en la pila.
Pila:[10, 3] - Elemento:
2(Operando)
→ Se introduce en la pila.
Pila:[10, 3, 2] - Elemento:
*(Operador)
→ Se sacan2y3. Se realiza3 * 2 = 6. Se introduce6en la pila.
Pila:[10, 6] - Elemento:
+(Operador)
→ Se sacan6y10. Se realiza10 + 6 = 16. Se introduce16en la pila.
Pila:[16]
Resultado final de la evaluación:16
¿Por qué las Expresiones Postfijas son Cruciales para los Compiladores?
La adopción de expresiones postfijas en el diseño de compiladores no es casualidad; responde a la necesidad de eficiencia y simplicidad. Al eliminar la ambigüedad de la precedencia de operadores y la necesidad de paréntesis, la evaluación de estas expresiones se vuelve un proceso directo y determinista. Esto significa que un compilador puede procesar y ejecutar operaciones matemáticas de manera mucho más rápida y con menos recursos computacionales.

En un entorno donde el rendimiento es crítico, como en la ejecución de código máquina, transformar una expresión infija compleja en una postfija más simple es una optimización fundamental. Permite a la unidad de procesamiento aritmético-lógica (ALU) de la CPU ejecutar instrucciones en un orden claro y predefinido, sin tener que resolver conflictos de precedencia o navegar por estructuras de árbol complejas. Es, en esencia, la forma en que las computadoras 'piensan' las matemáticas de la manera más eficiente.
Comparativa: Infijo vs. Postfijo
Para consolidar la comprensión, presentamos una tabla comparativa que resume las principales diferencias entre estas dos notaciones:
| Característica | Expresión Infija | Expresión Postfija |
|---|---|---|
| Posición del Operador | Entre los operandos (ej. A + B) | Después de los operandos (ej. A B +) |
| Uso de Paréntesis | Frecuente y necesario para la precedencia | No se utilizan, la posición define el orden |
| Precedencia de Operadores | Requiere reglas de precedencia y asociación | No requiere reglas de precedencia, la evaluación es lineal |
| Complejidad para Humanos | Intuitiva y fácil de leer | Menos intuitiva, requiere práctica |
| Complejidad para Máquinas | Requiere algoritmos complejos (shunting-yard) para análisis | Fácil de analizar y evaluar con una pila |
Ejemplo: (A + B) * C | (A + B) * C | A B + C * |
Preguntas Frecuentes sobre Expresiones Postfijas
¿Cuál es la regla fundamental para las expresiones postfijas?
La regla fundamental es que los operadores se colocan después de sus operandos. Esto elimina la necesidad de paréntesis y reglas de precedencia, permitiendo una evaluación lineal y directa.
¿Qué problema resuelven las expresiones postfijas?
Las expresiones postfijas resuelven el problema de la ambigüedad en la precedencia de operadores y la necesidad de paréntesis en las expresiones infijas. Facilitan la evaluación de expresiones por parte de las máquinas, haciéndola más eficiente y directa.
¿Cómo se evalúa una expresión postfija?
Una expresión postfija se evalúa utilizando una pila. Los operandos se empujan a la pila. Cuando se encuentra un operador, los dos operandos superiores se desapilan, se realiza la operación y el resultado se vuelve a empujar a la pila. El resultado final de la expresión es el único valor que queda en la pila al final.

¿Por qué los compiladores utilizan expresiones postfijas?
Los compiladores utilizan expresiones postfijas porque simplifican el proceso de análisis sintáctico y la generación de código. Al no requerir reglas de precedencia ni el manejo de paréntesis, la evaluación de expresiones se vuelve mucho más eficiente, lo que se traduce en un mejor rendimiento del software.
¿Pueden las expresiones postfijas manejar cualquier tipo de operación matemática?
Sí, las expresiones postfijas pueden representar cualquier operación matemática que pueda ser expresada en notación infija, incluyendo sumas, restas, multiplicaciones, divisiones y operaciones más complejas, siempre que se sigan las reglas de conversión y evaluación adecuadas.
En resumen, las expresiones postfijas son un testimonio de cómo la simplificación de la representación puede llevar a una eficiencia computacional significativa. Aunque no son la forma más intuitiva para los humanos, su lógica subyacente es una piedra angular en el diseño y funcionamiento interno de las calculadoras y los sistemas de computación que usamos a diario.
Si quieres conocer otros artículos parecidos a Expresiones Postfijas: La Lógica de los Compiladores puedes visitar la categoría Cálculos.
