Skip to content

Instantly share code, notes, and snippets.

@alganet
Created June 29, 2025 14:39
Show Gist options
  • Save alganet/23df53c567b8a0bf959ecbc7b68997c0 to your computer and use it in GitHub Desktop.
Save alganet/23df53c567b8a0bf959ecbc7b68997c0 to your computer and use it in GitHub Desktop.
Prototype sh parser written in sh
# Copyright (c) Alexandre Gomes Gaigalas <[email protected]>
# SPDX-License-Identifier: ISC
_repeat () {
case "${2:-}" in
0|"") return;;
1) REPLY="$1"; return;;
2) REPLY="$1$1"; return;;
3) REPLY="$1$1$1"; return;;
4) REPLY="$1$1$1$1"; return;;
esac
local VALUE="$1" COUNT="$2" POW=2; REPLY=
while :
do
if test $POW -gt $COUNT
then
test $COUNT -gt 0 || break
REPLY="$REPLY$VALUE" VALUE="$1" COUNT=$((COUNT - (POW / 2))) POW=2
continue
fi
VALUE="$VALUE$VALUE" POW=$((POW * 2))
done
}
_questn () {
eval "case \${_questn$1:-} in \"\") _repeat \\? $1; _questn$1=\$REPLY;; esac; REPLY=\$_questn$1";
}
alias SINPUTFEED='
if test ${#CODE} -lt 16 -a $# -gt 0
then
_a= _b=
while test ${#1} -gt 256
do
_questn $((${#1} / 2));
_b="${1#${REPLY}}"; _a="${1%$_b}"; shift
set -- "$_a" "$_b" "${@:-}"
done
CODE="$CODE$1"
shift
fi'
alias SINPUTMORE='
if test ${#CODE} -lt 256 -a $# -gt 0
then
_a= _b=
while test ${#1} -gt 256
do
_questn $((${#1} / 2));
_b="${1#${REPLY}}"; _a="${1%$_b}"; shift
set -- "$_a" "$_b" "${@:-}"
done
CODE="$CODE$1"
shift
fi'
alias CONSUME='REST="${CODE#?}"; CONSUMED="$CONSUMED${CODE%"$REST"}"; CODE="$REST"'
alias CONSUME2='REST="${CODE#??}"; CONSUMED="$CONSUMED${CODE%"$REST"}"; CODE="$REST"'
alias CONSUME3='REST="${CODE#???}"; CONSUMED="$CONSUMED${CODE%"$REST"}"; CODE="$REST"'
alias CONSUME4='REST="${CODE#????}"; CONSUMED="$CONSUMED${CODE%"$REST"}"; CODE="$REST"'
alias IGNORE='CODE="${CODE#?}"'
alias IGNORE2='CODE="${CODE#??}"'
alias IGNORE_WS='CODE="${CODE#"${CODE%%[!$_TAB\ ]*}"}"'
alias IGNORE_WSE='CODE="${CODE#"${CODE%%[!$_TAB$_EOL\ ]*}"}"'
alias SNEW='
STATES="$STATES $STATE"; V=$((V + 1))
case "$CONSUMED" in "");; *) local V$V="$CONSUMED";;esac
CONSUMED='
alias SOPEN='
local X$V$STATE=""
PARN="${NODES##*" "}"
NODE="X$V$STATE"; NODES="$NODES $NODE"'
alias SDOWN='
STATE="${STATES##*" "}"; STATES="${STATES%" ${STATE}"}"
eval local V$V=\"\${CONSUMED:-\${V$V:-}}\"
PARN="${NODES##*" "}"
NODE="$PARN"; NODES="${NODES%" $NODE"}"; PARN="${NODES##*" "}"'
alias SDISC='SDOWN;unset $NODE'
alias SCLOSE='SDOWN;eval "$PARN=\"\$$PARN \$NODE\""'
alias SCLOSRNE='SCLOSE; eval "eval \"case \\$\${$NODE#?}\" in \\\"\\\"\) _error $E \;\; esac; E=;"'
alias SCLOSOP='
SDOWN
eval "case \${$PARN##*" "} in X*) SIBL=\"\${$PARN##*" "}\";; *)SIBL=;;esac"
case $SIBL in
*BP) eval "$PARN=\"\${$PARN%\" \$SIBL\"}\" $SIBL=\"\${$PARN##*\" \"} \$NODE\" $PARN=\"\${$PARN%\" \"*} \$SIBL\"";;
*UP) eval "$PARN=\"\${$PARN%\" \$SIBL\"}\" $SIBL=\"\$NODE\" $PARN=\"\${$PARN%\" \"*} \$SIBL\"";;
*) eval "$PARN=\"\$$PARN \$NODE\"";;
esac'
xxx () {
local CODE= STATE=prog I=0 V=0 CONSUMED= NODES=" X0prog" X0prog='' X=0 NODE= REST= PARN= SIBL= E= _a= _b= STATES=
# set -- "! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;"
# set -- "! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;! foo; zaaa | baz b a c ||$_EOL lo_greatest_name_bar_that_has_ever_been_hooooohaaaaa=a thequickbrownfox && lazydog > foo 2>&1;"
# set -- "{ true;};2>&1"
set -- "foo && bar"
while : $CONSUMED -- x$CODE -- $STATE -- $I
do
SINPUTFEED
case $CODE in
'&&'* | '||'*)
case $STATE in
full) SNEW;STATE=logicBP;SOPEN;CONSUME2;;
stmt|exec|cmd) SCLOSOP;;
arg|word) SCLOSE;;
*) _error LOGIC;;esac;;
'!'*)
case $STATE in
stmt) SNEW;STATE=bangUP;SOPEN;IGNORE;CONSUMED=\!;;
arg) SNEW;STATE=word;SOPEN;IGNORE;CONSUMED=\!;;
bangUP) IGNORE;CONSUMED=\!;;
prog) SNEW;STATE=full;SOPEN;;
full) SNEW;STATE=stmt;SOPEN;;
cmd) SNEW;STATE=arg;SOPEN;;
exec) SCLOSOP;;
logicBP) SCLOSE;;
*) _error BANG;;esac;;
'|'*)
case $STATE in
exec) SNEW;STATE=pipeBP;SOPEN;IGNORE;CONSUMED=\|;;
cpatt)
IGNORE;SCLOSE;SNEW;STATE=cpatt;SOPEN;;
cmd) SCLOSOP;;
arg|word) SCLOSE;;
*) _error PIPE;;esac;;
"$_EOL"*)
case $STATE in
logicBP|pipeBP|prog) IGNORE_WSE;;
fredir) E=FREDIR; SCLOSRNE;;
full) SCLOSE;;
stmt|exec) SCLOSOP;;
cmd) SCLOSOP;CONSUMED=;;
cmdpre|blockpos|arg|word) SCLOSE;CONSUMED=;;
commt) SCLOSE;;
*) _error END OF LINE;;esac;;
';'*)
case $STATE in
full) SCLOSE;IGNORE;CONSUMED=;;
ccasepatt) SCLOSE;SCLOSE;IGNORE;;
prog)
SCLOSE
case $PARN in *ccaseitem) SCLOSE;SCLOSE;IGNORE;;esac
;;
fredir) E=FREDIR; SCLOSRNE;;
stmt|exec|cmd) SCLOSOP;;
cmdpre|blockpos|arg|word) SCLOSE;;
*) _error SEMICOLON;;esac;;
"")
case $STATE in
prog) break;;
fredir) E=FREDIR; SCLOSRNE;;
stmt|exec|cmd) SCLOSOP;;
blockpos|full|cmdpre|vassig|cmd|arg|word|commt) SCLOSE;;
logicBP) _error END LOGIC;;
pipeBP) _error END PIPE;;
*) _error END OF SCRIPT;;esac;;
' '*|"$_TAB"*)
case $STATE in
ccase|fdecl|blockpos|vassig|cmdpre|cmd|stmt|prog) IGNORE_WS;;
exec|bangUP|logicBP|pipeBP) IGNORE_WSE;;
fredir) E=FREDIR; SCLOSRNE;;
arg|word|expan) SCLOSE;CONSUMED=;;
text) CONSUME;;
dquo)
_error $STATE;;
commt)
CONSUME;;
*) _error ARGUMENT;;esac;;
[0-9]'>&'[0-9]*)
case $STATE in
blockpos|cmdpre|cmd) SNEW;STATE=ioredir;SOPEN;CONSUME4;SCLOSE;;
prog) SNEW;STATE=full;SOPEN;;
full) SNEW;STATE=stmt;SOPEN;;
stmt) SNEW;STATE=exec;SOPEN;;
exec) SNEW;STATE=cmd;SOPEN;STATE=cmdpre;;
vassig|arg|word) SCLOSE;;
*) _error IOREDIR;;esac;;
'>&'[0-9]*)
case $STATE in
blockpos|cmdpre|cmd) SNEW;STATE=ioredir;SOPEN;CONSUME3;SCLOSE;;
prog) SNEW;STATE=full;SOPEN;;
full) SNEW;STATE=stmt;SOPEN;;
stmt) SNEW;STATE=exec;SOPEN;;
exec) SNEW;STATE=cmd;SOPEN;STATE=cmdpre;;
vassig|arg|word) SCLOSE;;
*) _error IOREDIR;;esac;;
[0-9]'>'*)
case $STATE in
blockpos|cmdpre|cmd) SNEW;STATE=fredir;SOPEN;CONSUME2;IGNORE_WS;SNEW;STATE=arg;SOPEN;;
prog) SNEW;STATE=full;SOPEN;;
full) SNEW;STATE=stmt;SOPEN;;
stmt) SNEW;STATE=exec;SOPEN;;
exec) SNEW;STATE=cmd;SOPEN;STATE=cmdpre;;
vassig|arg|word) SCLOSE;;
*) _error FREDIR;;esac;;
'>'*)
case $STATE in
blockpos|cmdpre|cmd) SNEW;STATE=fredir;SOPEN;CONSUME;IGNORE_WS;SNEW;STATE=arg;SOPEN;;
prog) SNEW;STATE=full;SOPEN;;
full) SNEW;STATE=stmt;SOPEN;;
stmt) SNEW;STATE=exec;SOPEN;;
exec) SNEW;STATE=cmd;SOPEN;STATE=cmdpre;;
vassig|arg|word) SCLOSE;;
*) _error FREDIR;;esac;;
"{ "* | "{$_TAB"* | "{$_EOL"*)
case $STATE in
exec) SNEW;STATE=cmd;SOPEN;SNEW;STATE=block;SOPEN;IGNORE2;SNEW;STATE=prog;SOPEN;;
fdecl) SNEW;STATE=block;SOPEN;IGNORE2;SNEW;STATE=prog;SOPEN;;
prog) SNEW;STATE=full;SOPEN;;
full) SNEW;STATE=stmt;SOPEN;;
stmt) SNEW;STATE=exec;SOPEN;;
word) CONSUME;;
esac;;
'}'*)
case $STATE in
prog)
SCLOSE
case $PARN in *block);; *) _error AJDNKAJND;;esac
IGNORE;SCLOSE;STATE=blockpos
case $CODE in
"$_EOL"* | "$_TAB"* | ' '*);;
""|';'*);;
*) _error BLOCK CLOSING;;
esac
;;
expan|vsubst) SCLOSE; IGNORE;;
cmd|exec|arg|word) SCLOSE;;
stmt) _error BLOCK CLOSING;;
word) CONSUME;;
*) _error brclos;;esac;;
# escapes
# &
# until
# comments DONE
# subshell DONE
# dquotesub DONE
# expansions DONE (:- :+ %% ## # %)
# dquote PARTIAL (dquotesub, escapes)
# squote (mostly) DONE (improve chars)
# case -- (mostly) DONE (improve errors)
# for ------ (mostly) DONE (improve in)
# while --- DONE
# if --- DONE
')'*)
case $STATE in
word|arg|cmd|exec|stmt|full) SCLOSE;;
prog)
SCLOSE
case $PARN in
*dquotesub)
IGNORE;SCLOSE;CONSUMED=
case $PARN in
*dquo) SNEW;STATE=text;SOPEN;;
*arg) SCLOSE;;
*) _error $PARN AJDNKAJaaaND;;
esac;;
*subsh)
IGNORE;SCLOSE;CONSUMED=
case $PARN in
*arg) SCLOSE;;
*) _error $PARN ---AJDNKAJaaaND;;
esac;;
*) _error AJDNKAJND;;
esac
;;
cpatt) SCLOSE;IGNORE;
SNEW;STATE=prog;SOPEN;;
cpatt) IGNORE;SCLOSE;;
*) _error CASE ITEMx;;esac;;
"'"*)
case $STATE in
cmd) SNEW;STATE=arg;SOPEN;SNEW;STATE=squo;SOPEN;SNEW;STATE=text;SOPEN;IGNORE;;
squo) SCLOSE;IGNORE;;
text) SCLOSE;;
*) _error squo $STATE;;esac;;
'"'*)
case $STATE in
cmd) SNEW;STATE=arg;SOPEN;SNEW;STATE=dquo;SOPEN;SNEW;STATE=text;SOPEN;IGNORE;;
dquo) SCLOSE;IGNORE;;
text) SCLOSE;;
*) _error dquo $STATE;;esac;;
'${'*)
case $STATE in
cmd) SNEW;STATE=arg;SOPEN;SNEW;STATE=expan;SOPEN;SNEW;STATE=vparam;SOPEN;IGNORE2;;
*) _error brop $STATE;;esac;;
'$('*)
case $STATE in
text)
SCLOSE
case $PARN in *dquo);; *) _error AJDNKAJND;;esac
IGNORE2;CONSUMED=;SNEW;STATE=dquotesub;SOPEN;SNEW;STATE=prog;SOPEN;
;;
cmd) SNEW;STATE=arg;SOPEN;SNEW;STATE=dquotesub;SOPEN;SNEW;STATE=prog;SOPEN;IGNORE2;;
*) _error brop $STATE;;esac;;
'('*)
case $STATE in
prog) SNEW;STATE=full;SOPEN;;
full) SNEW;STATE=stmt;SOPEN;;
stmt) SNEW;STATE=exec;SOPEN;;
exec) SNEW;STATE=cmd;SOPEN;;
cmd) SNEW;STATE=arg;SOPEN;SNEW;STATE=subsh;SOPEN;SNEW;STATE=prog;SOPEN;IGNORE;;
*) _error bropa $STATE;;esac;;
'$'*)
case $STATE in
cmd) SNEW;STATE=arg;SOPEN;SNEW;STATE=expan;SOPEN;SNEW;STATE=vname;SOPEN;IGNORE;;
*) _error dquo $STATE;;esac;;
':-'* | ':+'* | '%%'* | '##'*)
case $STATE in
expan) SNEW;STATE=vsubst;SOPEN;CONSUME2;SNEW;STATE=arg;SOPEN;;
*) _error col $STATE;;esac;;
'#'* | '%'*)
case $STATE in
expan) SNEW;STATE=vsubst;SOPEN;CONSUME;SNEW;STATE=arg;SOPEN;;
prog|cmd) SNEW;STATE=commt;SOPEN;CONSUME;;
*) _error col $STATE;;esac;;
[a-zA-Z0-9_=]*)
case $STATE in
word) CONSUME;;
vsubst|vparam|vname)
SINPUTMORE
CONSUMED="${CODE%%[!a-zA-Z0-9_=]*}"; CODE="${CODE#"$CONSUMED"}"
SCLOSE;
;;
execpre)
STATE=cmdpre
SINPUTMORE
MATCH="${CODE%%[!a-zA-Z0-9_=]*}"; REST="${CODE#"$MATCH"}"
MATCH2="${REST#"${REST%%[!$_TAB\ ]*}"}"
case $MATCH2 in
'()'*)
CODE="${MATCH2#'()'}"
CONSUMED="$MATCH";SNEW;STATE=fdecl;SOPEN;
;;
*)
case $MATCH in
'if')
CODE="${MATCH2}"
CONSUMED="$MATCH";SNEW;STATE=cif;SOPEN;SNEW;STATE=prog;SOPEN;
;;
'then')
SDISC;SCLOSE;SCLOSE;SDISC
case $STATES in "") _error kdnafkandkasd;;esac
SCLOSE
case $PARN in
*cif|*celif)
CONSUME4;SNEW;STATE=cthen;SOPEN;SNEW;STATE=prog;SOPEN;
;;
*) _error aijndkjandlaksalallll;;
esac;;
'elif')
SDISC;SCLOSE;SCLOSE;SDISC
case $STATES in "") _error zzzzzzzzzzzz;;esac
SCLOSE;SCLOSE
case $PARN in
*cif|*celif)
CONSUME4;SNEW;STATE=celif;SOPEN;SNEW;STATE=prog;SOPEN;
;;
*) _error gggggggg;;
esac;;
'else')
SDISC;SCLOSE;SCLOSE;SDISC
case $STATES in "") _error xxxxxxxxxxkdnafkandkasd;;esac
SCLOSE;SCLOSE
case $PARN in
*cif|*celif)
CONSUME4;SNEW;STATE=celse;SOPEN;SNEW;STATE=prog;SOPEN;
;;
*) _error xxxxxxxxxaijndkjandlaksalallll;;
esac;;
'fi')
SDISC;SDISC;SDISC;SDISC
case $STATES in "") _error xxxxxxxxxxkdnafkandkasd;;esac
SCLOSE;SCLOSE
case $PARN in
*cif|*celif)
CONSUME2;SCLOSE;SCLOSE
;;
*) _error sadasdaijndkjandlaksalallll;;
esac;;
'while')
CODE="${MATCH2}"
CONSUMED="$MATCH";SNEW;STATE=cwhile;SOPEN;SNEW;STATE=prog;SOPEN;
;;
'for')
CODE="${MATCH2}"
CONSUMED="$MATCH";SNEW;STATE=cfor;SOPEN;SNEW;STATE=prog;SOPEN;
;;
'do')
SDISC;SCLOSE;SCLOSE;SDISC
case $STATES in "") _error kdnafkandkasd;;esac
SCLOSE
case $PARN in
*cwhile|*cfor)
CONSUME2;SNEW;STATE=cdo;SOPEN;SNEW;STATE=prog;SOPEN;
;;
*) _error doinqwkjnkqjwn;;
esac;;
'done')
SDISC;SDISC;SDISC;SDISC
case $STATES in "") _error xxxxxxxxxxkdnafkandkasd;;esac
SCLOSE;SCLOSE
case $PARN in
*cwhile|*cfor)
CONSUME4;SCLOSE;SCLOSE
;;
*) _error sadasdaijndkjandlaksalallll;;
esac;;
'case')
CODE="${MATCH2}"
CONSUMED="$MATCH";SNEW;STATE=cswitch;SOPEN;
;;
esac
esac
;;
cswitch)
SINPUTMORE
MATCH="${CODE%%[!a-zA-Z0-9_]*}"; REST="${CODE#"$MATCH"}"
MATCH2="${REST#"${REST%%[!$_TAB\ ]*}"}"
case $MATCH2 in
'in'*) CODE="${MATCH2#"in"}";CONSUMED="$MATCH";IGNORE_WS;SNEW;STATE=arg;SOPEN;SCLOSE;STATE=ccase;;
*) _error CASE;;
esac
;;
ccase)
SINPUTMORE
MATCH="${CODE%%[!a-zA-Z0-9_]*}"; REST="${CODE#"$MATCH"}"
case $MATCH in
'esac') CONSUME4;CONSUMED=;SCLOSE;;
*) SNEW;STATE=ccaseitem;SOPEN;SNEW;STATE=ccasepatt;SOPEN;;
esac
;;
cmdpre)
SINPUTMORE
MATCH="${CODE%%[!a-zA-Z0-9_]*}"; REST="${CODE#"$MATCH"}"
case $REST in
'='*) CODE="$REST";CONSUMED="$MATCH";SNEW;STATE=vassig;SOPEN;SNEW;STATE=arg;SOPEN;IGNORE;CONSUMED=;;
*) STATE=cmd;;
esac
;;
vassig)
SINPUTMORE
MATCH="${CODE%%[!a-zA-Z0-9_]*}"; REST="${CODE#"$MATCH"}"
case $REST in
'='*) SCLOSE;CODE="$REST";CONSUMED="$MATCH";SNEW;STATE=vassig;SOPEN;SNEW;STATE=arg;SOPEN;IGNORE;CONSUMED=;;
*) SCLOSE;STATE=cmd;;
esac
;;
prog) SNEW;STATE=full;SOPEN;;
full) SNEW;STATE=stmt;SOPEN;;
stmt) SNEW;STATE=exec;SOPEN;;
exec) SNEW;STATE=cmd;SOPEN;STATE=execpre;;
cmd) SNEW;STATE=arg;SOPEN;;
ccasepatt) SNEW;STATE=cpatt;SOPEN;;
arg) SNEW;STATE=word;SOPEN;;
cpatt) CONSUME;;
text|commt) CONSUME;;
bangUP|logicBP|pipeBP) SCLOSE;CONSUMED=;;
*) _error NAME;;esac;;
*) _error CHARACTER;;
esac
done
case $- in *z*);;*)
set | while read -r LINE || test -n "$LINE"
do
case $LINE in
[VX][0-9]*)
NAM="${LINE%%=*}"
eval "VAL=\"\${$NAM:-}\""
_printr1 "$NAM=$VAL"
;;
esac
done
exit $?
esac
}
main () {
xxx
}
@alganet
Copy link
Author

alganet commented Jun 29, 2025

Beware, this is a very early stage prototype, with lots of tests missing.

This was an attempt to gain performance using alias in shells that support it.

Now that I know it works, I can write a much more sensible parser without the alias tricks and transpile/inline functions by using the parser itself, so this code will be rewritten.

Since I've done it outside of any repo, I'm registering it here as an artifact.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment