program <- ws* rule+ { `(define (parser input offset) ,@(second data) (((parse_program)) input offset)) } rule <- id ws* "<-" ws* ordered-expr-list ws_or_nl* { `(define (,(make-name (first data))) (lambda () ,(fifth data))) } ordered-expr-list <- expr-list ws* "/" ws* ordered-expr-list { (let ((tail (fifth data))) (if (eq? (first tail) 'either) `(either ,(first data) ,@(cdr tail)) `(either ,(first data) ,(fifth data)))) } / expr-list { (first data) } expr-list <- expr (ws+ expr-list)* { (if (or (null? (second data)) (and (not (pair? (second data))) (string=? (second data) ""))) (first data) (let ((tail (second (first (second data))))) (if (eq? (first tail) 'seq) `(seq ,(first data) ,@(cdr tail)) `(seq ,(first data) ,tail)))) } expr <- simple-expr "*" { `(many ,(first data)) } / simple-expr "+" { `(many1 ,(first data)) } / simple-expr "?" / simple-expr { (first data) } simple-expr <- string { (first data) } / action / id { (make-scheme-call-rule-closure (make-name (first data))) } / bracketed-rule { (first data) } / "!." / "!" expr { `(negate ,(second data)) } / character-class { (first data) } / "." { `(match-any-char 'dummy) } bracketed-rule <- "()" / "(" ws* ordered-expr-list ws* ")" { (third data) } id <- [ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_]+ { (char-list-to-string (first data)) } character-class <- "[" (not_right_bracket .)+ "]" { `(match-char ',(fix-escapes (zip-second (second data)))) } string <- [\"] (![\"] .)* [\"] { `(match-string ,(char-list-to-string (zip-second (second data)))) } action <- [\{] (![\}] .)* [\}] { `(make-action ,(char-list-to-string (fix-escapes (zip-second (second data))))) } not_right_bracket <- !"]" ws <- [ \t] nl <- [\n] ws_or_nl <- ws/nl