chibi-scheme/lib/chibi/parse.sld
2013-06-04 04:26:01 +09:00

79 lines
3.4 KiB
Scheme

(define-library (chibi parse)
(export grammar grammar/unmemoized define-grammar define-grammar/unmemoized
call-with-parse parse parse-fully parse-fold
parse->list parse-fully->list
file->parse-stream string->parse-stream parse-stream-substring
parse-stream-start? parse-stream-end? parse-stream-ref
parse-anything parse-nothing parse-epsilon
parse-seq parse-and parse-or parse-not
parse-repeat parse-repeat+ parse-optional
parse-map parse-map-substring parse-ignore parse-assert
parse-atomic parse-commit parse-memoize
parse-char parse-not-char parse-char-pred
parse-string parse-token parse-sre
parse-beginning parse-end
parse-beginning-of-line parse-end-of-line
parse-beginning-of-line parse-end-of-line
parse-beginning-of-word parse-end-of-word
parse-word parse-word+
parse-with-failure-reason)
(import (chibi) (chibi char-set) (srfi 9))
(include "parse/parse.scm")
(cond-expand
(chibi
(begin
(define-syntax grammar-bind
(er-macro-transformer
(lambda (expr rename compare)
(let ((name (cadr expr))
(k (car (cddr expr)))
(f (cadr (cddr expr)))
(bindings (car (cddr (cddr expr)))))
(if (and (identifier? name)
(not (assq name bindings)))
(let ((new-tmp (rename 'new-tmp))
(save-tmp (rename 'save-tmp))
(lambda_ (rename 'lambda))
(set!_ (rename 'set!))
(s (rename 's))
(i (rename 'i))
(sk (rename 'sk))
(fk (rename 'fk))
(r (rename 'r)))
(append
k
(list
`(,lambda_
(,s ,i ,sk ,fk)
((,lambda_ (,save-tmp)
(,f ,s ,i
(,lambda_ (,r ,s ,i ,fk)
(,set!_ ,new-tmp ,r)
(,sk ,r ,s ,i ,fk))
(,lambda_ (,s ,i ,r)
(,set!_ ,new-tmp ,save-tmp)
(,fk ,s ,i ,r))))
,new-tmp))
(cons (list name new-tmp) bindings))))
(append k (list f bindings)))))))))
(else
(begin
(define-syntax grammar-bind
(syntax-rules ()
((grammar-bind name (k ...) f ((var tmp) ...))
(let-syntax ((new-symbol?
(syntax-rules (var ...)
((new-symbol? name sk fk) sk)
((new-symbol? _ sk fk) fk))))
;; Bind the name only to the first instance in the pattern.
(new-symbol?
random-symbol-to-match
(k ...
(lambda (s i sk fk)
(let ((save-tmp new-tmp))
(f s i
(lambda (r s i fk) (set! new-tmp r) (sk r s i fk))
(lambda (s i r) (set! new-tmp save-tmp) (fk s i r)))))
((var tmp) ... (name new-tmp)))
(k ... f ((var tmp) ...)))))))))))