mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-19 13:49:17 +02:00
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:
parent
4d6d56f002
commit
c63e00453c
3 changed files with 40 additions and 3 deletions
|
@ -17,7 +17,7 @@
|
||||||
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-beginning-of-word parse-end-of-word
|
||||||
parse-word parse-word+)
|
parse-word parse-word+)
|
||||||
(import (chibi) (chibi char-set base) (srfi 9))
|
(import (chibi) (chibi char-set) (srfi 9))
|
||||||
(include "parse/parse.scm")
|
(include "parse/parse.scm")
|
||||||
(cond-expand
|
(cond-expand
|
||||||
(chibi
|
(chibi
|
||||||
|
|
|
@ -455,6 +455,38 @@
|
||||||
;; combinators. A future version may translate pieces into a
|
;; combinators. A future version may translate pieces into a
|
||||||
;; non-backtracking engine where possible.
|
;; non-backtracking engine where possible.
|
||||||
(define (parse-sre x)
|
(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
|
(cond
|
||||||
((procedure? x) ; an embedded parser
|
((procedure? x) ; an embedded parser
|
||||||
x)
|
x)
|
||||||
|
@ -476,7 +508,11 @@
|
||||||
((=> ->) (apply maybe-parse-seq (map parse-sre (cddr x))))
|
((=> ->) (apply maybe-parse-seq (map parse-sre (cddr x))))
|
||||||
((word) (apply parse-word (cdr x)))
|
((word) (apply parse-word (cdr 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
|
(else
|
||||||
(case x
|
(case x
|
||||||
((any) parse-anything)
|
((any) parse-anything)
|
||||||
|
@ -495,7 +531,7 @@
|
||||||
((eol) parse-end-of-line)
|
((eol) parse-end-of-line)
|
||||||
((bos) parse-beginning)
|
((bos) parse-beginning)
|
||||||
((eos) parse-end)
|
((eos) parse-end)
|
||||||
(else (error "unknown sre parser" x))))))
|
(else (error "unknown SRE parser" x))))))
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; delayed combinators for self-referentiality
|
;; delayed combinators for self-referentiality
|
||||||
|
|
|
@ -402,6 +402,7 @@
|
||||||
(guard
|
(guard
|
||||||
(exn
|
(exn
|
||||||
(else
|
(else
|
||||||
|
(write `(exception ,exn)) (newline)
|
||||||
((current-test-handler)
|
((current-test-handler)
|
||||||
(if (assq-ref info 'expect-error) 'PASS 'ERROR)
|
(if (assq-ref info 'expect-error) 'PASS 'ERROR)
|
||||||
(append `((exception . ,exn)) info))))
|
(append `((exception . ,exn)) info))))
|
||||||
|
|
Loading…
Add table
Reference in a new issue