(define (grammar) (let ((__start *i*)) (r* (prod))))

(define (prod_debug)
  (let ((__start *i*) (p #f))
    (and (setf p (prod))
         (begin
           (when (>= *LOGLEVEL* 2)
             (printf "~%;>>> ~a~%" (read-parsed-text))
             (pretty-print p))
           p))))

(define (prod)
  (let ((__start *i*) (n #f) (rs #f) (a #f))
    (and (comments)
         (setf n (name))
         (or (and (ws) (literal "=") (setf rs (rules))) #t)
         (or (setf a (action)) #t)
         (declare-locals n rs a))))

(define (rules)
  (let ((__start *i*) (s #f) (ss #f))
    (and (setf s (seq))
         (setf ss (r* (and (and (ws) (literal "|") (seq)))))
         (if (empty? ss) s (cons 'or (cons s ss))))))

(define (seq)
  (let ((__start *i*) (r #f) (rs #f))
    (and (setf r (rule))
         (setf rs (r* (rule)))
         (if (empty? rs) r (cons 'and (cons r rs))))))

(define (rule)
  (let ((__start *i*) (item #f) (repeat #f) (var #f))
    (and (setf item (and (or (group) (option) (scheme) (lit) (atom))))
         (setf repeat (or (and (or (literal "+") (literal "*"))) #t))
         (or (and (literal ":") (setf var (name))) #t)
         (let ((x
                (cond
                 ((equal? repeat "+") `(r+ ,item))
                 ((equal? repeat "*") `(r* ,item))
                 (else item))))
           (if var `(setf ,var ,x) x)))))

(define (group)
  (let ((__start *i*) (rs #f))
    (and (ws) (literal "{") (setf rs (rules)) (ws) (literal "}") `(and ,rs))))

(define (option)
  (let ((__start *i*) (rs #f))
    (and (ws) (literal "[") (setf rs (rules)) (ws) (literal "]") `(or ,rs #t))))

(define (comments) (let ((__start *i*)) (r* (and (or (comment) (nl))))))

(define (comment) (let ((__start *i*)) (and (literal ";") (r* (not_nl)) (nl))))

(define (action) (let ((__start *i*)) (and (ws) (literal "->") (ws) (atext))))

(define (atext)
  (let ((__start *i*))
    (and (or (and (nl) (r* (and (and (ws_) (line))))) (line))
         (read-parsed-text))))

(define (line) (let ((__start *i*)) (and (r* (not_nl)) (nl))))

(define (atom) (let ((__start *i*) (n #f)) (and (setf n (name)) (list n))))

(define (test)
  (let ((__start *i*) (x #f)) (and (setf x (list '(foo bar))) (car x))))

