I am trying to parse some text and I am using the esrap library. Even if you are not familiar with it, please read on because you can perhaps still answer my question.
Code: Select all
(require :esrap)
(defpackage :my-grammar
(:use :cl :esrap))
(in-package :my-grammar)
(defparameter *currency-names*
'((usd . "USD")
(eur . "EUR")
(gbp . "GBP")))
(defun name-for-symbol (symbol table)
(cdr (assoc symbol table)))
(defun symbol-for-name (name table)
(car (rassoc name table :test 'equal)))
(defrule currency (or "USD" "EUR" "GBP") ;;esrap's defrule is a macro
(:lambda (name)
(symbol-for-name (text name) *currency-names*)))
Code: Select all
MY-GRAMMAR> (parse 'currency "USD")
USD
NIL
Code: Select all
(defrule currency (or (all-names *currencies*)) ;; this is not working
(:lambda (name)
(symbol-for-name (text name) *currency-names*)))
Code: Select all
(defun all-names (table)
(mapcar #'cdr table))
Code: Select all
(defmacro all-names (table)
`(mapcar #'cdr ,table))
I guess all-names must be a macro and not a function and I guess the problem is that my all-names returns ("USD" "EUR" "GBP"), while the "or" in defrule expects the list to be spliced. So if only I could create the list (or "USD" "EUR" "GBP") and give it to defrule. Also I read somewhere that I should use some instead of or in similar(?) cases, but some requires a predicate (in addition to a list) and I can't think of one.
I assume this might be simple, but I am a beginner in lisp. Any help would be appreciated. For anyone wishing to try, you should be able to run the above code if you load esrap using quicklisp first.