Skip to content

Instantly share code, notes, and snippets.

@ytaki0801
Last active February 10, 2022 16:47
Show Gist options
  • Save ytaki0801/e6587102b7710c97e0728cea7889f7fb to your computer and use it in GitHub Desktop.
Save ytaki0801/e6587102b7710c97e0728cea7889f7fb to your computer and use it in GitHub Desktop.
Parser for simplest S-expression or array-expression of parentheses by using noncanonical 1-character input in POSIX Shell
#!/bin/sh
# One token input function with look-ahead caching
stty -icanon
LF="$(printf \\012)"
get_c1 () {
case "$LH" in ("") GC1R=$(dd bs=1 count=1 2>/dev/null)
;;(*) GC1R="$LH"; LH="" ;;esac
}
skip_spaces () {
get_c1
while [ "$GC1R" = " " ] || [ "$GC1R" = "$LF" ]; do get_c1; done
LH="$GC1R"
}
get_token () {
get_c1; T=""
while : ; do
case "$GC1R" in (" "|"$LF") skip_spaces
case "$T" in ("") get_c1 ;;(*) GTR="$T"; break ;;esac
;;("(") skip_spaces; GTR="("; break
;;(")")
case "$T" in ("") GTR=")" ;;(*) LH=")"; GTR="$T" ;;esac
break
;;(*) T="$T$GC1R"; get_c1 ;;esac
done
}
# Simple S-expression parser
pusht () { eval STACK"$SNUM"="\$1"; SNUM="$((SNUM+1))"; }
popt () { SNUM="$((SNUM-1))"; eval POPTR="\$STACK$SNUM"; }
slist () {
get_token
case "$GTR" in (")") SLISTR=")"
;;("(")
pusht "$GTR"; slist; popt; GTR="$POPTR"; pusht "$SLISTR"
pusht "$GTR"; slist; popt; GTR="$POPTR"; popt
case "$SLISTR" in (")") SLISTR="($POPTR)"
;;(*) SLISTR="($POPTR $SLISTR" ;;esac
;;(*)
pusht "$GTR"; slist; popt;
case "$SLISTR" in (")") SLISTR="$POPTR)"
;;(*) SLISTR="$POPTR $SLISTR" ;;esac
esac
}
sread () {
get_token
case "$GTR" in ("(") slist; SREADR="($SLISTR"
;;(*) SREADR="$GTR" ;;esac
}
LH=""; SNUM=0
sread; printf "\n$SREADR\n"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment