program <- ws* rule+ { `(progn (let ((rules ',(second data))) (progn (let ((*rules* (loop for (name body) in rules collect (list name (funcall (eval body)))))) (funcall (cadr (assoc '|parse_program| *rules*)) 0))))) } rule <- id ws* "<-" ws* ordered-expr-list ws_or_nl* { `(,(make-name (first data)) #'(lambda () ,(fifth data))) } ordered-expr-list <- expr-list ws* "/" ws* ordered-expr-list { (let ((tail (fifth data))) (if (equal (first tail) 'either) `(either ,(first data) ,@(rest tail)) `(either ,(first data) ,(fifth data)))) } / expr-list { (first data) } expr-list <- expr (ws+ expr-list)* { (if (or (equal (second data) "") (null (second data))) (first data) (let ((tail (second (first (second data))))) (if (equal (first tail) 'seq) `(seq ,(first data) ,@(rest 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-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 (map 'list #'(lambda (string) (elt string 0)) (zip-second (second data))))) } string <- [\"] (![\"] .)* [\"] { `(match-string ,(char-list-to-string (zip-second (second data)))) } action <- [\{] (![\}] .)* [\}] { `(make-action ,(char-list-to-string (fix-escapes (map 'list #'(lambda (string) (elt string 0)) (zip-second (second data)))))) } not_right_bracket <- !"]" ws <- [ \t] nl <- [\n] ws_or_nl <- ws/nl