program <- ws* rule+ { `(define (parser pctx offset) (begin ,@(second data) (((parse_program)) pctx offset))) } rule <- id ws* "<-" ws* ordered-expr-list ws_or_nl* { `(define (,(make-name (first data))) (let* ((parser ,(fifth data))) (lambda () (lambda (ctx offset) (let* ((ctx2 (parser ctx offset))) (if (ctx-failed? ctx2) (fail) (succeed (clone-ctx ctx ,(first data)) (ctx-value ctx2) (ctx-start-index ctx2) (ctx-end-index ctx2)))))))) } 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) 'glyph-seq) `(glyph-seq ,(first data) ,@(cdr tail)) `(glyph-seq ,(first data) ,tail))))) } expr <- simple-expr "*" { `(many ,(first data)) } / simple-expr "+" { `(many1 ,(first data)) } / simple-expr "?" { `(optional, (first data)) } / simple-expr { (first data) } simple-expr <- string { (first data) } / action / "@" id { `(match ,(second data)) } / id { (make-scheme-call-rule-closure2 (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 <- [0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_]+ { (char-list-to-string (first data)) } character-class <- "[" (not_right_bracket .)+ "]" { `(match-char ',(fix-escapes2 (zip-second (second data)))) } string <- [\"] (![\"] .)* [\"] { `(match-string ,(char-list-to-string (zip-second (second data)))) } action <- [\{] (escaped-char / non-escaped-char)* [\}] { (make-glyph-action2 (char-list-to-string (fix-escapes2 (second data)))) } escaped-char <- [\\] . { (second data) } non-escaped-char <- ![\}] . { (second data) } not_right_bracket <- !"]" ws <- [ \t] nl <- [\n] ws_or_nl <- ws/nl