;;; Grammar used: ;;; ;;; id --> letter, rest ;;; ;;; rest --> "" ;;; rest --> dash, char, rest ;;; ;;; dash --> "" ;;; dash --> "-" ;;; ;;; char --> letter ;;; char --> digit ;;; ;;; 'letter' and 'digit' nonterminals are implemented by ;;; Lisp predicates alpha-char-p and digit-char-p, respectively. (defun identifier (str) (id str ()) ) (defun id (str stack) "True when STR has a prefix that is an identifier and the rest of STR can be parsewd sucessfully with the predicates in STACK." (check str (cons #'letra (cons #'resto stack))) ) (defun check (str stack) (if (null stack) (string= str "") (funcall (car stack) str (cdr stack)) ) ) (defun letra (str stack) (and (> (length str) 0) (alpha-char-p (elt str 0)) (check (subseq str 1) stack) ) ) (defun digito (str stack) (and (> (length str) 0) (digit-char-p (elt str 0)) (check (subseq str 1) stack) ) ) (defun resto (str stack) (or (check str stack) (check str (cons #'traco (cons #'carac (cons #'resto stack)))) ) ) (defun traco (str stack) (or (check str stack) (and (> (length str) 0) (string= (elt str 0) "-") (check (subseq str 1) stack) ) ) ) (defun carac (str stack) (or (letra str stack) (digito str stack) ) )