Task

Create a stack-based evaluator for an expression in   reverse Polish notation (RPN)   that also shows the changes in the stack as each individual token is processed as a table.



 Assume an input of a correct, space separated, string of tokens of an RPN expression
 Test with the RPN expression generated from the   Parsing/Shunting-yard algorithm   task: 

         3 4 2 * 1 5 - 2 3 ^ ^ / + 

 Print or display the output here


Notes

    ^    means exponentiation in the expression above.
    /    means division.


See also

   Parsing/Shunting-yard algorithm for a method of generating an RPN from an infix expression.
   Several solutions to 24 game/Solve make use of RPN evaluators (although tracing how they work is not a part of that task).
   Parsing/RPN to infix conversion.
   Arithmetic evaluation.


#!/bin/sh
 
exp() {
    R=1
    local i=1
 
    while [ $i -le $2 ]; do
        R=$(($R * $1))
        i=$(($i + 1))
    done
}
 
rpn() {
    local O1 O2 stack
 
    while [ $# -ge 1 ]; do
        grep -iE '^-?[0-9]+$' <<< "$1" > /dev/null 2>&1
        if [ "$?" -eq 0 ]; then
            stack=`sed -e '$a'"$1" -e '/^$/d' <<< "$stack"`
        else
            grep -iE '^[-\+\*\/\%\^]$' <<< "$1" > /dev/null 2>&1
            if [ "$?" -eq 0 ]; then
                O2=`sed -n '$p' <<< "$stack"`
                stack=`sed '$d' <<< "$stack"`
                O1=`sed -n '$p' <<< "$stack"`
 
                case "$1" in
                    '+')
                        stack=`sed -e '$a'"$(($O1 + $O2))" -e '/^$/d' -e '$d' \
                            <<< "$stack"`;;
                    '-')
                        stack=`sed -e '$a'"$(($O1 - $O2))" -e '/^$/d' -e '$d' \
                            <<< "$stack"`;;
                    '*')
                        stack=`sed -e '$a'"$(($O1 * $O2))" -e '/^$/d' -e '$d' \
                            <<< "$stack"`;;
                    '/')
                        stack=`sed -e '$a'"$(($O1 / $O2))" -e '/^$/d' -e '$d' \
                            <<< "$stack"`;;
                    '%')
                        stack=`sed -e '$a'"$(($O1 % $O2))" -e '/^$/d' -e '$d' \
                            <<< "$stack"`;;
                    '^')
                        exp $O1 $O2
                        stack=`sed -e '$a'"$(($R))" -e '/^$/d' -e '$d' <<< \
                            "$stack"`;;
                esac
            else
                echo "Unknown RPN token \`\`$1''"
            fi
        fi
        echo "$1" ":" $stack
        shift
    done
 
    sed -n '1p' <<< "$stack"
    if [ "`wc -l <<< "$stack"`" -gt 1 ]; then
        echo "Malformed input expression" > /dev/stderr
        return 1
    else
        return 0
    fi
}
 
rpn 3 4 2 '*' 1 5 '-' 2 3 '^' '^' '/' '+'