Adding SRE char-set handling to (chibi parse).

I wanted to avoid the full char-set dependency, but
it's too useful and the alternatives to ugly in grammars.
This commit is contained in:
Alex Shinn 2013-03-09 19:16:26 +09:00
parent 4d6d56f002
commit c63e00453c
3 changed files with 40 additions and 3 deletions

View file

@ -17,7 +17,7 @@
parse-beginning-of-line parse-end-of-line
parse-beginning-of-word parse-end-of-word
parse-word parse-word+)
(import (chibi) (chibi char-set base) (srfi 9))
(import (chibi) (chibi char-set) (srfi 9))
(include "parse/parse.scm")
(cond-expand
(chibi

View file

@ -455,6 +455,38 @@
;; combinators. A future version may translate pieces into a
;; non-backtracking engine where possible.
(define (parse-sre x)
(define (ranges->char-set ranges)
(let lp ((ls ranges) (res (char-set)))
(cond
((null? ls)
res)
((string? (car ls))
(lp (append (string->list (car ls)) (cdr ls)) res))
((null? (cdr ls))
(error "incomplete range in / char-set" ranges))
(else
(let ((cs (ucs-range->char-set (char->integer (car ls))
(+ 1 (char->integer (cadr ls))))))
(lp (cddr ls) (char-set-union cs res)))))))
(define (sre-list->char-set ls)
(apply char-set-union (map sre->char-set ls)))
(define (sre->char-set x)
(cond
((char? x) (char-set x))
((string? x) (if (= 1 (string-length x))
(string->char-set x)
(error "multi-element string in char-set" x)))
((pair? x)
(if (and (string? (car x)) (null? (cdr x)))
(string->char-set (car x))
(case (car x)
((/) (ranges->char-set (cdr x)))
((~) (char-set-complement (sre-list->char-set (cdr x))))
((-) (apply char-set-difference (map sre->char-set (cdr x))))
((&) (apply char-set-intersection (map sre->char-set (cdr x))))
((or) (sre-list->char-set (cdr x)))
(else (error "unknown SRE char-set operator" x)))))
(else (error "unknown SRE char-set" x))))
(cond
((procedure? x) ; an embedded parser
x)
@ -476,7 +508,11 @@
((=> ->) (apply maybe-parse-seq (map parse-sre (cddr x))))
((word) (apply parse-word (cdr x)))
((word+) (apply parse-word+ (cdr x)))
(else (error "unknown sre list parser" x))))
((/ ~ & -) (parse-char (sre->char-set x)))
(else
(if (string? (car x))
(parse-char (sre->char-set x))
(error "unknown SRE operator" x)))))
(else
(case x
((any) parse-anything)
@ -495,7 +531,7 @@
((eol) parse-end-of-line)
((bos) parse-beginning)
((eos) parse-end)
(else (error "unknown sre parser" x))))))
(else (error "unknown SRE parser" x))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; delayed combinators for self-referentiality

View file

@ -402,6 +402,7 @@
(guard
(exn
(else
(write `(exception ,exn)) (newline)
((current-test-handler)
(if (assq-ref info 'expect-error) 'PASS 'ERROR)
(append `((exception . ,exn)) info))))