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:
parent
490878443b
commit
27df6180c3
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue