anchor.diff:                                      (cons (grammar-start-nonterminal grammar)
                                             (finite-set-list (finite-set-remove nonterminals start)))))
            (hash (make-hash-table :test #'equal)))
  -    ;; index nonterminals
  -    (dotimes (i (length nonterm-array))
  -      (setf (gethash (aref nonterm-array i) hash) i))
  +    ;; index symbol case numbers
  +    (loop
  +       with k = -1
  +       for x across nonterm-array
  +       do (setf (gethash (list x) hash) (incf k))
  +         (do-finite-set (z terminals)
  +           (when (funcall table x z)
  +             (setf (gethash (cons x z) hash) (incf k)))))
       ;; output stuff
  -    (labels ((nonterm-label (X) (csymbol X "nonterm_")))
  +    (labels ((case-label (X &optional a)
  +               (if a
  +                   (csymbol (list X a) "prod_")
  +                   (csymbol X "nonterm_")))
  +             (case-number (x &optional a) (gethash (cons x a) hash))
  +             (collect-tails (tail)
  +               (cond
  +                 ;; no more symbols, return
  +                 ((null tail)
  +                  '((:return 0)))
  +                 ;; tail nonterminal, tail optimize
  +                 ((and (null (cdr tail))
  +                       (finite-set-inp (car tail) nonterminals))
  +                  `((:goto ,(case-label (car tail)))))
  +                  ;; non-tail nonterminal, call
  +                  ((finite-set-inp (car tail) nonterminals)
  +                   `((:if (:!= 0 (:call ,function-name "context"
  +                                        ,(case-number (car tail) nil)))
  +                          ((:return -1)))
  +                     ,@(collect-tails (cdr tail))))
  +                  ;; terminal, check it
  +                  ((finite-set-inp (car tail) terminals)
  +                   `((:if (:! ,(c-parser-test (car tail) "context"))
  +                          ((:return -1)))
  +                     ,@(collect-tails (cdr tail))))
  +                  (t (error "Unknown symbol type ~A" (car tail))))))
         (with-c-output output
           (when header (c-indent-format "~A" header))
           (c-indent-format "/*****************/~&")
  
positive.code:      (with-c-block
         (map nil #'c-gen body)))
      ((:if test then-clause &optional else-clause)
       (with-c-nest ((c-indent-format "if ( ~A )" (c-exp test)))
         (map nil #'c-gen then-clause))
       (when else-clause
         (with-c-nest ((c-indent-format "else"))
           (map nil #'c-gen else-clause))))
      ((:comment str)
       (c-indent-format "// ~A" str))
      (a
  
negative.code:         (with-c-nest ((c-indent-format "int ~A( ~A context, int i )" function-name context-type))
            ;; nonterms
            (with-c-nest ((c-indent-format "switch( i )"))
              (loop
                 for X across nonterm-array
                 do
                 ;; nonterminal label
                   (c-gen `(:seq (:case ,(case-number X nil))
                                 (:label ,(case-label X))))
                 ;; test each following production
                   (do-finite-set (a terminals)
                     (let ((production (funcall table X a)))
                       ;; got a live production
                       (when production
                         (c-gen `(:comment ,production))
                         (c-gen (destructuring-bind (head term0 &rest rest) production
                                  (assert (equal X head))
                                  `(:if ,(c-parser-test a "context")
                                        ((:case ,(case-number X a))
                                         (:label ,(case-label X a))
                                         ,@(cond
                                            ;; eat first terminal and continue
                                            ((and (equal term0 a)
                                                  rest)
                                             (collect-tails rest))
                                            ;; eat first terminal and done
                                            ((and (equal term0 a)
                                                  (null rest))
                                             (list '(:return 0)))
                                            ((and (finite-set-inp term0 nonterminals)
                                                  rest)
                                             ;; Production starts with nonterminal, recurse
                                             `((:if (:call ,function-name "context"
                                                           ,(case-number term0 a))
                                                    ,(collect-tails rest)
                                                    ((:return -1)))))
                                            ((and (finite-set-inp term0 nonterminals)
                                                  (null rest))
                                             ;; Production starts with nonterminal, jump
                                             `((:goto ,(case-label term0 a))))
                                            (t (error "Can't handle production ~A" production))))))))))
                 ;; no match, syntax error
                   (c-gen '(:return -1)))
              ;; default
  