Support escaped newline.

* gash/peg.scm (parse-): Support escaped newline.
* test/01-script-backslash.sh: Test it.
This commit is contained in:
Jan Nieuwenhuizen 2018-11-03 12:53:39 +01:00
parent bca65e807b
commit 2a4e3ec71b
14 changed files with 36 additions and 17 deletions

View File

@ -6,8 +6,14 @@ SHELL=${SHELL-bin/gash}
tests="
00-exit
01-exit-0
02-exit-1
00-exit-0
00-exit-1
01-script-newline
01-script-semi
01-script-backslash
01-script-backslash-space.sh
01-script-backslash-twice.sh
03-echo
03-echo-nesting

View File

@ -156,10 +156,10 @@
and <-- '&&'
or <-- '||'
pipe < '|'
pipeline <-- negate? pipeline-head pipeline-tail*
pipeline-head <- sp* command
pipeline-tail <- sp* pipe ws* command
negate <-- '!'
pipeline <-- negate? pipeline-head pipeline-tail*
command <-- (compound-command (sp+ io-redirect)*) / simple-command / function-def
compound-command <- brace-group / subshell / for-clause / case-clause / if-clause / while-clause / until-clause
simple-command <- (sp* (io-redirect sp+)* nonreserved)+
@ -212,7 +212,7 @@
filename <-- word
name <-- identifier
identifier <- [_a-zA-Z][_a-zA-Z0-9]*
word <-- assignment / delim / (number / variable / brace-variable / literal)+
word <-- assignment / delim / (number / variable / variable-and-or / literal)+
number <-- [0-9]+
lsubst < '$('
@ -223,9 +223,9 @@
rhs <- (substitution / word)*
assign < '='
dollar < '$'
literal <-- (!tick !dollar !pipe !semi !par !nl !sp !rbrace .)+
variable <-- dollar ('$' / '*' / '?' / '@' / [0-9] / identifier)
brace-variable <- dollar lbrace (variable-or / variable-and / identifier) rbrace
literal <-- backslash? (!ws !tick !dollar !pipe !semi !par !nl !sp !rbrace .)+
variable <-- dollar ('$' / '*' / '?' / '@' / [0-9] / identifier / lbrace identifier rbrace)
variable-and-or <- dollar lbrace (variable-or / variable-and ) rbrace
variable-and <-- identifier plus rhs
variable-or <-- identifier minus rhs
delim <- singlequotes / doublequotes / substitution
@ -238,6 +238,7 @@
separator <- (sp* break ws*) / ws+
sequential-sep <- (semi !semi ws*) / ws+
amp <- '&'
backslash <- '\\'
semi < ';'
lpar < '('
rpar < ')'
@ -247,10 +248,14 @@
minus < '-'
par < lpar / rpar
nl < '\n'
sp < [\t ]
sp < '\t' / ' ' / (escaped-nl sp*)
ws < sp / nl
escaped-nl < (backslash nl)
error <-- .*")
(when (> %debug-level 1)
(format (current-error-port) "input:~s\n" input))
(let* ((match (match-pattern script input))
(end (peg:end match))
(pt (peg:tree match)))
@ -340,16 +345,8 @@
s)))
(string-split s #\newline)) "\n"))
(define (remove-escaped-newlines s)
(reduce (lambda (next prev)
(let* ((escaped? (string-suffix? "\\" next))
(next (if escaped? (string-drop-right next 1) next))
(sep (if escaped? "" "\n")))
(string-append prev sep next)))
"" (string-split s #\newline)))
(define (parse-string string)
(let* ((pt ((compose parse- remove-escaped-newlines remove-shell-comments) string))
(let* ((pt ((compose parse- remove-shell-comments) string))
(foo (when (> %debug-level 1) (display "tree:\n") (pretty-print pt)))
(flat (flatten pt))
(foo (when (> %debug-level 0) (display "flat:\n") (pretty-print flat)))

View File

@ -0,0 +1,4 @@
echo foo\
bar baz\
bla
echo

View File

@ -0,0 +1 @@
2

View File

@ -0,0 +1,3 @@
exit \
\
2

View File

@ -0,0 +1 @@
2

View File

@ -0,0 +1,2 @@
exit\
2

View File

@ -0,0 +1 @@
2

View File

@ -0,0 +1,2 @@
true
exit 2

1
test/01-script-semi.exit Normal file
View File

@ -0,0 +1 @@
2

1
test/01-script-semi.sh Normal file
View File

@ -0,0 +1 @@
true; exit 2