  
(defun parse (fragment to-parse &key (mandatory t) &aux keyword)

  ;; Parse the given sentence/fragment.
  ;; Depending on the input parsing rule, we could be
  ;; parsing a single word vs. a terminal, or a new sequence,
  ;; optionally with control keywords.

  (format t "Parsing ~s expecting ~s. ~%" fragment to-parse)
  (cond
    ((null fragment)
     (print 'no-more-sentence) nil)
    ((null to-parse)
     (print 'no-more-parse) nil)
    ((atom fragment)
     (format t "???Trashed fragment ~s found.~&" fragment) nil)
    (t
     (cond
       ((atom to-parse)		   ;We have a rule or a terminal
	(cond
	  ((terminal-p to-parse)   ;Parse 1 word
	   (when (parse-word (car fragment) to-parse :mandatory mandatory)
	     (log-parse to-parse)
	     (return-from parse (cdr fragment) )))
	  ((rule-p to-parse)
	   (parse-by-rule fragment to-parse))
	  ))
				   ;We have either a keyword phrase
				   ;or a new sequence
       ((null			   ;If it's not a keyword,
	  (keywordp (setq keyword (car to-parse))))
	(parse-seq fragment (car to-parse)))	   ;parse the sequence.

       ((equal keyword :either)	   ;If this is an either/or,
	(cond			   ;see where we are.
	  ((null (cdr to-parse))   ;This is the end of things
	   
	   (let ((leftover fragment)
	      (dolist (try-parse (cdr to-parse) fragment)
		(when (null (setq leftover (parse fragment try-parse :mandatory nil)))
	    (log-parse try-parse)
	    (return-from parse (cdr fragment))))
	(format t "?All parses failed, found ~s expecting ~s.~&"
		fragment to-parse))))))
       (t (format t "???Unknown parse keyword ~s in ~s.~&"
		  (car to-parse) (cdr to-parse)))
       ))
    ))
