From f6e55a026abf33867141896b1e227e791942c2a3 Mon Sep 17 00:00:00 2001 From: P. J. McDermott Date: Fri, 19 Feb 2016 04:01:32 -0500 Subject: [WIP] Add lexer/parser demo --- (limited to 'parsing/parse.sh') diff --git a/parsing/parse.sh b/parsing/parse.sh new file mode 100644 index 0000000..2ac4215 --- /dev/null +++ b/parsing/parse.sh @@ -0,0 +1,133 @@ +HT="$(printf '\t.')"; HT="${HT%.}" +LF="$(printf '\n.')"; LF="${LF%.}" +RS="$(printf '\036.')"; RS="${RS%.}" +US="$(printf '\037.')"; US="${US%.}" + +. ./tokens.sh +. ./lexer.sh + +complete_command() +{ + if list; then + separator + return 0 + fi + return 1 +} + +list() +{ + if and_or; then + while separator_op; do + if ! and_or; then + return 1 + fi + done + return 0 + fi + return 1 +} +and_or() +{ + if pipeline; then + while accept T_AND_IF || accept T_OR_IF; do + if ! linebreak || ! pipeline; then + return 1 + fi + done + return 0 + fi + return 1 +} +pipeline() +{ + accept T_BANG + if pipe_sequence; then + return 0 + fi + return 1 +} + +pipe_sequence() +{ + if command; then + while accept T_PIPE; do + if ! linebreak || ! command; then + return 1 + fi + done + return 0 + fi + return 1 +} + +command() +{ + # XXX: Unfinished + accept T_WORD +} + + + +newline_list() +{ + if accept T_NEWLINE; then + while accept T_NEWLINE; do + : + done + return 0 + fi + return 1 +} +linebreak() +{ + newline_list + return 0 +} + +separator_op() +{ + if accept T_AND || accept T_SEMI; then + return 0 + fi + return 1 +} + +separator() +{ + if separator_op && linebreak; then + return 0 + elif newline_list; then + return 0 + fi + return 1 +} + +parse() +{ + local fn="${1}" + shift 1 + + init_lexer "${fn}" + while complete_command; do :; done + if :; then # TODO: Test for EOF or errors + get_tokens + return 0 + fi + return 1 +} + +if tokens="$(printf '%s\n' '"foo bar" && $baz || qux' '${quux%uux } quuux' | \ + parse -)"; then + IFS="${RS}" + for t in ${tokens}; do + printf 'Token: %s\n' "$(tokname "${t}")" + case "${t%${US}*}" in T_WORD) + printf ' "%s"\n' "${t#T_WORD${US}}" + ;; + esac + done + unset IFS +else + echo FAIL +fi -- cgit v0.9.1