|Portada|Blog|Space|
[Índice] > Mini-expr en awk
Buenas, como hoy no podía dormir, decidí ponerme a resolver uno de los
típicos ejercicios de programación: Un evaluador de expresiones
aritméticas.
He aquí una solución al problema que funciona en gawk y mawk:
echo 81,708+2,2*4/7^3,5*5+2 | awk 'BEGIN{ord[""]=0;ord["+"]=ord["-"]=1
ord["*"]=ord["/"]=2;ord["^"]=3}function top(s){return s[s["c"]]}
function pop(s){if(s["c"])return s[s["c"]--];return""}function push(s,
e){s[++s["c"]]=e}BEGIN{FS="";d=0}{for(i=1;i<=NF+1;i++){if($i~/[0-9]/){
if(d){n+=$i*m;m/=10}else n=n*10+$i}else if($i~/[\.,]/){d=1;m=.1}else{
print n; d=n=0; while(ord[$i]<=ord[top(stack)] && top(stack)!=""){
print pop(stack)}push(stack, $i)}} print "p"}' | awk 'function top(s){
return s[s["c"]]}function pop(s){if(s["c"])return s[s["c"]--];return""}
function push(s,e){s[++s["c"]]=e} /[0-9]/{push(stack, $0)} /p/{
print top(stack)} /\+/{push(stack, pop(stack)+pop(stack))} /-/{x=pop(stack)
y=pop(stack);push(stack, y-x)} /\*/{push(stack, pop(stack)*pop(stack))}
/\//{x=pop(stack);y=pop(stack);push(stack, y/x)} /\^/{x=pop(stack)
y=pop(stack);push(stack, y^x)}'
Y como siempre se quejan de la forma en como sangro el código, es por
eso que decidí dejar como ejercicio al lector el sangrado del mismo.
Lo interesante en este script es que como podrán ver por el | de la
línea 7, el programa se compone de dos scripts de awk. La primer parte
se encarga de convertir la expresión infija en postfija, y la segunda
parte se encarga evaluarla. Como necesitaba una pila en ambos es que
tuve que duplicar las funciones top, push y pop.
Al desarmar el código se puede ver lo simple de su funcionamiento, y
como lenguajes extremadamente sencillos como awk influyen directamente y
en gran medida, sobre la simplicidad de los algoritmos, y permiten
enfocarse en el diseño de los mismos y no en burocracias innecesarias
como la declaración de variables, manejo de punteros u objetos,
o interfaces gráficas.
---------
Los documentos en este sitio se encuentran licenciados bajo la GFDL.
Ver comentarios: [Hay i comentarios]
Para agregar un comentario: agregue a la URL: ?do=show_comment_form (explicación)