Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.unix.shell > #26531
| From | ram@zedat.fu-berlin.de (Stefan Ram) |
|---|---|
| Newsgroups | comp.unix.shell |
| Subject | Re: handy shell function/alias that wraps bc |
| Date | 2025-10-31 18:21 +0000 |
| Organization | Stefan Ram |
| Message-ID | <parser-20251031191650@ram.dialup.fu-berlin.de> (permalink) |
| References | <10e1l5i$8scp$1@dont-email.me> |
Michael Sanders <porkchop@invalid.foo> wrote or quoted:
># test cases: expression|expected output
Oh man, that takes me back to my old parsers. I just tried
writing one for Bash. It's really just a bare-bones demo though -
everything's integers, the numbers can only have a single digit, and
the power operator only works if both sides are between 0 and 11.
#!/bin/bash
g=""
pos=0
REPLY="" # Used as a global return variable
# xpow: only for args between 0 and 11
xpow() {
local x=$1 y=$2 result=1 i
if [ "$x" -lt 11 ] && [ "$y" -lt 11 ]; then
for i in $(seq 1 $y); do
result=$((result * x))
done
echo "$result"
fi
}
xmul() {
echo $(($1 * $2))
}
xdiv() {
echo $(($1 / $2))
}
xadd() {
echo $(($1 + $2))
}
xsub() {
echo $(($1 - $2))
}
declare -A op_func op_left
op_func["^"]="xpow"; op_left["^"]=0 # right associative
op_func["*"]="xmul"; op_left["*"]=1 # left associative
op_func["/"]="xdiv"; op_left["/"]=1
op_func["+"]="xadd"; op_left["+"]=1
op_func["-"]="xsub"; op_left["-"]=1
lookup() {
local name=$1
if [[ -n ${op_func[$name]} ]]; then
echo "$name ${op_func[$name]} ${op_left[$name]}"
else
echo "0 0 0"
fi
}
peek() {
REPLY="${g:pos:1}"
}
get() {
REPLY="${g:pos:1}"
if [[ -n "$REPLY" ]]; then
pos=$((pos + 1))
fi
}
check() {
local op_chars="$1"
peek
local ch="$REPLY"
if [[ "$op_chars" == *"$ch"* ]]; then
get
else
REPLY=""
fi
}
numeral() {
local ch
get
ch="$REPLY"
REPLY=$((10#$ch - 0))
}
prefix() {
local sign=1
peek
while [[ "$REPLY" == "-" ]]; do
get
sign=$((sign * -1))
peek
done
numeral
REPLY=$((sign * REPLY))
}
parse() {
local op_chars="$1" # $1: op_chars (e.g., "+-")
local next_func="$2" # $2: next_func (e.g., "product")
local result
$next_func
result="$REPLY"
while true; do
local sym
check "$op_chars"
sym="$REPLY"
[[ -z "$sym" ]] && break
local _name func left_assoc
read -r _name func left_assoc <<<"$(lookup "$sym")"
local ll=$left_assoc
local x
if [[ "$ll" -eq 1 ]]; then
$next_func
x="$REPLY"
else
parse "$op_chars" "$next_func"
x="$REPLY"
fi
result=$($func "$result" "$x")
done
REPLY="$result"
}
power() {
parse "^" prefix
}
product() {
parse "*/" power
}
sum() {
parse "+-" product
}
start() {
sum
}
test_expr() {
local s="$1"
g="$s"
pos=0
start
printf "Test '%s' Result: %g\n" "$s" "$REPLY"
}
test_expr "-2"
test_expr "--2"
test_expr "-2*-2"
test_expr "2^3^2"
test_expr "2*2^3^2-1"
test_expr "1+2^3^2/2"
Back to comp.unix.shell | Previous | Next — Previous in thread | Next in thread | Find similar
handy shell function/alias that wraps bc Michael Sanders <porkchop@invalid.foo> - 2025-10-31 06:32 +0000
Re: handy shell function/alias that wraps bc Lawrence D’Oliveiro <ldo@nz.invalid> - 2025-10-31 06:38 +0000
Re: handy shell function/alias that wraps bc gazelle@shell.xmission.com (Kenny McCormack) - 2025-10-31 10:16 +0000
Re: handy shell function/alias that wraps bc Michael Sanders <porkchop@invalid.foo> - 2025-10-31 15:49 +0000
Re: handy shell function/alias that wraps bc Geoff Clare <geoff@clare.See-My-Signature.invalid> - 2025-10-31 13:16 +0000
Re: handy shell function/alias that wraps bc Lawrence D’Oliveiro <ldo@nz.invalid> - 2025-10-31 23:29 +0000
Re: handy shell function/alias that wraps bc Michael Sanders <porkchop@invalid.foo> - 2025-10-31 15:31 +0000
Re: handy shell function/alias that wraps bc Jim <zsd+ng@jdvb.ca> - 2025-11-07 10:09 -0400
Re: handy shell function/alias that wraps bc Lawrence D’Oliveiro <ldo@nz.invalid> - 2025-11-08 00:00 +0000
Re: handy shell function/alias that wraps bc Christian Weisgerber <naddy@mips.inka.de> - 2025-11-08 16:51 +0000
Re: handy shell function/alias that wraps bc Lawrence D’Oliveiro <ldo@nz.invalid> - 2025-11-08 21:55 +0000
Re: handy shell function/alias that wraps bc Jim Diamond <zsd@jdvb.ca> - 2025-11-19 20:37 -0400
Re: handy shell function/alias that wraps bc Brian Patrie <bpatrie@bellsouth.spamisicky.net> - 2025-11-23 14:40 -0600
Re: handy shell function/alias that wraps bc Lawrence D’Oliveiro <ldo@nz.invalid> - 2025-11-23 20:58 +0000
Re: handy shell function/alias that wraps bc Jim Diamond <zsd@jdvb.ca> - 2025-11-24 21:12 -0400
Re: handy shell function/alias that wraps bc Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-10-31 10:38 +0100
Re: handy shell function/alias that wraps bc gazelle@shell.xmission.com (Kenny McCormack) - 2025-10-31 12:39 +0000
Re: handy shell function/alias that wraps bc Kaz Kylheku <643-408-1753@kylheku.com> - 2025-10-31 17:03 +0000
Re: handy shell function/alias that wraps bc Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-10-31 18:14 +0100
Re: handy shell function/alias that wraps bc Richard Harnden <richard.nospam@gmail.invalid> - 2025-11-03 14:03 +0000
Re: handy shell function/alias that wraps bc Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-11-03 15:10 +0100
Re: handy shell function/alias that wraps bc Richard Harnden <richard.nospam@gmail.invalid> - 2025-11-03 14:40 +0000
Re: handy shell function/alias that wraps bc gazelle@shell.xmission.com (Kenny McCormack) - 2025-11-03 16:11 +0000
Re: handy shell function/alias that wraps bc Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-11-03 17:24 +0100
Re: handy shell function/alias that wraps bc gazelle@shell.xmission.com (Kenny McCormack) - 2025-11-03 17:33 +0000
Re: handy shell function/alias that wraps bc Christian Weisgerber <naddy@mips.inka.de> - 2025-11-03 23:19 +0000
Re: handy shell function/alias that wraps bc Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-11-04 05:34 +0100
Re: handy shell function/alias that wraps bc Kaz Kylheku <643-408-1753@kylheku.com> - 2025-11-04 04:40 +0000
Re: handy shell function/alias that wraps bc Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-11-04 05:57 +0100
Re: handy shell function/alias that wraps bc Kaz Kylheku <643-408-1753@kylheku.com> - 2025-11-04 00:35 +0000
Re: handy shell function/alias that wraps bc Kaz Kylheku <643-408-1753@kylheku.com> - 2025-11-04 01:04 +0000
Re: handy shell function/alias that wraps bc Christian Weisgerber <naddy@mips.inka.de> - 2025-11-03 15:56 +0000
Re: handy shell function/alias that wraps bc Lawrence D’Oliveiro <ldo@nz.invalid> - 2025-11-03 20:06 +0000
Re: handy shell function/alias that wraps bc Janis Papanagnou <janis_papanagnou+ng@hotmail.com> - 2025-11-03 21:25 +0100
Re: handy shell function/alias that wraps bc Kaz Kylheku <643-408-1753@kylheku.com> - 2025-11-03 21:11 +0000
Re: handy shell function/alias that wraps bc Michael Sanders <porkchop@invalid.foo> - 2025-10-31 15:53 +0000
Re: handy shell function/alias that wraps bc Christian Weisgerber <naddy@mips.inka.de> - 2025-10-31 14:56 +0000
Re: handy shell function/alias that wraps bc Michael Sanders <porkchop@invalid.foo> - 2025-10-31 15:54 +0000
Re: handy shell function/alias that wraps bc Nuno Silva <nunojsilva@invalid.invalid> - 2025-11-01 10:43 +0000
Re: handy shell function/alias that wraps bc Michael Sanders <porkchop@invalid.foo> - 2025-11-01 12:29 +0000
Re: handy shell function/alias that wraps bc Michael Sanders <porkchop@invalid.foo> - 2025-10-31 17:51 +0000
Re: handy shell function/alias that wraps bc ram@zedat.fu-berlin.de (Stefan Ram) - 2025-10-31 18:21 +0000
Re: handy shell function/alias that wraps bc Michael Sanders <porkchop@invalid.foo> - 2025-10-31 19:15 +0000
Re: handy shell function/alias that wraps bc Ed Morton <mortonspam@gmail.com> - 2025-11-01 11:47 -0500
Re: handy shell function/alias that wraps bc Lawrence D’Oliveiro <ldo@nz.invalid> - 2025-11-01 20:21 +0000
Other languages and people's personal issues (Was: handy shell function/alias that wraps bc) gazelle@shell.xmission.com (Kenny McCormack) - 2025-11-01 21:27 +0000
Re: handy shell function/alias that wraps bc Ed Morton <mortonspam@gmail.com> - 2025-11-02 16:58 -0600
Re: handy shell function/alias that wraps bc Lawrence D’Oliveiro <ldo@nz.invalid> - 2025-11-03 01:53 +0000
Re: handy shell function/alias that wraps bc gazelle@shell.xmission.com (Kenny McCormack) - 2025-11-03 02:39 +0000
Re: handy shell function/alias that wraps bc Ed Morton <mortonspam@gmail.com> - 2025-11-04 16:49 -0600
Re: handy shell function/alias that wraps bc Lawrence D’Oliveiro <ldo@nz.invalid> - 2025-11-05 00:06 +0000
Re: handy shell function/alias that wraps bc Kaz Kylheku <643-408-1753@kylheku.com> - 2025-11-04 23:06 +0000
csiph-web