(use-package 'yacc) (defun list-lexer (list) #'(lambda () (let ((value (pop list))) (if (null value) (values nil nil) (let ((terminal (cond ((member value '(+ - * / |(| |)|)) value) ((integerp value) 'int) ((symbolp value) 'id) (t (error "Unexpected value ~S" value))))) (values terminal value)))))) (eval-when (compile load eval) (defun i2p (a b c) "Infix to prefix" (list b a c)) (defun k-2-3 (a b c) (declare (ignore a c)) b) ) (define-parser *expression-parser* (:start-symbol expression) (:terminals (int id + - * / |(| |)|)) (:precedence ((:left * /) (:left + -))) (expression (expression + expression #'i2p) (expression - expression #'i2p) (expression * expression #'i2p) (expression / expression #'i2p) term) (term id int (- term) (|(| expression |)| #'k-2-3))) (parse-with-lexer (list-lexer '(x * - - 2 + 3 * y)) *expression-parser*)