104 lines
2.7 KiB
Bash
104 lines
2.7 KiB
Bash
#!/bin/sh
|
|
|
|
getopprec() {
|
|
case "$1" in
|
|
'+') echo 2;;
|
|
'-') echo 2;;
|
|
'*') echo 3;;
|
|
'/') echo 4;;
|
|
'%') echo 4;;
|
|
'^') echo 4;;
|
|
'(') echo 5;;
|
|
esac
|
|
}
|
|
|
|
getopassoc() {
|
|
case "$1" in
|
|
'^') echo r;;
|
|
*) echo l;;
|
|
esac
|
|
}
|
|
|
|
showstacks() {
|
|
[ -n "$1" ] && echo "Token: $1" || echo "End parsing"
|
|
echo -e "\tOutput: `tr $'\n' ' ' <<< "$out"`"
|
|
echo -e "\tOperators: `tr $'\n' ' ' <<< "$ops"`"
|
|
}
|
|
|
|
infix() {
|
|
local out="" ops=""
|
|
|
|
while [ "$#" -gt 0 ]; do
|
|
grep -qE '^[0-9]+$' <<< "$1"
|
|
if [ "$?" -eq 0 ]; then
|
|
out="`sed -e '$a'"$1" -e '/^$/d' <<< "$out"`"
|
|
|
|
showstacks "$1"
|
|
shift && continue
|
|
fi
|
|
|
|
grep -q '^[-+*/^%]$' <<< "$1"
|
|
if [ "$?" -eq 0 ]; then
|
|
if [ -n "$ops" ]; then
|
|
thispred=`getopprec "$1"`
|
|
thisassoc=`getopassoc "$1"`
|
|
topop="`sed -n '$p' <<< "$ops"`"
|
|
thatpred=`getopprec "$topop"`
|
|
thatassoc=`getopassoc "$topop"`
|
|
while [ $thatpred -gt $thispred ] 2> /dev/null || ( [ \
|
|
$thatpred -eq $thispred ] 2> /dev/null && [ $thisassoc = \
|
|
'l' ] 2> /dev/null ); do # To /dev/null 'cus u r fake news
|
|
|
|
[ "$topop" = '(' ] && break
|
|
|
|
op="`sed -n '$p' <<< "$ops"`"
|
|
out="`sed -e '$a'"$op" -e '/^$/d' <<< "$out"`"
|
|
ops="`sed '$d' <<< "$ops"`"
|
|
|
|
topop="`sed -n '$p' <<< "$ops"`"
|
|
thatpred=`getopprec "$topop"`
|
|
thatassoc=`getopassoc "$topop"`
|
|
done
|
|
fi
|
|
ops="`sed -e '$a'"$1" -e '/^$/d' <<< "$ops"`"
|
|
|
|
showstacks "$1"
|
|
shift && continue
|
|
fi
|
|
|
|
if [ "$1" = '(' ]; then
|
|
ops="`sed -e '$a'"$1" -e '/^$/d' <<< "$ops"`"
|
|
|
|
showstacks "$1"
|
|
shift && continue
|
|
fi
|
|
|
|
if [ "$1" = ')' ]; then
|
|
grep -q '^($' <<< "`sed -n '$p' <<< "$ops"`"
|
|
while [ "$?" -ne 0 ]; do
|
|
op="`sed -n '$p' <<< "$ops"`"
|
|
out="`sed -e '$a'"$op" -e '/^$/d' <<< "$out"`"
|
|
ops="`sed '$d' <<< "$ops"`"
|
|
|
|
grep -q '^($' <<< "`sed '$p' <<< "$ops"`"
|
|
done
|
|
ops="`sed '$d' <<< "$ops"`"
|
|
|
|
showstacks "$1"
|
|
shift && continue
|
|
fi
|
|
|
|
shift
|
|
done
|
|
|
|
while [ -n "$ops" ]; do
|
|
op="`sed -n '$p' <<< "$ops"`"
|
|
out="`sed -e '$a'"$op" -e '/^$/d' <<< "$out"`"
|
|
ops="`sed '$d' <<< "$ops"`"
|
|
done
|
|
|
|
showstacks "$1"
|
|
}
|
|
|
|
infix 3 + 4 \* 2 / \( 1 - 5 \) ^ 2 ^ 3
|