Hello,
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.
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.
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.
(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*)))
The above works as intended, that is it recognizes the input if it is one of the three currency names and returns the corresponding symbol.
MY-GRAMMAR> (parse 'currency "USD")
USD
NIL
But I want to change the definition of the rule like this, so that the names of the currencies are not hard-coded, because this would avoid code duplication and because I have to parse other things in a way similar to currencies.
(defrule currency (or (all-names *currencies*)) ;; this is not working
(:lambda (name)
(symbol-for-name (text name) *currency-names*)))
where I have tried all-names to be
(defun all-names (table)
(mapcar #'cdr table))
and
(defmacro all-names (table)
`(mapcar #'cdr ,table))
among other thingsI 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.