From caae83f445935c06cd6aef36f283a4688675278a Mon Sep 17 00:00:00 2001 From: Yves Fischer Date: Sun, 14 Aug 2016 19:25:26 +0200 Subject: refactored ebus code --- ebus-racket/3rdparty/bzlib/parseq/basic.ss | 200 ++++++++++++++++++ ebus-racket/3rdparty/bzlib/parseq/combinator.ss | 208 ++++++++++++++++++ ebus-racket/3rdparty/bzlib/parseq/depend.ss | 3 + ebus-racket/3rdparty/bzlib/parseq/example/calc.ss | 51 +++++ ebus-racket/3rdparty/bzlib/parseq/example/csv.ss | 42 ++++ ebus-racket/3rdparty/bzlib/parseq/example/json.ss | 135 ++++++++++++ ebus-racket/3rdparty/bzlib/parseq/example/regex.ss | 163 ++++++++++++++ ebus-racket/3rdparty/bzlib/parseq/example/sql.ss | 138 ++++++++++++ ebus-racket/3rdparty/bzlib/parseq/info.ss | 35 ++++ ebus-racket/3rdparty/bzlib/parseq/input.ss | 83 ++++++++ ebus-racket/3rdparty/bzlib/parseq/main.ss | 32 +++ ebus-racket/3rdparty/bzlib/parseq/primitive.ss | 233 +++++++++++++++++++++ ebus-racket/3rdparty/bzlib/parseq/reader.ss | 41 ++++ ebus-racket/3rdparty/bzlib/parseq/token.ss | 100 +++++++++ ebus-racket/3rdparty/bzlib/parseq/util.ss | 53 +++++ 15 files changed, 1517 insertions(+) create mode 100644 ebus-racket/3rdparty/bzlib/parseq/basic.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/combinator.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/depend.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/example/calc.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/example/csv.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/example/json.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/example/regex.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/example/sql.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/info.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/input.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/main.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/primitive.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/reader.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/token.ss create mode 100644 ebus-racket/3rdparty/bzlib/parseq/util.ss (limited to 'ebus-racket/3rdparty/bzlib/parseq') diff --git a/ebus-racket/3rdparty/bzlib/parseq/basic.ss b/ebus-racket/3rdparty/bzlib/parseq/basic.ss new file mode 100644 index 0000000..4e5d94a --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/basic.ss @@ -0,0 +1,200 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; basic.ss - a set of basic parsers +;; yc 12/31/2009 - first version +;; yc 7/7/2010 - updating real-number to also handle exponents. + +(require "depend.ss" + "primitive.ss" + "combinator.ss" + "input.ss" + ) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; char parsers. +;; digit +(define digit (char-between #\0 #\9)) + +;; not-digit +(define not-digit (char-not-between #\0 #\9)) + +;; lower-case +(define lower-case (char-between #\a #\z)) + +;; upper-case +(define upper-case (char-between #\A #\Z)) + +;; alpha +(define alpha (choice lower-case upper-case)) + +;; alphanumeric +(define alphanumeric (choice alpha digit)) + +;; hexdecimal parser +(define hexdecimal (char-in '(#\a #\b #\c #\d #\e #\f + #\A #\B #\C #\D #\E #\F + #\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9))) + +;; whitespace +(define whitespace (char-in '(#\space #\return #\newline #\tab #\vtab))) + +(define not-whitespace (char-not-in '(#\space #\return #\newline #\tab #\vtab))) + +;; ascii +(define ascii (char-between (integer->char 0) (integer->char 127))) + +;; word = a-zA-Z0-9_ +(define word (choice alphanumeric (char= #\_))) + +;; not-word +(define not-word (char-when (lambda (c) + (not (or (char<=? #\a c #\z) + (char<=? #\A c #\Z) + (char<=? #\0 c #\9) + (char=? c #\_)))))) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; number parsers. + +;; signed +(define sign (zero-one (char= #\-) #\+)) + +;; natural +(define natural (one-many digit)) + +;; decimal +;; there is a bug - anything fails in seq should automatically fail the whole thing... +(define decimal (seq number <- (zero-many digit) + point <- (char= #\.) + decimals <- natural + (return (append number (cons point decimals))))) + +(define (hexdecimals->number hexes) + (define (hex->num hex) + (- (char->integer hex) + (char->integer (case hex + ((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9) #\0) + ((#\a #\b #\c #\d #\e #\f) #\a) + ((#\A #\B #\C #\D #\E #\F) #\A))) + (- (case hex + ((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9) 0) + ((#\a #\b #\c #\d #\e #\f) 10) + ((#\A #\B #\C #\D #\E #\F) 10))))) + (define (helper rest total) + (if (null? rest) + total + (helper (cdr rest) (+ (hex->num (car rest)) (* total 16))))) + ;;(trace helper) + ;;(trace hex->num) + (helper hexes 0)) + +(define hexdecimals (seq num <- (zero-many hexdecimal) + (return (hexdecimals->number num)))) + +;; positive +(define positive (choice decimal natural)) + +;; signed (number) +(define (make-signed parser) + (seq +/- <- sign + number <- parser + (return (cons +/- number)))) + +;; make-number +(define (make-number parser) + (seq n <- parser + (return (string->number (list->string n))))) + +;; natural-number +(define natural-number (make-number natural)) + +;; integer +(define integer (make-number (make-signed natural))) + +;; positive-integer +(define positive-number (make-number positive)) + +;; real-number (now handling exponents) +(define real-number (make-number (choice (seq exp <- (make-signed positive) + e <- (choice #\E #\e) + magenta <- (make-signed natural) + (return (append exp (list e) magenta))) + (make-signed positive) + ))) + +(define hexdecimal-number (make-number hexdecimals)) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; string parsers. + +;; escaped-char +;; allows for an escaping sequence for a particular character... +(define (escaped-char escape char (as #f)) + (seq (char= escape) + c <- (if (char? char) (char= char) char) + (return (if as as c)))) + +;; e-newline +(define e-newline (escaped-char #\\ #\n #\newline)) + +;; e-return +(define e-return (escaped-char #\\ #\r #\return)) + +;; e-tab +(define e-tab (escaped-char #\\ #\t #\tab)) + +;; e-backslash +(define e-backslash (escaped-char #\\ #\\)) + +;; quoted +;; a specific string-based bracket parser +(define (quoted open close escape) + (seq (char= open) + atoms <- (zero-many (choice e-newline + e-return + e-tab + e-backslash + (escaped-char escape close) + (char-not-in (list close #\\)))) + (char= close) + (return atoms))) + +;; make-quoted-string +;; a simplification for creating a string parser +(define (make-quoted-string open (close #f) (escape #\\)) + (seq v <- (quoted open (if close close open) escape) + (return (list->string v)))) + +;; single-quoted-string +;; parse a string with single quotes +(define single-quoted-string (make-quoted-string #\')) + +;; double-quoted-string +;; parse a string with double quotes +(define double-quoted-string (make-quoted-string #\")) + +;; quoted-string +;; choosing between single and double quotes +(define quoted-string + (choice single-quoted-string double-quoted-string)) + +;; whitespaces +;; parsing out all whitespaces together... +(define whitespaces (zero-many whitespace)) + +;; newline +(define newline + (choice (seq r <- (char= #\return) + n <- (char= #\newline) + (return (list r n))) + (char= #\return) + (char= #\newline))) + +(provide (all-defined-out)) diff --git a/ebus-racket/3rdparty/bzlib/parseq/combinator.ss b/ebus-racket/3rdparty/bzlib/parseq/combinator.ss new file mode 100644 index 0000000..b68764d --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/combinator.ss @@ -0,0 +1,208 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; combinator.ss - higher level combinator for parsers... +;; yc 12/31/2009 - first version +;; yc 1/5/2010 - moved delimited, bracket, and alternate to token.ss +(require "depend.ss" + mzlib/defmacro + (for-syntax scheme/base + "depend.ss" + scheme/match + ) + "primitive.ss" + "input.ss" + ) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Parser COMBINATORS + +;; bind +;; Parser a -> (a -> Parser b) -> Parser b +;; this is the function version of the monad - use this when you want to +;; create higher combinators dynamically... +(define (bind parser v->parser) + (lambda (in) + (let-values (((v in) + (parser in))) + ((v->parser v) in)))) + +;; result +;; allows the transformation of the result of the parser... +(define (result parser transform) + (bind parser + (lambda (v) + (if (succeeded? v) + (return (transform v)) + fail)))) + +(define (result* parser transform) + (bind parser + (lambda (v) + (if (and (succeeded? v) (list? v)) + (return (apply transform v)) + fail)))) + +;; seq +;; the macro-based monad for stringing multiple parsers together... +;; (seq parser) => parser +;; (seq v <- parser exp ...) => (bind paser (lambda (v) (if v (seq exp ...) fail)) +(define-macro (seq . exps) + (define *in (gensym 'in)) ;; represents the input + (define *v (gensym 'v)) ;; represents the value + (define literal 'literal) + ;; sequence body for creating a sequence combinator... + (define (body exps) + (match exps + ((list exp) + `((,literal ,exp) ,*in)) + ((list-rest var '<- exp rest) + `(let-values (((,var ,*in) + ((,literal ,exp) ,*in))) + (if (succeeded? ,var) + ,(body rest) + (fail in)))) + ((list-rest exp rest) + (body `(,*v <- ,exp . ,rest))) + )) + `(lambda (in) + (let ((,*in in)) + ,(body exps)))) + +;; sequence +;; a functional version of seq +(define (sequence parsers) + (lambda (IN) + (define (helper parsers in acc) + (if (null? parsers) + ((return (reverse acc)) in) + (let-values (((v in) + ((car parsers) in))) + (if (succeeded? v) + (helper (cdr parsers) in (cons v acc)) + (fail IN))))) + (helper (map literal parsers) IN '()))) + +;; sequence* +(define (sequence* . parsers) + (sequence parsers)) + +;; #| +;; choice +;; (choice parser) => (bind parser (lambda (v) (if v (return v) fail)) +;; (choice parser rest ...) => (bind parser (lambda (v) (if v (choice rest ...) fail))) +(define-macro (choice . exps) + (define *in (gensym 'in)) ;; represents the input + (define *v (gensym 'v)) ;; represents the value + (define (body exps) + (match exps + ((list) + `(fail ,*in)) + ((list-rest exp rest) + `(let-values (((,*v ,*in) + ((literal ,exp) ,*in))) + (if (succeeded? ,*v) + ((return ,*v) ,*in) + ,(body rest)))) + )) + `(lambda (,*in) + ,(body exps))) +;;|# + +;; one-of +;; a function version of choice +(define (one-of parsers) + (lambda (in) + (define (helper parsers) + (if (null? parsers) + (fail in) + (let-values (((v in) + ((car parsers) in))) + (if (succeeded? v) + ((return v) in) + (helper (cdr parsers)))))) + (helper (map literal parsers)))) + +;; one-of* +(define (one-of* . parsers) + (one-of parsers)) + +;; all-of +(define (all-of parsers) + (lambda (in) + (define (helper parsers v) + (if (null? parsers) + ((return v) in) + (let-values (((v IN) + ((car parsers) in))) + (if (succeeded? v) + (helper (cdr parsers) v) + (fail in))))) + (helper (map literal parsers) (make-failed 0)))) + +;; all-of* +(define (all-of* . parsers) + (all-of parsers)) + +;; repeat +;; returns when # of occurence falls within the min and max range +;; default to [1,+inf] +(define (repeat parser (min 1) (max +inf.0)) + (define (make parser) + (lambda (IN) + (define (helper prev-in acc count) + (let-values (((v in) + (parser prev-in))) + (if (succeeded? v) + (if (< count max) + (helper in (cons v acc) (add1 count)) + ((return (reverse acc)) prev-in)) + (if (< count min) + (fail IN) + ((return (reverse acc)) in))))) + (helper IN '() 0))) + (make (literal parser))) + +;; zero-many +;; returns the matched values if zero or more matches +;; (this means that this parser will always match) +(define (zero-many parser) + (repeat parser 0)) + +;; one-many +;; matches if parser parses one or more times +(define (one-many parser) + (repeat parser)) + +;; zero-one +;; returns if the parser matches zero or one times +;; when the parser does not match, it defaults to fail, but you can pass in a +;; default value so it does not fail. +(define (zero-one parser default) + (lambda (in) + (let-values (((v in) + ((literal parser) in))) + ((return (if (succeeded? v) v default)) in)))) + +(provide bind + result + result* + seq + sequence + sequence* + choice + one-of + one-of* + all-of + all-of* + repeat + zero-many + one-many + zero-one + ) diff --git a/ebus-racket/3rdparty/bzlib/parseq/depend.ss b/ebus-racket/3rdparty/bzlib/parseq/depend.ss new file mode 100644 index 0000000..03737ad --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/depend.ss @@ -0,0 +1,3 @@ +#lang scheme +(require "../base/main.ss") +(provide (all-from-out "../base/main.ss")) diff --git a/ebus-racket/3rdparty/bzlib/parseq/example/calc.ss b/ebus-racket/3rdparty/bzlib/parseq/example/calc.ss new file mode 100644 index 0000000..35ada60 --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/example/calc.ss @@ -0,0 +1,51 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; calc.ss - a simple arithmetic calculator +;; yc 12/31/2009 - first version +(require "../main.ss" + ) + +;; determine the operator (currently there are no precedences)... +(define OP (tokens op <- (char-in '(#\+ #\- #\* #\/)) + (return (case op + ((#\+) +) + ((#\-) -) + ((#\*) *) + ((#\/) /))))) + +(define NUMBER (token real-number)) + +;; expr := term op term +(define expr (tokens lhs <- term + (let loop ((lhs lhs)) + (choice (tokens opr <- OP + rhs <- term + (loop (list opr lhs rhs))) + (return lhs))))) +;; term := factor op factor +(define term (tokens lhs <- factor + (let loop ((lhs lhs)) + (choice (tokens opr <- OP + rhs <- factor + (loop (list opr lhs rhs))) + (return lhs))))) + +;; factor := number | ( exp ) +(define factor (choice NUMBER (bracket #\( expr #\)))) + +(define (calc in) + (define (helper exp) + (cond ((number? exp) exp) + ((pair? exp) + (apply (car exp) + (map helper (cdr exp)))))) + (helper ((make-reader expr) in))) + +(provide calc) diff --git a/ebus-racket/3rdparty/bzlib/parseq/example/csv.ss b/ebus-racket/3rdparty/bzlib/parseq/example/csv.ss new file mode 100644 index 0000000..4fd1526 --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/example/csv.ss @@ -0,0 +1,42 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; csv.ss - a customizable csv reader +;; yc 12/31/2009 - first version +(require "../main.ss" + ) + +;; creating a delimiter-based string. +(define (delim-string delim) + (seq s <- (zero-many (choice (escaped-char #\\ delim) + (char-not-in (list delim #\return #\newline)))) + (return (list->string s)))) + +;; csv-string +;; combine between quoted string and delimited string +(define (csv-string delim) + (choice quoted-string (delim-string delim))) + +;; csv-record +;; reads a list of csv-strings by skipping over the delimiters +(define (csv-record delim) + (delimited (csv-string delim) (char= delim))) + +;; csv-table +;; reads over a csv-table +(define (csv-table delim) + (delimited (csv-record delim) newline)) + +;; make-csv-reader +;; creates a csv-reader based on the delim... +(define (make-csv-reader delim) + (make-reader (csv-table delim))) + +;; contract +(provide make-csv-reader) diff --git a/ebus-racket/3rdparty/bzlib/parseq/example/json.ss b/ebus-racket/3rdparty/bzlib/parseq/example/json.ss new file mode 100644 index 0000000..c8df746 --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/example/json.ss @@ -0,0 +1,135 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; json.ss - a parser for the json format +;; yc 1/5/2010 - first version +;; yc 7/76/2010 - updated json-string to handle single quotes. +(require "../main.ss" + ) + +(define hex-digit (seq d <- (choice digit #\a #\b #\c #\d #\e #\f + #\A #\B #\C #\D #\E #\F) + (return (case d + ((#\0) 0) + ((#\1) 1) + ((#\2) 2) + ((#\3) 3) + ((#\4) 4) + ((#\5) 5) + ((#\6) 6) + ((#\7) 7) + ((#\8) 8) + ((#\9) 9) + ((#\a #\A) 10) + ((#\b #\B) 11) + ((#\c #\C) 12) + ((#\d #\D) 13) + ((#\e #\E) 14) + ((#\f #\F) 15))))) + +(define (hex->char h) + (case h + ((0) #\0) + ((1) #\1) + ((2) #\2) + ((3) #\3) + ((4) #\4) + ((5) #\5) + ((6) #\6) + ((7) #\7) + ((8) #\8) + ((9) #\9) + ((10) #\a) + ((11) #\b) + ((12) #\c) + ((13) #\d) + ((14) #\e) + ((15) #\f))) + + +(define (hexes->char hexes) + (integer->char (hexes->integer hexes))) + +(define (char->hexes c) + (integer->hexes (char->integer c))) + +(define (char->hex-chars c) + (map hex->char (char->hexes c))) + +(define (hexes->integer hexes) + (define (helper rest acc) + (cond ((null? rest) acc) + (else + (helper (cdr rest) (+ (* acc 16) (car rest)))))) + (helper hexes 0)) + +(define (integer->hexes i) + (define (helper q acc) + (if (= q 0) + acc + (let-values (((q r) + (quotient/remainder q 16))) + (helper q (cons r acc))))) + (helper i '())) + +(define unicode-char + (seq #\\ #\u + code <- (repeat hex-digit 4 4) + (return (hexes->char code)))) + +(define (json-string/inner quote) + (zero-many (choice e-newline + e-return + e-tab + e-backslash + (escaped-char #\\ quote) + (escaped-char #\\ #\/) + (escaped-char #\\ #\\) + (escaped-char #\\ #\b #\backspace) + (escaped-char #\\ #\f #\page) + unicode-char + (char-not-in (list quote + #\newline + #\return + #\tab + #\\ + #\backspace + #\page)) + ))) + +(define json-string + (choice (seq #\' atoms <- (json-string/inner #\') #\' + (return (list->string atoms))) + (seq #\" atoms <- (json-string/inner #\") #\" + (return (list->string atoms))))) + +(define json-array (tokens v <- (bracket/delimited #\[ json-value #\, #\]) + (return (list->vector v)))) + +(define json-object (tokens v <- (bracket/delimited #\{ json-pair #\, #\}) + (return (make-immutable-hash v)))) + +(define json-pair (tokens key <- (choice json-string + (seq c <- alpha + lst <- (zero-many alphanumeric) + (return (list->string (cons c lst))))) + #\: + value <- json-value + (return (cons key value)))) + +(define json-literal (choice (tokens "true" (return #t)) + (tokens "false" (return #f)) + (tokens "null" (return '())) + )) + +(define json-value (choice json-literal json-array json-object real-number json-string)) + +(define read-json (make-reader json-value)) + +(provide read-json) diff --git a/ebus-racket/3rdparty/bzlib/parseq/example/regex.ss b/ebus-racket/3rdparty/bzlib/parseq/example/regex.ss new file mode 100644 index 0000000..299b999 --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/example/regex.ss @@ -0,0 +1,163 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; regex.ss - a simple regular expression parser +;; yc 1/1/2009 - first version +(require "../main.ss" + mzlib/trace + ) + +;; sof = start of file +(define regex-sof (zero-one (char= #\^) #\$)) + +;; eof = end of file +(define regex-eof (zero-one (char= #\$) #\^)) + +;; meta-chars - a list of meta characters +(define regex-meta-chars '( #\. #\+ #\* #\? #\^ #\$ #\[ #\] #\( #\) #\{ #\} #\\)) + +;; digit = \\d +(define regex-digit (seq "\\d" (return digit))) + +;; not-digit = \\D +(define regex-not-digit (seq "\\D" (return not-digit))) + +;; word = \\w +(define regex-word (seq "\\w" (return word))) + +;; not-word = \\W +(define regex-not-word (seq "\\W" (return not-word))) + +;; whitespace = \\s +(define regex-whitespace (seq "\\s" (return whitespace))) + +;; not-whitespace = \\S +(define regex-not-whitespace (seq "\\S" (return not-whitespace))) + +;; any-char = . +(define regex-any-char (seq #\. (return any-char))) + +;; literal = \\d | \\D | \\w | \\W | \\s | \\S | . | \n | \r | \t | \\ | other chars +(define regex-literal (choice regex-digit + regex-not-digit + regex-word + regex-not-word + regex-whitespace + regex-not-whitespace + regex-any-char + (seq v <- (choice e-newline + e-return + e-tab + (escaped-char #\\ any-char) + (char-not-in regex-meta-chars)) + (return (char= v))))) + +;; atom = literal | group | choice +(define regex-atom (choice regex-literal + regex-group + regex-choice + )) + +;; char-range = -, e.g., a-z +(define regex-char-range (seq lc <- (char-not-in (cons #\- regex-meta-chars)) + #\- + hc <- (char-not-in (cons #\- regex-meta-chars)) + (return `(,char-between ,lc ,hc)))) + +;; choice = [+] +(define regex-choice (seq #\[ + literals <- (one-many (choice regex-char-range + regex-literal)) + #\] + (return `(,one-of* ,@literals)))) + +;; group = (+) +(define regex-group (seq #\( + chars <- (one-many regex-atom) + #\) + (return `(,sequence* ,@chars)))) + +;; regex combinators +;; zero-one = ? +(define regex-zero-one (seq v <- regex-atom + #\? + (return `(,zero-one ,v)))) +;; zero-many = * +(define regex-zero-many (seq v <- regex-atom + #\* + (return `(,zero-many ,v)))) + +;; one-many = + +(define regex-one-many (seq v <- regex-atom + #\+ + (return `(,one-many ,v)))) + +;; range = {min,max} | {times} +(define regex-range (seq v <- regex-atom + #\{ + min <- (zero-one natural-number 0) + max <- (zero-one (seq #\, + max <- (zero-one natural-number +inf.0) + (return max)) + min) + #\} + (return `(,repeat ,v ,min ,max)))) + +;; exp = sof ? * eof ? +(define regex-exp (seq SOF + sof <- regex-sof + atoms <- (zero-many (choice regex-zero-one + regex-zero-many + regex-one-many + regex-range + regex-atom + )) + eof <- regex-eof + EOF + (return `(,regex-parser* ,@(if (char=? sof #\^) + `(,SOF) + '()) + ,@atoms + ,@(if (char=? eof #\$) + `(,EOF) + '()))))) + +;; regex-parser +;; convert the regexp into an useable parser, which including determining +;; whether to allow for +(define (regex-parser parsers) + (let ((regexp (sequence parsers))) + (if (eq? (car parsers) SOF) + regexp + (seq v <- (choice regexp + (seq any-char (regex-parser parsers))) + (return v))))) + +;; regex-parser* +;; the variable arg form of regex-parser +(define (regex-parser* parser . parsers) + (regex-parser (cons parser parsers))) + +;; make-regex-exp +;; wrapper over regex... +(define (make-regex-exp in) + (define (helper exp) + (cond ((list? exp) (apply (car exp) (map helper (cdr exp)))) + (else exp))) + ;; (trace helper) + (let-values (((exp in) + (regex-exp (make-input in)))) + (if (failed? exp) + (error 'make-regex-exp "the regular expression is invalid") + (lambda (in) + ((helper exp) (make-input in)))))) + +(provide regex-parser + make-regex-exp + ) diff --git a/ebus-racket/3rdparty/bzlib/parseq/example/sql.ss b/ebus-racket/3rdparty/bzlib/parseq/example/sql.ss new file mode 100644 index 0000000..3863ab1 --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/example/sql.ss @@ -0,0 +1,138 @@ +#lang scheme +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; sql.ss - parsing the create table statement +;; yc 1/5/2010 - first version +(require "../main.ss" + mzlib/defmacro + (for-syntax scheme/base + scheme/match + ) + (planet bzlib/base) + ) + +(define sql-identifier + (seq c <- alpha + rest <- (zero-many word) + (return (string->symbol + (string-downcase (list->string (cons c rest))))))) + +(define create-table-def + (tokens-ci "create" "table" + name <- sql-identifier + clauses <- (bracket #\( + (delimited clause-def #\,) + #\)) + (return (cons name clauses)))) + +(define clause-def + (choice primary-key-def foreign-key-def column-def)) + +;; making things without order would be quite a difficult combinator. +;; basically we need to try each of the combinator, and then as we have the binding +;; make sure it is returned in a way that can easily be identified... +;; for example, the first +(define (self-and-value parser) + (seq v <- parser + (return (cons parser v)))) + +(define (one-of-each parsers defaults) + ;; we need to try each one, and then figure out the *rest* that weren't matched + ;; continue until we are either out of the stream or out of the combinator... + ;; at any time there is anything that none of them matches then we will be in trouble... + (define (each-helper parsers) + (one-of (map self-and-value parsers))) + (define (sort-helper acc parsers defaults) + (map (lambda (v default) + (if (pair? v) + (cdr v) + default)) + (map (lambda (parser) + (assf (lambda (p) + (eq? p parser)) + acc)) + parsers) + defaults)) + ;; if all of them failed @ the next position, then we need to offer + ;; default values for the remainder of the parsers!!! + ;; this is where it is *interesting!!!... + ;; in such case we want to have a chance to work on the *fail* clause... + ;; this is hmm.... + (define (helper rest acc) + (bind (each-helper rest) + (lambda (v) + (if (succeeded? v) + (let ((rest (remove (car v) rest))) + (if (null? rest) + (return (sort-helper acc parsers defaults)) + (helper rest (cons v acc)))) + (return (sort-helper acc parsers defaults)))))) + (helper parsers '())) + +(define-syntax one-of-each* + (syntax-rules () + ((~ (parser default) ...) + (one-of-each (list parser ...) (list default ...))))) + +(define column-def + (tokens name <- sql-identifier + attrs <- (one-of-each* (type-def 'text) + (nullability 'null) + (inline-primary-key #f) + (inline-foreign-key #f)) + (return (cons name attrs)))) + +(define nullability + (choice (tokens-ci "null" (return 'null)) + (tokens-ci "not" "null" (return 'not-null)))) + +(define type-def + (seq type <- (choice (string-ci= "int") + (string-ci= "integer") + (string-ci= "float") + (string-ci= "text")) + (return (string->symbol type)))) + +(define inline-primary-key + (tokens-ci "primary" "key" (return 'pkey))) +;; (trace inline-primary-key) + +(define sql-identifiers/paren + (bracket #\( (delimited sql-identifier #\,) #\))) + +(define inline-foreign-key + (tokens-ci "foreign" "key" + (zero-one (string-ci= "references") "references") + table <- sql-identifier + (zero-one (string-ci= "on") "on") + columns <- sql-identifiers/paren + (return `(foreign-key ,table ,columns)))) + +(define primary-key-def + (tokens-ci "primary" "key" + name <- (zero-one sql-identifier #f) + columns <- sql-identifiers/paren + (return `(primary-key ,name ,columns)))) + +(define foreign-key-def + (tokens-ci "foreign" "key" + name <- (zero-one sql-identifier #f) + columns <- sql-identifiers/paren + (string-ci= "references") + table <- sql-identifier + (zero-one (string-ci= "on") "on") + fk-columns <- sql-identifiers/paren + (return `(foreign-key ,name ,columns ,table ,fk-columns)))) + +;; (provide create-table-def) +(define sql-def (choice create-table-def)) + +(define read-sql (make-reader sql-def)) + +(provide read-sql) diff --git a/ebus-racket/3rdparty/bzlib/parseq/info.ss b/ebus-racket/3rdparty/bzlib/parseq/info.ss new file mode 100644 index 0000000..689c099 --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/info.ss @@ -0,0 +1,35 @@ +#lang setup/infotab +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; info.ss +;; yc 12/31/2009 - first version +(define name "BZLIB/PARSEQ: a monadic parser combinator library") + +(define blurb + '((p "Inspired by Haskell's Parse, bzlib/parsec provides a monadic parser combinator library that can handle both character and binary data parsing. "))) + +(define release-notes + '((p "0.4 (1 3) - added ability to parse exponents to real-number, and updated read-json to handle single quoted string") + (p "0.3 (1 2) - added additional tokenizers") + (p "0.2 (1 1) - fixed a bug with the all-of combinator") + (p "0.1 (1 0) - first release"))) + +(define categories + '(devtools net misc)) + +(define homepage "http://weblambda.blogspot.com") + +(define required-core-version "4.0") + +(define version "0.3") + +(define repositories '("4.x")) + +(define primary-file "main.ss") + diff --git a/ebus-racket/3rdparty/bzlib/parseq/input.ss b/ebus-racket/3rdparty/bzlib/parseq/input.ss new file mode 100644 index 0000000..406b6f2 --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/input.ss @@ -0,0 +1,83 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; input.ss - holds the abstraction of the input object... +;; yc 12/31/2009 - first version +;; yc 1/8/2009 - fix build-input & Input/c +(require scheme/contract) +;; state +;; the struct that abstracts the input +;; currently this holds an input-port + the position on the port +;; in the future this can be used to hold string, list, vector, etc. +(define-struct input (source pos) #:prefab) + +;; input +;; an utility for converting source into input state. +(define (build-input v (pos 0)) + (define (helper v) + (cond ((input-port? v) v) + ((string? v) (open-input-string v)) + ((bytes? v) (open-input-bytes v)))) + (if (input? v) + (new-input v pos) + (make-input (helper v) pos))) + +;; new-input +;; make a new input based on the old input and a new position... +(define (new-input input incr) + (make-input (input-source input) + (+ incr (input-pos input)))) + +;; peek-bytes* +;; return a funtion that will make a particular amount of reading based on +;; the requested size... +(define (peek-bytes* size) + (lambda (in) + (peek-bytes size (input-pos in) (input-source in)))) + +;; peek-string* +;; return a function that will read a particular size of string... +;; this can fail since it is expected to be using utf-8 as the input size... +(define (peek-string* size) + (lambda (in) + (peek-string size (input-pos in) (input-source in)))) + +;; peek-byte* +;; peek a single byte +(define (peek-byte* in) + (peek-byte (input-source in) (input-pos in))) + +;; peek-char* +;; peek a single char +(define (peek-char* in) + (peek-char (input-source in) (input-pos in))) + +;; read-bytes* +;; read out the bytes based on the size of the input... +(define (read-bytes* in) + (read-bytes (input-pos in) (input-source in))) + +(define Input/c (or/c input? bytes? string? input-port?)) + +(define Parser/c (-> Input/c (values any/c Input/c))) + +(provide input + input? + input-source + input-pos + (rename-out (build-input make-input)) + new-input + peek-bytes* + peek-string* + peek-byte* + peek-char* + read-bytes* + Input/c + Parser/c + ) \ No newline at end of file diff --git a/ebus-racket/3rdparty/bzlib/parseq/main.ss b/ebus-racket/3rdparty/bzlib/parseq/main.ss new file mode 100644 index 0000000..407ef93 --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/main.ss @@ -0,0 +1,32 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; main.ss - wrapper around the main modules +;; yc 12/31/2009 - first version +;; yc 1/5/2010 - added token.ss +;; yc 1/18/2010 - add reader.ss + +(require "input.ss" + "util.ss" + "primitive.ss" + "combinator.ss" + "basic.ss" + "token.ss" + "reader.ss" + ) +(provide (all-from-out "input.ss" + "util.ss" + "primitive.ss" + "combinator.ss" + "basic.ss" + "token.ss" + "reader.ss" + ) + ) + diff --git a/ebus-racket/3rdparty/bzlib/parseq/primitive.ss b/ebus-racket/3rdparty/bzlib/parseq/primitive.ss new file mode 100644 index 0000000..2fcece5 --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/primitive.ss @@ -0,0 +1,233 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; primitive.ss - holds the primitive parsers... +;; yc 12/31/2009 - first version +;; yc 1/5/2010 - added literal & literal-ci +;; yc 1/18/2010 - move make-reader to reader.ss + +(require "depend.ss" + "util.ss" + "input.ss" + scheme/contract + ) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; primitive parsers + +;; return +(define (return v (size 0)) + (lambda (in) + (values v + (new-input in size)))) + +;; struct failed - represents failed parse... +(define-struct failed (pos) #:prefab) + +;; succeeded? +(define (succeeded? v) (not (failed? v))) + +;; fail - the parser that returns failed with the current port position. +(define (fail in) + (values (make-failed (input-pos in)) + in)) + +;; SOF (start-of-file) +;; returns true only when the input-pos = 0 +(define (SOF in) + ((if (= (input-pos in) 0) + (return 'sof) + fail) in)) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; item-based primitive parsers + +;; item +;; the fundamental building block +(define (item peek isa? satisfy? size) + (lambda (in) + (let ((v (peek in))) + ((if (and (isa? v) (satisfy? v)) + (return v (size v)) + fail) in)))) + +;; bytes= +;; parses if the next part of the input matches the exact bytes +(define (bytes= bytes) + (let ((size (bytes-length bytes))) + (item (peek-bytes* size) + bytes? + (lambda (b) + (bytes=? b bytes)) + (the-number size)))) + +;; string= +;; parses if the next part of the input matches the exact string +(define (string= s (comp? string=?)) + (let ((size (string-bytes/utf-8-length s))) + (item (peek-string* size) + string? + (lambda (str) + (comp? str s)) + (the-number size)))) + +(define (string-ci= s) + (string= s string-ci=?)) + +;; byte-when +;; return the next byte when satisfy matches +(define (byte-when satisfy? (isa? byte?) (size (the-number 1))) + (item peek-byte* isa? satisfy? size)) + +;; any-byte +;; return the next byte +(define any-byte (byte-when identity)) + +;; byte= +(define (byte= b) (byte-when (lambda (v) + (= b v)))) + +;; EOF +;; return if the next byte is eof +(define EOF (byte-when identity eof-object? (the-number 0))) + +;; bits= +;; matches a byte @ the bits level... (pass in the individual bits) +(define (bits= bits) + (byte-when (lambda (b) (= b (bits->byte bits))))) + +;; byte-in +(define (byte-in bytes) + (byte-when (lambda (b) (member b bytes)))) + +(define (byte-not-in bytes) + (byte-when (lambda (b) (not (member b bytes))))) + +(define (byte-between lb hb) + (byte-when (lambda (b) (<= lb b hb)))) + +(define (byte-not-between lb hb) + (byte-when (compose not (lambda (b) (<= lb b hb))))) + +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; character-based parsers + +;; char-when +;; the fundamental character-based parser +(define (char-when satisfy?) + (item peek-char* char? satisfy? char-utf-8-length)) + +;; any-char +;; return the next character +(define any-char (char-when identity)) + +;; char= +;; return the next character if it equals c +(define (char= c (comp? char=?) (trans identity)) + (char-when (lambda (v) (trans (comp? c v))))) + +;; char-ci= +(define (char-ci= c) (char= c char-ci=?)) + +;; char-not +;; return the next character if it is not c +(define (char-not= c (comp? char=?)) (char= c comp? not)) + +;; char-ci-not +(define (char-ci-not= c) (char-not= char-ci=?)) + +;; char-between +;; return the next character if it falls in between lc & hc +(define (char-between lc hc (comp? char<=?) (trans identity)) + (char-when (lambda (v) (trans (comp? lc v hc))))) + +;; char-ci-between +(define (char-ci-between lc hc) (char-between lc hc char-ci<=?)) + +(define (char-not-between lc hc (comp? char<=?)) + (char-between lc hc comp? not)) + +;; char-ci-not-between +(define (char-ci-not-between lc hc) (char-not-between lc hc char-ci<=?)) + +;; char-in +;; return the next character if it one of the chars +(define (char-in chars (comp? char=?) (trans identity)) + (char-when (lambda (v) + (trans (memf (lambda (c) + (comp? c v)) + chars))))) + +;; char-ci-in +(define (char-ci-in chars) (char-in chars char-ci=?)) + +;; char-not-in +;; return the next character if it is not one of the characters +(define (char-not-in chars (comp? char=?)) (char-in chars comp? not)) + +;; char-ci-not-in +(define (char-ci-not-in chars) (char-not-in chars char-ci=?)) + +;; literal +;; returns a parser based on the passed in literal +(define (literal p) + (cond ((char? p) (char= p)) + ((byte? p) (byte= p)) + ((string? p) (string= p)) + ((bytes? p) (bytes= p)) + (else p))) + +;; literal-ci +;; a ci version of literal +(define (literal-ci p) + (cond ((char? p) (char-ci= p)) + ((string? p) (string-ci= p)) + (else (literal p)))) + +(define Literal/c (or/c string? bytes? char? byte?)) + +(define Literal-Parser/c (or/c Literal/c Parser/c)) + +(provide return + (struct-out failed) + succeeded? + fail + SOF + item + bytes= + string= + string-ci= + byte-when + any-byte + byte= + EOF + bits= + byte-in + byte-not-in + byte-between + byte-not-between + char-when + any-char + char= + char-ci= + char-not= + char-ci-not= + char-between + char-ci-between + char-not-between + char-ci-not-between + char-in + char-ci-in + char-not-in + char-ci-not-in + literal + literal-ci + Literal/c + Literal-Parser/c + ) diff --git a/ebus-racket/3rdparty/bzlib/parseq/reader.ss b/ebus-racket/3rdparty/bzlib/parseq/reader.ss new file mode 100644 index 0000000..50a5f9d --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/reader.ss @@ -0,0 +1,41 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; reader.ss - move make-reader & Reader/c here +;; yc 1/18/2010 - first version +;; yc 1/21/2010 - make-reader to take on additional default params +(require "depend.ss" + "input.ss" + "primitive.ss" + "combinator.ss" + (prefix-in c: scheme/contract) + ) +;; use this to create a reader that will read the bytes if the parse succeeds. +(define (make-reader parser #:sof? (sof? #t) #:eof? (eof? #t) #:default (default #f)) + (lambda (in #:sof? (sof? sof?) #:eof? (eof? eof?) #:default (default default)) + (let-values (((v in) + ((seq (if sof? SOF (return #t)) + v <- parser + (if eof? EOF (return #t)) + (return v)) (make-input in)))) + (unless (failed? v) (read-bytes* in)) + (if (failed? v) + default + v)))) + +(define Reader/c (c:->* (Input/c) + (#:sof? boolean? #:eof? boolean? #:default c:any/c) + c:any)) +(provide Reader/c) +(c:provide/contract + (make-reader (c:->* (Parser/c) + (#:sof? boolean? #:eof? boolean? #:default c:any/c) + Reader/c)) + ) + diff --git a/ebus-racket/3rdparty/bzlib/parseq/token.ss b/ebus-racket/3rdparty/bzlib/parseq/token.ss new file mode 100644 index 0000000..cbeb492 --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/token.ss @@ -0,0 +1,100 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; token.ss - token-based parser combinators. +;; yc 1/5/2010 - first version +;; yc 1/31/2010 - add tokens/by to allow for custom tokenizer, fix token to consume trailing whitespaces as well... +(require "primitive.ss" + "combinator.ss" + "basic.ss" + "input.ss" + mzlib/defmacro + (for-syntax scheme/base + scheme/match + ) + scheme/list + ) + +;; token +;; tokenizing a particular value... +(define (token parser (delim whitespaces)) + (seq delim + t <- parser + delim + (return t))) + +(define (token/pre parser (delim whitespaces)) + (seq delim t <- parser (return t))) + +(define-macro (tokens/by tokenizer . exps) + (define (body exps) + (match exps + ((list exp) (list exp)) + ((list-rest v '<- exp rest) + `(,v <- (,tokenizer ,exp) . ,(body rest))) + ((list-rest exp rest) + `((,tokenizer ,exp) . ,(body rest))))) + `(seq . ,(body exps))) + +;; tokens +;; generating a sequence of tokens... +(define-macro (tokens . exps) + `(tokens/by token . ,exps)) + +;; token-ci +;; the literal tokens for string & character are case-insensitive +(define-macro (tokens-ci . exps) + `(tokens/by (compose token literal-ci) . ,exps)) + +;; alternate +;; alternate between 2 parsers - ideally used for parsing delimited input +;; you can choose whether you want to have the delimiter returned... +(define (alternate parser1 parser2) + (tokens v <- parser1 + v2 <- (zero-many (seq v1 <- parser2 + v3 <- parser1 + (return (list v1 v3)))) + (return (flatten (cons v v2))))) + +;; delimited +;; same as alternate, except the delimiters are parsed out and not returned +(define (delimited parser delim (tokenizer token)) + (tokens/by tokenizer + v <- parser + v2 <- (zero-many (tokens/by tokenizer + v3 <- delim + v4 <- parser + (return v4))) + (return (cons v v2)))) + +;; bracket +;; parsing bracketed structures... +(define (bracket open parser close) + (tokens open + v <- parser + close + (return v))) + +;; bracket/delimited +(define (bracket/delimited open parser delim close) + (tokens open ;; even the parser is optional... + v <- (zero-one (delimited parser delim) '()) + close + (return v))) + +(provide token + token/pre + tokens/by + tokens + tokens-ci + alternate + delimited + bracket + bracket/delimited + ) diff --git a/ebus-racket/3rdparty/bzlib/parseq/util.ss b/ebus-racket/3rdparty/bzlib/parseq/util.ss new file mode 100644 index 0000000..822ce3c --- /dev/null +++ b/ebus-racket/3rdparty/bzlib/parseq/util.ss @@ -0,0 +1,53 @@ +#lang scheme/base +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PARSEQ.PLT +;; A Parser Combinator library. +;; +;; Bonzai Lab, LLC. All rights reserved. +;; +;; Licensed under LGPL. +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; util.ss - an utility module... the code might be moved out of here... +;; yc 12/31/2009 - first version + +(require mzlib/etc + ) + +;; the-number +;; makes a function that returns a particular number no matter what +;; args are passed in +(define (the-number n) + (lambda args n)) + +;; bits->byte +;; convert a list of bits into its corresponding byte (or integer...) +;; note the byte can be greater than 255 +(define (bits->byte bits) + (define (->i bit) + (case bit + ((0 #f) 0) + ((1 #t) 1))) + (apply + + (map (lambda (bit exponent) + (* (->i bit) (expt 2 exponent))) + bits + (reverse (build-list (length bits) identity))))) + +;; byte->bits +;; the reverse of converting byte to bits... +(define (byte->bits b) + (define (helper q acc) + (cond ((= 0 q) acc) + (else + (let-values (((q r) + (quotient/remainder q 2))) + (helper q (cons r acc)))))) + (helper b '())) + +;; string-bytes/utf-8-length +;; return the bytes length for a string (instead of character length) +(define (string-bytes/utf-8-length s) + (bytes-length (string->bytes/utf-8 s))) + +(provide (all-defined-out)) + -- cgit v1.2.1