1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

Add '*' PEG

The s-expression representation of PEG grammars now uses a '(* ...)' form
instead of '(body lit ... *)'.
This commit is contained in:
Noah Lavine 2011-09-19 10:24:56 -04:00 committed by Andy Wingo
parent 5c3f2da81f
commit f310a111de
3 changed files with 28 additions and 7 deletions

View file

@ -69,7 +69,7 @@ succeeds.
@code{"a*"}
@code{(body lit a *)}
@code{(* a)}
@end deftp
@deftp {PEG Pattern} {one or more} a

View file

@ -237,6 +237,26 @@ return EXP."
#,(cggr (baf accum) 'cg-body
#'(reverse body) #'new-end)))))))))))))
(define (cg-* args accum)
(syntax-case args ()
((pat)
#`(lambda (str strlen at)
(let ((body '()))
(let lp ((end at) (count 0))
(let* ((match (#,(peg-sexp-compile #'pat (baf accum))
str strlen end))
(new-end (if match (car match) end))
(count (if (> new-end end) (1+ count) count)))
(if (> new-end end)
(push-not-null! body (single-filter (cadr match))))
(if (and (> new-end end)
#,#t)
(lp new-end count)
(let ((success #,#t))
#,#`(and success
#,(cggr (baf accum) 'cg-body
#'(reverse body) #'new-end)))))))))))
;; Association list of functions to handle different expressions as PEGs
(define peg-compiler-alist '())
@ -250,6 +270,7 @@ return EXP."
(add-peg-compiler! 'and cg-and)
(add-peg-compiler! 'or cg-or)
(add-peg-compiler! 'body cg-body)
(add-peg-compiler! '* cg-*)
;; Takes an arbitrary expressions and accumulation variable, then parses it.
;; E.g.: (peg-sexp-compile syntax '(and "abc" (or "-" (range #\a #\z))) 'all)

View file

@ -68,11 +68,11 @@ RB < ']'
(body lit (and peg-nonterminal (or "<--" "<-" "<") peg-sp peg-pattern) +))
(define-sexp-parser peg-pattern all
(and peg-alternative
(body lit (and (ignore "/") peg-sp peg-alternative) *)))
(* (and (ignore "/") peg-sp peg-alternative))))
(define-sexp-parser peg-alternative all
(body lit (and (body lit (or "!" "&") ?) peg-sp peg-suffix) +))
(define-sexp-parser peg-suffix all
(and peg-primary (body lit (and (or "*" "+" "?") peg-sp) *)))
(and peg-primary (* (and (or "*" "+" "?") peg-sp))))
(define-sexp-parser peg-primary all
(or (and "(" peg-sp peg-pattern ")" peg-sp)
(and "." peg-sp)
@ -80,11 +80,11 @@ RB < ']'
peg-charclass
(and peg-nonterminal (body ! "<" 1))))
(define-sexp-parser peg-literal all
(and "'" (body lit (and (body ! "'" 1) peg-any) *) "'" peg-sp))
(and "'" (* (and (body ! "'" 1) peg-any)) "'" peg-sp))
(define-sexp-parser peg-charclass all
(and (ignore "[")
(body lit (and (body ! "]" 1)
(or charclass-range charclass-single)) *)
(* (and (body ! "]" 1)
(or charclass-range charclass-single)))
(ignore "]")
peg-sp))
(define-sexp-parser charclass-range all (and peg-any "-" peg-any))
@ -92,7 +92,7 @@ RB < ']'
(define-sexp-parser peg-nonterminal all
(and (body lit (or (range #\a #\z) (range #\A #\Z) (range #\0 #\9) "-") +) peg-sp))
(define-sexp-parser peg-sp none
(body lit (or " " "\t" "\n") *))
(* (or " " "\t" "\n")))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; PARSE STRING PEGS