anchor.diff:    (partial-vocabulary-word #'verb-completions))
   (defun partial-adverb ()
     (partial-vocabulary-word #'adverb-completions))
  -
  -;; #+nil(defun sentence ()
  -;;   (=let* ((adverb1 (maybe (=prog1 (adverb) (ws)) 'error))
  -;;           (verb (verb))
  -;;           (noun-clause-1 (maybe (=and (ws) (noun-clause)) 'error))
  -;;           (noun-clause-2 (maybe (=and (ws) (noun-clause)) 'error))
  -;;           (adverb2 (maybe (=and (ws) (adverb)) 'error)))
  -;;     (result `(:sentence
  -;;               (:adverb1 . ,adverb1)
  -;;               (:verb . ,verb)
  -;;               (:noun-clause-1 . ,noun-clause-1)
  -;;               (:noun-clause-2 . ,noun-clause-2)
  -;;               (:adverb2 . ,adverb2)))))
  -
  -;; ;; noun-clause = [[[adverb ws] preposition ws] noun-group]
  -;; (defun noun-clause ()
  -;;   ;; TODO
  -;;   (noun-group))
  -
  -;; ;; noun-group =  noun-phrase 0*(["," ws] conjunction noun-phrase)
  -;; (defun noun-group ()
  -;;   (=let* ((x (noun-phrase))
  -;;           (y (zero-or-more (conjed-noun-phrase))))
  -;;     (result (cons x y))))
  -;; (defun conjed-noun-phrase ()
  -;;   (=let* ((comma (maybe (=and (=char #\,) (ws))))
  -;;           (_ (if comma (maybe (=prog1 (conjunction) (ws))) (=prog2 (ws) (conjunction) (ws))))
  -;;           (np (noun-phrase)))
  -;;     (result np)))
  -
  -;; ;; conjunction = "and" / "&"
  -;; (defun conjunction ()
  -;;   (=or (=string "and")
  -;;        (=string "&")))
  -
  -;; ;; noun-phrase = [cardinal ws] 0*(adjective ws) noun
  -;; ;; noun-phrase =/ [article ws] [ordinal ws] 0*(adjective ws) \
  -;; ;;                (noun / possessive-noun ws noun-phrase)
  -;; (defun noun-phrase ()
  -;;   (=or (=let* ((cardinal (=prog1 (cardinal) (ws)))
  -;;                (adjective (zero-or-more (=prog1 (adjective) (ws))))
  -;;                (noun (noun)))
  -;;          (result (list :noun-phrase
  -;;                        :cardinal cardinal
  -;;                        :adjectives adjective
  -;;                        :noun noun)))
  -;;        (=let* ((article (maybe (=prog1 (article) (ws))))
  -;;                (ordinal (=and (=not (cardinal)) (maybe (=prog1 (ordinal) (ws)))))
  -;;                (adjective (zero-or-more (=prog1 (adjective) (ws))))
  -;;                (noun (noun)))
  -;;          ;; TODO - What this should -really- return is the id of the game object, itself. If it
  -;;          ;;        fails to bind to an object, then the parser itself can fail. This could be used
  -;;          ;;        to stop the all-powerful hunger of the adjective parser.
  -;;          (result (list :noun-phrase
  -;;                        :article article
  -;;                        :ordinal ordinal
  -;;                        :adjectives adjective
  -;;                        :noun noun)))))
  -
  -;; ;; article = "the" / "a"
  -;; (defun article ()
  -;;   (=or (=string "the")
  -;;        (=string "a")))
  -
  -;; ;; adjective = A dashed-word. Later validated against the noun it's attached to.
  -;; (defun adjective ()
  -;;   (dashed-word))
  -
  -;; ;; noun = A dashed-word that identifies a present, visible object.
  -;; (defun noun ()
  -;;   (dashed-word))
  -
  -;; ;; possessive-noun = noun ("'"/"'s")
  -;; (defun possessive-noun ()
  -;;   (=let* ((name (text (alpha-char)))
  -;;           (_ (=and (=char #\') (maybe (=char #\s)))))
  -;;     (result (cons :possessive name))))
  -
  -;; (defun nounp (maybe-noun)
  -;;   maybe-noun)
  
positive.code:     (if (adverbp adverb)
          (result `(:adverb . ,adverb))
          (fail :error (format nil "'~A' is not an adverb." adverb)))))
  
  ;;;
  ;;; Dialogue
  ;;;
  (defun to/at-someone ()
    (=let* ((at/to (=or (=string "at")
                        (=string "to")
                        (=string "@")))
            (_ (ws))
            (target-name (dashed-word)))
      (result `(:at/to . ,(concatenate 'string at/to " " target-name)))))
  
  ;; parenthetical = "(" ("@"|"to"|"at") name | adverb ")"
  (defun parenthetical ()
    (=let* ((_ (=char #\())
            (content (=or (to/at-someone) (adverb)))
            (_ (=char #\))))
      (result `(:parenthetical . ,(cdr content)))))
  
  ;; dialogue = [parenthetical ws] text
  (defun dialogue ()
    (=let* ((parenthetical (maybe (=prog1 (parenthetical) (ws))))
            (dialogue-text (if parenthetical
                               (text)
                               (=and (=not (=char #\())
                                     (text)))))
      (result `(:dialogue
                (:parenthetical . ,(cdr parenthetical))
                (:dialogue . ,dialogue-text)))))
  
  (defun parse-dialogue (message)
    (let ((results (invoke-parser (either (dialogue) 'error) message)))
      (cond ((cdr results)
             (error "Parse was ambiguous."))
            ((typep (car results) 'error)
             (error (car results)))
            (t (values (cdr (assoc :dialogue (cdar results)))
                       (cdr (assoc :parenthetical (cdar results))))))))
  
  ;;;
  ;;; Full-sentence action parser
  
negative.code:            (error (car results)))
            (t (let ((sentence (cdar results)))
                 (apply #'invoke-verb-command :actor actor (alist-plist sentence)))))))
  
  ;;;
  ;;; Dialogue
  ;;;
  (defun to/at-someone ()
    (=let* ((at/to (=or (=string "at")
                        (=string "to")
                        (=string "@")))
            (_ (ws))
            (target-name (dashed-word)))
      (result `(:at/to . ,(concatenate 'string at/to " " target-name)))))
  
  ;; parenthetical = "(" ("@"|"to"|"at") name | adverb ")"
  (defun parenthetical ()
    (=let* ((_ (=char #\())
            (content (=or (to/at-someone) (adverb)))
            (_ (=char #\))))
      (result `(:parenthetical . ,(cdr content)))))
  
  ;; dialogue = [parenthetical ws] text
  (defun dialogue ()
    (=let* ((parenthetical (maybe (=prog1 (parenthetical) (ws))))
            (dialogue-text (if parenthetical
                               (text)
                               (=and (=not (=char #\())
                                     (text)))))
      (result `(:dialogue
                (:parenthetical . ,(cdr parenthetical))
                (:dialogue . ,dialogue-text)))))
  
  (defun parse-dialogue (message)
    (let ((results (invoke-parser (either (dialogue) 'error) message)))
      (cond ((cdr results)
             (error "Parse was ambiguous."))
            ((typep (car results) 'error)
             (error (car results)))
            (t (values (cdr (assoc :dialogue (cdar results)))
                       (cdr (assoc :parenthetical (cdar results))))))))
  
  ;;;
  ;;; Partial-sentence completion
  