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

View File

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