various fixes, TODO remove debugging code

This commit is contained in:
Rutger van Beusekom 2016-09-17 19:36:09 +02:00
parent 14147e01a3
commit 4995a36773
1 changed files with 28 additions and 20 deletions

View File

@ -21,54 +21,56 @@
(define-peg-pattern here-document all (and (+ (and (not-followed-by here-delim) peg-any)) here-delim))
(define-peg-string-patterns
"script <-- (sp / linebreak)* (term (separator term)* separator?)?
term <-- pipeline (sp* (and / or) (sp / linebreak)* pipeline)*
"script <-- ws* (term (separator term)* separator?)?
term <-- pipeline (sp* (and / or) ws* pipeline)*
and <-- '&&'
or <-- '||'
pipeline <-- '!'? sp* command (sp* pipe (sp / linebreak)* command)*
pipeline <-- '!'? sp* command (sp* pipe ws* command)*
pipe <-- '|'
command <-- simple-command / (compound-command (sp+ io-redirect)*) / function-def
compound-command <-- brace-group / subshell / for-clause / case-clause / if-clause / while-clause / until-clause
subshell <-- '(' sp* compound-list sp* ')'
compound-list <-- (sp / linebreak)* term (separator term)* separator?
case-clause <-- 'case' sp+ word (sp / linebreak)* 'in' (sp / linebreak)* (case-item sp)* 'esac'
case-item <-- '('? sp* pattern sp* ')' (((sp / linebreak) ';;' (sp / linebreak)) / ((compound-list sp* ';;'?)? (sp / linebreak)))
subshell <-- '(' compound-list ')'
compound-list <-- ws* term (separator term)* separator?
case-clause <-- 'case' sp+ word ws* 'in' ws* (case-item sp)* 'esac'
case-item <-- '('? sp* pattern sp* ')' ((ws ';;' ws) / ((compound-list sp* ';;'?)? ws))
pattern <-- word (sp* '|' sp* word)*
for-clause <-- 'for' sp+ identifier (sp / linebreak)+ ('in' (sp+ word)* sp* sequential-sep)? do-group
for-clause <-- 'for' sp+ identifier ws+ ('in' (sp+ word)* sp* sequential-sep)? do-group
do-group <-- 'do' compound-list 'done'
if-clause <-- 'if' compound-list 'then' compound-list else-part? 'fi'
else-part <-- ('elif' compound-list 'then' compound-list else-part?) / ('else' compound-list)
while-clause <-- 'while' compound-list do-group
until-clause <-- 'until' compound-list do-group
function-def <-- name sp* '(' sp* ')' (sp / linebreak)* function-body
function-def <-- name sp* '(' sp* ')' ws* function-body
function-body <-- compound-command io-redirect*
brace-group <-- '{' sp* compound-list sp* '}'
simple-command <-- (io-redirect sp+)* !reserved word (sp+ (io-redirect / (!reserved word)))*
reserved < ('if' / 'then' / 'else' / 'elif' / 'fi' / 'for' / 'done' / 'do' / 'until' / 'while') (sp / linebreak)
simple-command <-- (io-redirect sp+)* (!(reserved ws+) word) (sp+ (io-redirect / (!(reserved ws+) word)))*
reserved < ('case' / 'esac' / 'if' / 'fi' / 'then' / 'else' / 'elif' / 'for' / 'done' / 'do' / 'until' / 'while')
io-redirect <-- [0-9]* sp* (io-here / io-file)
io-file <-- ('<&' / '>&' / '>>' / '>' / '<>'/ '<' / '>|') sp* ([0-9]+ / filename)
io-here <- ('<<' / '<<-') io-suffix here-document
io-op < '<<-' / '<<' / '<&' / '>&' / '>>' / '>' / '<>'/ '<' / '>|'
io-suffix <- sp* here-label sp* linebreak
io-suffix <- sp* here-label sp* nl
filename <-- word
name <-- identifier
identifier <- [_a-zA-Z][_a-zA-Z0-9]*
word <-- test / substitution / assignment / literal
test <-- ltest (!' ]' .)* rtest
test <-- ltest (!rtest .)* rtest
ltest < '[ '
rtest < ' ]'
substitution <-- ('$' '(' script ')') / ('`' word (sp+ word)* '`')
substitution <-- ('$(' 'ls' ')') / ('`' script '`')
assignment <-- name assign word?
assign < '='
literal <- (subst / delim / (![0-9] (!io-op !sp !linebreak !break !pipe !assign .)+) / ([0-9]+ &separator)) literal*
subst <- '$' ('$' / '*' / '@' / [0-9] / identifier / ([{] (![}] .)+ [}]))
literal <-- (subst / delim / (![0-9] (![()] !io-op !sp !nl !break !pipe !assign .)+) / ([0-9]+ &separator)) literal*
subst <-- '$' ('$' / '*' / '@' / [0-9] / identifier / ([{] (![}] .)+ [}]))
delim <- (['] (!['] .)* [']) / ([\"] (![\"] .)* [\"]) / ([`] (![`] .)* [`])
separator <-- (sp* break (sp / linebreak)*) / (sp / linebreak)+
separator <-- (sp* break ws*) / ws*
break <-- '&' / ';'
sequential-sep <-- (semi (sp / linebreak)*) / (sp / linebreak)+
sequential-sep <-- (semi ws*) / ws+
semi < ';'
linebreak < '\n'
sp < [\t ]")
nl < '\n'
sp < [\t ]
ws < sp / nl
")
(let ((match (match-pattern script input)))
(if (not (eq? (string-length input) (peg:end match)))
@ -77,3 +79,9 @@
(pretty-print "parse error" (current-error-port))
(pretty-print (peg:end match)))
(peg:tree match))))
;; (display 'foo)
;; (newline)
;; (display (parse "for f in a b; do echo $f; ls; done"))
;; (newline)