[beginner] I need a macro (probably)
Posted: Thu Sep 05, 2013 8:59 am
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.
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.
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.
where I have tried all-names to be
and
among other things
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.
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.