Update AST for command substitutions

The AST generated by the parser did not match the syntax document.
However, neither were right.  This commit updates the syntax document
to describe a more consistent form, and fixes the code to follow it.

* doc/syntax.txt (word): Make the children of '<sh-cmd-sub>' a
possibly empty list of 'list's.
* geesh/lexer.scm (get-bracketed-command): Splice in children for
'<sh-cmd-sub>'.
(get-backquoted-command): Ditto.
* geesh/parser.scm (read-sh/bracketed): Make sure that result is
always a list.
(read-sh/backquoted): Ditto.
* tests/lexer.scm: Update tests accordingly.
* tests/parser.scm: Ditto.
This commit is contained in:
Timothy Sample 2018-07-18 14:27:11 -04:00
parent 4f1e737cdd
commit 2aa8615f9e
5 changed files with 15 additions and 13 deletions

View File

@ -40,7 +40,7 @@ redir ::= ('> fdes word)
word ::= string
| (word ...)
| ('<sh-quote> word)
| ('<sh-cmd-sub> sync ...)
| ('<sh-cmd-sub> [list] ...)
| ('<sh-ref> var)
| ('<sh-ref-or> var [word])
| ('<sh-ref-or*> var [word])

View File

@ -322,7 +322,7 @@ leading '$')."
(#\(
(let ((result ((read-bracketed-command) port)))
(match (get-char port)
(#\) `(<sh-cmd-sub> ,result)))))))
(#\) `(<sh-cmd-sub> ,@result)))))))
(define (get-backquoted-command port)
"Get a backquoted command ('`...`') from @var{port}."
@ -330,7 +330,7 @@ leading '$')."
(#\`
(let ((result ((read-backquoted-command) port)))
(match (get-char port)
(#\` `(<sh-cmd-sub> ,result)))))))
(#\` `(<sh-cmd-sub> ,@result)))))))
(define (get-expansion port)
"Get an expansion ('$name', '${...}', '$(...)', or '`...`') from

View File

@ -766,7 +766,8 @@ bracket."
(parse (make-parser #:open-bracket-hook incr-bracket-depth!
#:close-bracket-hook decr-bracket-depth!)))
(match (parse lex syntax-error)
((? eof-object?) #f)
((? eof-object?) '())
(((? symbol? tag) . rest) `((,tag . ,rest)))
(code code))))
(define (read-sh/backquoted port)
@ -776,7 +777,8 @@ bracket."
(let ((lex (make-lexer port read-sh/bracketed read-sh/backquoted))
(parse (make-parser)))
(match (parse lex syntax-error)
((? eof-object?) #f)
((? eof-object?) '())
(((? symbol? tag) . rest) `((,tag . ,rest)))
(code code))))))
(define* (read-sh #:optional (port #f))

View File

@ -340,7 +340,7 @@
(parameterize ((read-bracketed-command
(lambda (port)
(string-for-each (lambda _ (read-char port)) "foo")
'(<sh-exec> "foo"))))
'((<sh-exec> "foo")))))
(tokenize "$(foo)")))
;;;
@ -352,7 +352,7 @@
(parameterize ((read-backquoted-command
(lambda (port)
(string-for-each (lambda _ (read-char port)) "foo")
'(<sh-exec> "foo"))))
'((<sh-exec> "foo")))))
(tokenize "`foo`")))
(test-end)

View File

@ -314,12 +314,12 @@
(parse "echo $(foo $(bar))"))
(test-equal "Parses empty bracketed command substitions"
'(<sh-exec> "echo" (<sh-cmd-sub> #f))
'(<sh-exec> "echo" (<sh-cmd-sub>))
(parse "echo $()"))
(test-equal "Parses multiline bracketed command substitions"
'(<sh-exec> "echo" (<sh-cmd-sub> ((<sh-exec> "foo")
(<sh-exec> "bar"))))
'(<sh-exec> "echo" (<sh-cmd-sub> (<sh-exec> "foo")
(<sh-exec> "bar")))
(parse "echo $(foo
bar)"))
@ -336,12 +336,12 @@
(parse "echo `foo \\`bar\\``"))
(test-equal "Parses empty backquoted command substitions"
'(<sh-exec> "echo" (<sh-cmd-sub> #f))
'(<sh-exec> "echo" (<sh-cmd-sub>))
(parse "echo ``"))
(test-equal "Parses multiline backquoted command substitions"
'(<sh-exec> "echo" (<sh-cmd-sub> ((<sh-exec> "foo")
(<sh-exec> "bar"))))
'(<sh-exec> "echo" (<sh-cmd-sub> (<sh-exec> "foo")
(<sh-exec> "bar")))
(parse "echo `foo
bar`"))