10.05.2013 Views

Algoritmo shunting yard

Algoritmo shunting yard

Algoritmo shunting yard

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Algoritmo</strong> <strong>shunting</strong> <strong>yard</strong><br />

El algoritmo <strong>shunting</strong> <strong>yard</strong> es un método para analizar (parsing) las ecuaciones<br />

matemáticas especificadas en la notación de infijo. Puede ser utilizado para producir la<br />

salida en la notación polaca inversa (RPN) o como árbol de sintaxis abstracta (AST). El<br />

algoritmo fue inventado por Edsger Dijkstra y nombró como algoritmo "<strong>shunting</strong> <strong>yard</strong>"<br />

(patio de clasificación) porque su operación se asemeja al de un patio de clasificación del<br />

ferrocarril.<br />

Como la evaluación del RPN, el algoritmo <strong>shunting</strong> <strong>yard</strong> está basado en el stack. Las<br />

expresiones de infijo son la forma de matemáticas a la que la mayoría de la gente está<br />

acostumbrada, por ejemplo 3+4 ó 3+4*(2-1). Para la conversión hay dos variables de texto<br />

(strings), la entrada y la salida. Hay también un stack que guarda los operadores que<br />

todavía no se han añadido a la cola de salida. Para hacer la conversión, el programa lee<br />

cada símbolo en orden y hace algo basado en ese símbolo.<br />

El algoritmo en detalle<br />

• Mientras haya tokens a ser leídos:<br />

• Lea un token.<br />

• Si el token es un número, entonces agréguelo a la cola de salida.<br />

• Si el token es un token de función, entonces póngalo (push) sobre la pila.<br />

• Si el token es un separador de un argumento de función (ej., una coma):<br />

• Hasta que el token en el tope de la pila sea un paréntesis abierto, retire (pop)<br />

de la pila a los operadores y póngalos en la cola de salida. Si no es<br />

encontrado ningún paréntesis abierto, el separador fue colocado mal o los<br />

paréntesis fueron mal emparejados.<br />

• Si el token es un operador, o1, entonces:<br />

• mientras que haya un operador, o2, en el tope de la pila (esto excluye el<br />

paréntesis abierto), y<br />

o1 es asociativo izquierdo y su precedencia es menor que (una precedencia más<br />

baja) o igual a la de o2, ó<br />

o1 es asociativo derecho y su precedencia es menor que (una precedencia más baja)<br />

que la de o2,<br />

retire (pop) de la pila el o2, y póngalo en la cola de salida;<br />

• ponga (push) o1 en el tope de la pila.


• Si el token es un paréntesis abierto, entonces póngalo en la pila.<br />

• Si el token es un paréntesis derecho:<br />

• Hasta que el token en el tope de la pila sea un paréntesis abierto, retire (pop)<br />

a los operadores de la pila y colóquelos en la cola de salida.<br />

• Retire (pop) el paréntesis abierto de la pila, pero no lo ponga en la cola de<br />

salida.<br />

• Si el token en el tope de la pila es un token de función, póngalo (pop) en la<br />

cola de salida.<br />

• Si la pila se termina sin encontrar un paréntesis abierto, entonces hay<br />

paréntesis sin pareja.<br />

• Cuando no hay más tokens para leer:<br />

• Fin.<br />

• Mientras todavía haya tokens de operadores en la pila:<br />

• Si el token del operador en el tope de la pila es un paréntesis, entonces hay<br />

paréntesis sin la pareja correspondiente.<br />

• retire (pop) al operador y póngalo en la cola de salida.<br />

Para analizar la complejidad de tiempo de ejecución de este algoritmo, uno solo tiene que<br />

notar que cada token será leído solo una vez, cada número, función, u operador será<br />

impreso solo una vez, y cada función, operador o paréntesis será puesto (push) en la pila y<br />

retirado (pop) de la pila solo una sola vez - por lo tanto, hay a lo sumo un número constante<br />

de operaciones ejecutadas por token, y el tiempo de ejecución es así O(n) - lineal al tamaño<br />

de la entrada.<br />

Ejemplo detallado<br />

Entrada: 3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3<br />

Token Acción Salida (en RPN)<br />

3 agrega token a la salida 3<br />

Stack de<br />

operadores<br />

+ Push token al stack 3 +<br />

Notas


4 agrega token a la salida 3 4 +<br />

* Push token al stack 3 4 * + * tiene mayor precedencia que +<br />

2 agrega token a la salida 3 4 2 * +<br />

/<br />

Pop stack a la salida 3 4 2 * + / y * tienen la misma precedencia<br />

Push token al stack 3 4 2 * / + / tiene mayor precedencia que +<br />

( Push token al stack 3 4 2 * ( / +<br />

1 agrega token a la salida 3 4 2 * 1 ( / +<br />

- Push token al stack 3 4 2 * 1 - ( / +<br />

5 agrega token a la salida 3 4 2 * 1 5 - ( / +<br />

)<br />

Pop stack a la salida 3 4 2 * 1 5 - ( / + Repite hasta que sea encontrado "("<br />

Pop stack 3 4 2 * 1 5 - / + Descarta paréntesis emparejados<br />

^ Push token al stack 3 4 2 * 1 5 - ^ / + ^ tiene mayor precedencia que /<br />

2 agrega token a la salida 3 4 2 * 1 5 - 2 ^ / +<br />

^ Push token al stack 3 4 2 * 1 5 - 2 ^ ^ / + ^ es evaluado de derecha a izquierda


3 agrega token a la salida 3 4 2 * 1 5 - 2 3 ^ ^ / +<br />

end Pop todo el stack a la salida 3 4 2 * 1 5 - 2 3 ^ ^ / +

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!