Last active
March 30, 2026 18:02
-
-
Save cgsdev0/9d251c54dbf49092f0ed1fc78937bfd6 to your computer and use it in GitHub Desktop.
lisp parser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # basic lisp parser that creates an AST. | |
| # assumes valid input. | |
| # | |
| # it stores this AST using the file system, since | |
| # bash doesn't really have a good way to do trees | |
| output_path=/tmp/parsed | |
| usage() { | |
| cat << USAGE | |
| usage: $0 [path_to_program] | |
| example program: | |
| (first (list 1 (+ 2 3) 9)) | |
| example output: | |
| . | |
| └── first | |
| └── list | |
| ├── 1 | |
| ├── + | |
| │ ├── 2 | |
| │ └── 3 | |
| └── 9 | |
| USAGE | |
| exit 1 | |
| } | |
| source="$1" | |
| [[ -f "$source" ]] || usage | |
| rm -rf "$output_path" | |
| mkdir -p "$output_path" | |
| tokenizer() { | |
| local acc char | |
| emit() { | |
| [[ -n "$acc" ]] && echo "$acc" | |
| acc= | |
| } | |
| # loop character by character | |
| while IFS= read -rn 1 char; do | |
| char=${char:- } # newlines become spaces | |
| case $char in | |
| '(' | ')') | |
| emit | |
| echo "$char" | |
| ;; | |
| ' ') emit ;; | |
| # accumulate characters | |
| *) acc="${acc}${char}" ;; | |
| esac | |
| done | |
| } | |
| lexer() { | |
| local i=0 | |
| cd "$1" | |
| while read -r token; do | |
| case "$token" in | |
| '(') | |
| read -r token | |
| mkdir "$i $token" | |
| pushd "$i $token" &> /dev/null | |
| ;; | |
| ')') popd &> /dev/null ;; | |
| *) touch "$i $token" ;; | |
| esac | |
| ((i++)) | |
| done | |
| } | |
| show_ast() { | |
| cd "$1" | |
| tree . -v --noreport \ | |
| | sed 's/[0-9]\+ //' | |
| } | |
| cat "$source" \ | |
| | tokenizer \ | |
| | lexer "$output_path" | |
| show_ast "$output_path" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment