From 7c67b09765d7334690d9b48e91ee188e9be179b7 Mon Sep 17 00:00:00 2001 From: "Luke T. Shumaker" Date: Wed, 22 May 2024 16:17:05 -0400 Subject: have a single token callback --- gron | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ json.sh | 59 +++++++++++++++++++++++++++++++++++++---------------------- tokenize | 10 ++++++++++ trace | 30 ------------------------------ 4 files changed, 110 insertions(+), 52 deletions(-) create mode 100755 gron create mode 100755 tokenize delete mode 100755 trace diff --git a/gron b/gron new file mode 100755 index 0000000..0fd05d0 --- /dev/null +++ b/gron @@ -0,0 +1,63 @@ +#!/bin/bash +set -e + +. "$(dirname -- "${BASH_SOURCE[0]}")/json.sh" + +stack=() + +print_lhs() { + printf 'json' + local x + for x in "${stack[@]}"; do + printf '[%s]' "$x" + done + printf '=' +} + +handle_token() { + local val='' + case "$1" in + object_beg) + val='{}' + stack+=('bogus') + ;; + object_end) + stack=("${stack[@]::${#stack[@]}-1}") + ;; + object_key) + stack[${#stack[@]}-1]="${2@Q}" + ;; + array_beg) + val='[]' + stack+=('0') + ;; + array_end) + stack=("${stack[@]::${#stack[@]}-1}") + ;; + number) + val="$2" + ;; + string) + val="${2@Q}" + ;; + null|true|false) + val="$1" + ;; + error) + printf >&2 "json error: $1\n" "${@:2}" + ;; + esac + if [[ -n "$val" ]]; then + printf 'json' + local x + for x in "${stack[@]}"; do + printf '[%s]' "$x" + done + printf '=%s;\n' "$val" + fi + if [[ ${#stack[@]} -gt 0 && ${stack[${#stack[@]}-1]} =~ ^[0-9]$ ]]; then + stack[${#stack[@]}-1]=$((${stack[${#stack[@]}-1]}+1)) + fi +} + +json_tokenize handle_token diff --git a/json.sh b/json.sh index 9d7701b..a197158 100644 --- a/json.sh +++ b/json.sh @@ -1,11 +1,30 @@ #!/hint/bash -json_parse() { - type json_object_beg &>/dev/null || json_object_beg() { :; } # no args - type json_object_end &>/dev/null || json_object_end() { :; } # no args - type json_array_beg &>/dev/null || json_array_beg() { :; } # no args - type json_array_end &>/dev/null || json_array_end() { :; } # no args - type json_atom &>/dev/null || json_atom() { :; } # $1=(key|string|number|bool|null) $2=$val +# Usage: json_tokenize myfn &2 "json error: $1"'\n' "${@:2}" + "$_json_token" "$@" return 1 } @@ -50,13 +69,13 @@ _json_value() { _json_object() { _json_expect '{' - json_object_beg + "$_json_token" object_beg _json_ws case "${_json_buf::1}" in '"' ) local _json_obj_key while true; do - _json_string key + _json_string object_key _json_ws _json_expect ':' _json_value @@ -68,7 +87,7 @@ _json_object() { ;; '}' ) _json_buf=${_json_buf:1} - json_object_end + "$_json_token" object_end return ;; esac @@ -76,7 +95,7 @@ _json_object() { ;; '}' ) _json_buf=${_json_buf:1} - json_object_end + "$_json_token" object_end return ;; esac @@ -84,11 +103,11 @@ _json_object() { _json_array() { _json_expect '[' - json_array_beg + "$_json_token" array_beg _json_ws if [[ "${_json_buf::1}" == ']' ]]; then _json_buf=${_json_buf:1} - json_array_end + "$_json_token" array_end return fi while true; do @@ -101,7 +120,7 @@ _json_array() { ;; ']' ) _json_buf=${_json_buf:1} - json_array_end + "$_json_token" array_end return ;; esac @@ -113,7 +132,7 @@ _json_string() { _json_expect '"' local _json_strval='' local _json_re='^[^\"]+' - local _json_c json_n _json_n2 + local _json_c _json_n _json_n2 while true; do case "${_json_buf::1}" in "\\" ) @@ -154,7 +173,7 @@ _json_string() { ;; '"' ) _json_buf=${_json_buf:1} - json_atom "$1" "$_json_strval" + "$_json_token" "$1" "$_json_strval" return ;; * ) @@ -174,7 +193,7 @@ _json_number() { _json_error 'invalid number: %q' "${_json_buf::16}" fi _json_buf=${_json_buf:${#BASH_REMATCH[0]}} - json_atom number "${BASH_REMATCH[0]}" + "$_json_token" number "${BASH_REMATCH[0]}" } _json_lit() { @@ -182,9 +201,5 @@ _json_lit() { _json_error 'expected %q, got: %q' "$1" "${_json_buf::${#1}}" fi _json_buf=${_json_buf:${#1}} - if [[ "$1" == 'null' ]]; then - json_atom null null - else - json_atom bool "$1" - fi + "$_json_token" "$1" } diff --git a/tokenize b/tokenize new file mode 100755 index 0000000..35576af --- /dev/null +++ b/tokenize @@ -0,0 +1,10 @@ +#!/bin/bash +set -e + +. "$(dirname -- "${BASH_SOURCE[0]}")/json.sh" + +handle_token() { + printf '%s\n' "${*@Q}" +} + +json_tokenize handle_token diff --git a/trace b/trace deleted file mode 100755 index 3aa657d..0000000 --- a/trace +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -# no args -json_object_beg() { - echo json_object_beg -} - -# no args -json_object_end() { - echo json_object_end -} - -# no args -json_array_beg() { - echo json_array_beg -} - -# no args -json_array_end() { - echo json_array_end -} - -# $1=(key|string|number|bool|null) $2=$val -json_atom() { - printf 'json_atom %q %q\n' "$1" "$2" -} - -. "$(dirname -- "${BASH_SOURCE[0]}")/json.sh" - -json_parse -- cgit v1.2.3-54-g00ecf