(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))) )) ))