Remove extra '<sh-begin>' wrappers.

This commit fixes many differences between the parser output and the
syntax document.

* gash/parser.scm (make-parser): Only wrap a command list with
'<sh-begin>' when necessary.
* tests/unit/parser.scm: Update tests accordingly.
This commit is contained in:
Timothy Sample 2019-05-26 20:33:54 -04:00
parent 490878443b
commit 27df6180c3
2 changed files with 43 additions and 46 deletions

View File

@ -1,5 +1,5 @@
;;; Gash -- Guile As SHell ;;; Gash -- Guile As SHell
;;; Copyright © 2018 Timothy Sample <samplet@ngyro.com> ;;; Copyright © 2018, 2019 Timothy Sample <samplet@ngyro.com>
;;; ;;;
;;; This file is part of Gash. ;;; This file is part of Gash.
;;; ;;;
@ -181,6 +181,12 @@ is also called when reducing case patterns that end with an unbalanced
closing bracket. This ensures that when parsing valid Shell code, closing bracket. This ensures that when parsing valid Shell code,
@var{open-bracket-hook} and @var{close-bracket-hook} should be called @var{open-bracket-hook} and @var{close-bracket-hook} should be called
the same number of times.)" the same number of times.)"
(define command-list->block
(match-lambda
((cmd) cmd)
((cmds ...) `(<sh-begin> ,@cmds))))
(lalr-parser (lalr-parser
(AND ; '&' (AND ; '&'
@ -243,17 +249,12 @@ the same number of times.)"
(complete-command (complete-command
(list separator-op) (list separator-op)
: (let ((lst (match $2 : (command-list->block
('AND (reverse! (cons `(<sh-async> ,(car $1)) (cdr $1)))) (match $2
('SEMI (reverse! $1))))) ('AND (reverse! (cons `(<sh-async> ,(car $1)) (cdr $1))))
(if (null? (cdr lst)) ('SEMI (reverse! $1))))
(car lst)
(cons '<sh-begin> lst)))
(list) (list)
: (let ((lst (reverse! $1))) : (command-list->block (reverse! $1)))
(if (null? (cdr lst))
(car lst)
(cons '<sh-begin> lst))))
(list (list
(list separator-op and-or) (list separator-op and-or)
@ -299,7 +300,7 @@ the same number of times.)"
(compound-command (compound-command
(brace-group) (brace-group)
: $1 : (command-list->block $1)
(subshell) (subshell)
: $1 : $1
(for-clause) (for-clause)
@ -315,19 +316,15 @@ the same number of times.)"
(subshell (subshell
(LPAREN! compound-list RPAREN!) (LPAREN! compound-list RPAREN!)
: `(<sh-subshell> ,$2)) : `(<sh-subshell> ,@$2))
(compound-list (compound-list
(linebreak term) (linebreak term)
: (match $2 : (reverse! $2)
((cmd) cmd)
(cmds `(<sh-begin> ,@(reverse! cmds))))
(linebreak term separator) (linebreak term separator)
: (match (match $3 : (reverse! (match $3
('AND (cons `(<sh-async> ,(car $2)) (cdr $2))) ('AND (cons `(<sh-async> ,(car $2)) (cdr $2)))
((or 'SEMI 'NEWLINE) $2)) ((or 'SEMI 'NEWLINE) $2))))
((cmd) cmd)
(cmds `(<sh-begin> ,@(reverse! cmds)))))
(term (term
(term separator and-or) (term separator and-or)
@ -339,13 +336,13 @@ the same number of times.)"
(for-clause (for-clause
(For name do-group) (For name do-group)
: `(<sh-for> (,$2 ((<sh-quote> (<sh-ref> "@")))) ,$3) : `(<sh-for> (,$2 ((<sh-quote> (<sh-ref> "@")))) ,@$3)
(For name sequential-sep do-group) (For name sequential-sep do-group)
: `(<sh-for> (,$2 ((<sh-quote> (<sh-ref> "@")))) ,$4) : `(<sh-for> (,$2 ((<sh-quote> (<sh-ref> "@")))) ,@$4)
(For name linebreak in sequential-sep do-group) (For name linebreak in sequential-sep do-group)
: `(<sh-for> (,$2 ()) ,$6) : `(<sh-for> (,$2 ()) ,@$6)
(For name linebreak in wordlist sequential-sep do-group) (For name linebreak in wordlist sequential-sep do-group)
: `(<sh-for> (,$2 ,$5) ,$7)) : `(<sh-for> (,$2 ,$5) ,@$7))
(name (name
(NAME-with-keywords) (NAME-with-keywords)
@ -385,21 +382,21 @@ the same number of times.)"
(pattern! RPAREN! linebreak) (pattern! RPAREN! linebreak)
: `(,$1 #f) : `(,$1 #f)
(pattern! RPAREN! compound-list) (pattern! RPAREN! compound-list)
: `(,$1 ,$3) : `(,$1 ,@$3)
(LPAREN! pattern RPAREN! linebreak) (LPAREN! pattern RPAREN! linebreak)
: `(,$2 #f) : `(,$2 #f)
(LPAREN! pattern RPAREN! compound-list) (LPAREN! pattern RPAREN! compound-list)
: `(,$2 ,$4)) : `(,$2 ,@$4))
(case-item (case-item
(pattern! RPAREN! linebreak DSEMI linebreak) (pattern! RPAREN! linebreak DSEMI linebreak)
: `(,$1 #f) : `(,$1 #f)
(pattern! RPAREN! compound-list DSEMI linebreak) (pattern! RPAREN! compound-list DSEMI linebreak)
: `(,$1 ,$3) : `(,$1 ,@$3)
(LPAREN! pattern RPAREN! linebreak DSEMI linebreak) (LPAREN! pattern RPAREN! linebreak DSEMI linebreak)
: `(,$2 #f) : `(,$2 #f)
(LPAREN! pattern RPAREN! compound-list DSEMI linebreak) (LPAREN! pattern RPAREN! compound-list DSEMI linebreak)
: `(,$2 ,$4)) : `(,$2 ,@$4))
(pattern (pattern
(WORD*-without-Esac) (WORD*-without-Esac)
@ -409,25 +406,25 @@ the same number of times.)"
(if-clause (if-clause
(If compound-list Then compound-list else-part Fi) (If compound-list Then compound-list else-part Fi)
: `(<sh-cond> (,$2 ,$4) ,@$5) : `(<sh-cond> (,(command-list->block $2) ,@$4) ,@$5)
(If compound-list Then compound-list Fi) (If compound-list Then compound-list Fi)
: `(<sh-cond> (,$2 ,$4))) : `(<sh-cond> (,(command-list->block $2) ,@$4)))
(else-part (else-part
(Elif compound-list Then compound-list) (Elif compound-list Then compound-list)
: `((,$2 ,$4)) : `((,(command-list->block $2) ,@$4))
(Elif compound-list Then compound-list else-part) (Elif compound-list Then compound-list else-part)
: (cons `(,$2 ,$4) $5) : (cons `(,(command-list->block $2) ,@$4) $5)
(Else compound-list) (Else compound-list)
: `((<sh-else> ,$2))) : `((<sh-else> ,@$2)))
(while-clause (while-clause
(While compound-list do-group) (While compound-list do-group)
: `(<sh-while> ,$2 ,$3)) : `(<sh-while> ,(command-list->block $2) ,@$3))
(until-clause (until-clause
(Until compound-list do-group) (Until compound-list do-group)
: `(<sh-until> ,$2 ,$3)) : `(<sh-until> ,(command-list->block $2) ,@$3))
(function-definition (function-definition
(fname LPAREN! RPAREN! linebreak function-body) (fname LPAREN! RPAREN! linebreak function-body)

View File

@ -153,8 +153,8 @@
echo bar; }")) echo bar; }"))
(test-equal "Parses subshells" (test-equal "Parses subshells"
'(<sh-subshell> (<sh-begin> (<sh-exec> "echo" "foo") '(<sh-subshell> (<sh-exec> "echo" "foo")
(<sh-exec> "echo" "bar"))) (<sh-exec> "echo" "bar"))
(parse "(echo foo; echo bar)")) (parse "(echo foo; echo bar)"))
;; Here documents ;; Here documents
@ -179,10 +179,10 @@
(test-equal "Parses multiple here-documents in a compound list" (test-equal "Parses multiple here-documents in a compound list"
'(<sh-subshell> '(<sh-subshell>
(<sh-begin> (<sh-with-redirects> ((<< 0 (<sh-quote> "foo\n"))) (<sh-with-redirects> ((<< 0 (<sh-quote> "foo\n")))
(<sh-exec> "cat")) (<sh-exec> "cat"))
(<sh-with-redirects> ((<< 0 (<sh-quote> "bar\n"))) (<sh-with-redirects> ((<< 0 (<sh-quote> "bar\n")))
(<sh-exec> "cat")))) (<sh-exec> "cat")))
(parse "(cat <<eof1; cat <<eof2\nfoo\neof1\nbar\neof2\n)")) (parse "(cat <<eof1; cat <<eof2\nfoo\neof1\nbar\neof2\n)"))
(test-equal "Parses here-documents in both simultaneously" (test-equal "Parses here-documents in both simultaneously"
@ -255,10 +255,10 @@
(test-equal "Parses two here-documents split by two newlines" (test-equal "Parses two here-documents split by two newlines"
'(<sh-subshell> '(<sh-subshell>
(<sh-begin> (<sh-with-redirects> ((<< 0 (<sh-quote> "foo\n"))) (<sh-with-redirects> ((<< 0 (<sh-quote> "foo\n")))
(<sh-exec> "cat")) (<sh-exec> "cat"))
(<sh-with-redirects> ((<< 0 (<sh-quote> "bar\n"))) (<sh-with-redirects> ((<< 0 (<sh-quote> "bar\n")))
(<sh-exec> "cat")))) (<sh-exec> "cat")))
(parse "(\ncat <<eof\nfoo\neof\n\ncat <<eof\nbar\neof\n)")) (parse "(\ncat <<eof\nfoo\neof\n\ncat <<eof\nbar\neof\n)"))
(test-equal "Parses tab-trimming here-document" (test-equal "Parses tab-trimming here-document"