Hello everyone,
I've written a recursive-decsent parser generator. it accepts a
grammar and creates a function for each non-terminal in the grammar, a
parser and a kind of lexical analyzer.
its arguments are like this:
(make-rdp ((?S ?A ?B) ;nonterminals
(a b c d) ;terminals
?S ;start symbol
((?S a ?S ?A) ;productions
(?S c c)
(?A ?B b)
(?b d d)))
i'd like to know if it is possible to simply call the macro thus:
(make-rdp grammar)
where `grammar' contains the grammar specified above.
Thanks,
Vijay L
······@lycos.com (Vijay L) writes:
> Hello everyone,
> I've written a recursive-decsent parser generator. it accepts a
> grammar and creates a function for each non-terminal in the grammar, a
> parser and a kind of lexical analyzer.
>
> its arguments are like this:
> (make-rdp ((?S ?A ?B) ;nonterminals
> (a b c d) ;terminals
> ?S ;start symbol
> ((?S a ?S ?A) ;productions
> (?S c c)
> (?A ?B b)
> (?b d d)))
>
> i'd like to know if it is possible to simply call the macro thus:
> (make-rdp grammar)
> where `grammar' contains the grammar specified above.
Apparently MAKE-RDP parses its argument directly. In that case, you
can still do (make-rdp #.grammar), but only if grammar is known at
compile time (which you can ensure with EVAL-WHEN).
Regards,
--
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."
PGP key ID 0x42B32FC9
In article <····························@posting.google.com>,
Vijay L <······@lycos.com> wrote:
>Hello everyone,
>I've written a recursive-decsent parser generator. it accepts a
>grammar and creates a function for each non-terminal in the grammar, a
>parser and a kind of lexical analyzer.
>
>its arguments are like this:
>(make-rdp ((?S ?A ?B) ;nonterminals
> (a b c d) ;terminals
> ?S ;start symbol
> ((?S a ?S ?A) ;productions
> (?S c c)
> (?A ?B b)
> (?b d d)))
>
>i'd like to know if it is possible to simply call the macro thus:
>(make-rdp grammar)
>where `grammar' contains the grammar specified above.
If you wanted to be able to do this, why did you define it as a macro in
the first place? You should define it as a function, and then if you want
a macro interface it's simple to add:
(defmacro defrdp (grammar)
`(make-rdp ',grammar))
Given that you have a macro, you can use EVAL to invoke it with evaluated
arguments:
(eval `(make-rdp ,grammar))
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin <······@genuity.net> wrote in message news:<················@paloalto-snr1.gtei.net>...
> In article <····························@posting.google.com>,
> Vijay L <······@lycos.com> wrote:
> >Hello everyone,
> >I've written a recursive-decsent parser generator. it accepts a
> >grammar and creates a function for each non-terminal in the grammar, a
> >parser and a kind of lexical analyzer.
> >
> >its arguments are like this:
> >(make-rdp ((?S ?A ?B) ;nonterminals
> > (a b c d) ;terminals
> > ?S ;start symbol
> > ((?S a ?S ?A) ;productions
> > (?S c c)
> > (?A ?B b)
> > (?b d d)))
> >
> >i'd like to know if it is possible to simply call the macro thus:
> >(make-rdp grammar)
> >where `grammar' contains the grammar specified above.
>
> If you wanted to be able to do this, why did you define it as a macro in
> the first place? You should define it as a function, and then if you want
> a macro interface it's simple to add:
>
> (defmacro defrdp (grammar)
> `(make-rdp ',grammar))
I cannot do the above because the macro generates code. For eg.
(pprint
(macroexpand-1
'(make-parser ( ;grammar that accepts all strings with an odd
;number of 1s [ones]
(?s ?a)
(1)
?s
((?s 1 ?a)
(?a 1 ?s)
(?a nil) ;nil is epsilon
)))))
i have changed the resulting code to lower case
(progn
(defvar *current-token* ())
(defvar *sentence* ())
(defvar *grammar* (quote
((?s ?a)
(1)
?s
((?s 1 ?a) (?a 1 ?s) (?a nil)))))
(defun next-token ()
(setf *current-token* (pop *sentence*)))
(defun restore (sentence token)
(setf *sentence* sentence
*current-token* token)
'nil)
(defun ?a ()
(let ((save-sent *sentence*)
(save-ct *current-token*))
(cond ((cond ((eq *current-token* '1)
(next-token)
(cond ((?s) t)
(t (restore save-sent save-ct))))
(t (restore save-sent save-ct))))
((cond (t t) (t (restore save-sent save-ct)))))))
(defun ?s ()
(let ((save-sent *sentence*)
(save-ct *current-token*))
(cond ((cond ((eq *current-token* '1)
(next-token)
(cond ((?a) t)
(t (restore save-sent save-ct))))
(t (restore save-sent save-ct)))))))
(defun parse (sentence)
(setq *sentence* sentence)
(next-token)
(?S)))
> Given that you have a macro, you can use EVAL to invoke it with evaluated
> arguments:
>
> (eval `(make-rdp ,grammar))
Sir, in your article (ALU: Lisp Programming Style) you say:
EVAL. Novices almost always misuse EVAL. When experts use EVAL, they
often would be better off using APPLY, FUNCALL, or SYMBOL-VALUE. Use
of EVAL when defining a macro should set off a warning bell -- macro
definitions are already evaluated during expansion. See also the
answer to question 3-12. The general rule of thumb about EVAL is: if
you think you need to use EVAL, you're probably wrong.
given that I am a novice, and you an expert, the use of EVAL is
obviously justified here. Can you tell me when and where the use of
EVAL *is* justified or, show me a reference where I may find such
material or, does something like this grow only with experience?
Thanks,
Vijay
In article <···························@posting.google.com>,
Vijay L <······@lycos.com> wrote:
>Barry Margolin <······@genuity.net> wrote in message
>news:<················@paloalto-snr1.gtei.net>...
>> If you wanted to be able to do this, why did you define it as a macro in
>> the first place? You should define it as a function, and then if you want
>> a macro interface it's simple to add:
>>
>> (defmacro defrdp (grammar)
>> `(make-rdp ',grammar))
>
>I cannot do the above because the macro generates code. For eg.
You wrote it, you can fix that, can't you? Instead of generating
(defun next-token ()
(setf *current-token* (pop *sentence*)))
it can execute:
(setf (symbol-function 'next-token)
#'(lambda () (setf *current-token* (pop *sentence*))))
>Sir, in your article (ALU: Lisp Programming Style) you say:
>
>EVAL. Novices almost always misuse EVAL. When experts use EVAL, they
>often would be better off using APPLY, FUNCALL, or SYMBOL-VALUE. Use
>of EVAL when defining a macro should set off a warning bell -- macro
>definitions are already evaluated during expansion. See also the
In this case you're not using it in the definition of the macro.
>answer to question 3-12. The general rule of thumb about EVAL is: if
>you think you need to use EVAL, you're probably wrong.
But one of the few appropriate uses of EVAL is to supply runtime-generated
data to something that's only available as a macro.
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin <······@genuity.net> wrote in message news:<g%O69.6$%>
> You wrote it, you can fix that, can't you? Instead of generating
>
> (defun next-token ()
> (setf *current-token* (pop *sentence*)))
>
> it can execute:
>
> (setf (symbol-function 'next-token)
> #'(lambda () (setf *current-token* (pop *sentence*))))
If I do that, will I be able to compile the functions `generated' so?
Any function defined by DEFUN is available in global scope, will a
function defined the above specified way also be available the same
way?
> >Sir, in your article (ALU: Lisp Programming Style) you say:
> >
> >EVAL. Novices almost always misuse EVAL. When experts use EVAL, they
> >often would be better off using APPLY, FUNCALL, or SYMBOL-VALUE. Use
> >of EVAL when defining a macro should set off a warning bell -- macro
> >definitions are already evaluated during expansion. See also the
>
> In this case you're not using it in the definition of the macro.
>
> >answer to question 3-12. The general rule of thumb about EVAL is: if
> >you think you need to use EVAL, you're probably wrong.
>
> But one of the few appropriate uses of EVAL is to supply runtime-generated
> data to something that's only available as a macro.
Thank you.
Thanks,
Vijay L
In article <····························@posting.google.com>,
Vijay L <······@lycos.com> wrote:
>Barry Margolin <······@genuity.net> wrote in message news:<g%O69.6$%>
>> You wrote it, you can fix that, can't you? Instead of generating
>>
>> (defun next-token ()
>> (setf *current-token* (pop *sentence*)))
>>
>> it can execute:
>>
>> (setf (symbol-function 'next-token)
>> #'(lambda () (setf *current-token* (pop *sentence*))))
>
>If I do that, will I be able to compile the functions `generated' so?
Yes, the functions will be compiled when the function containing the
assignment is compiled. E.g. if you have:
(defun make-adder (x)
#'(lambda (y) (+ x y)))
when you compile MAKE-ADDER, the function that will be included in the
closures that it returns will also be compiled.
>Any function defined by DEFUN is available in global scope, will a
>function defined the above specified way also be available the same
>way?
SETF of SYMBOL-FUNCTION updates the symbol's global function binding.
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Barry Margolin <······@genuity.net> writes:
> In article <····························@posting.google.com>,
> Vijay L <······@lycos.com> wrote:
>
> >Any function defined by DEFUN is available in global scope, will a
> >function defined the above specified way also be available the same
> >way?
>
> SETF of SYMBOL-FUNCTION updates the symbol's global function binding.
The only caveat is that defining a function this way might circumvent
some niceties in your development environment.
--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'
In article <···············@mudslide.OCF.Berkeley.EDU>,
Thomas F. Burdick <···@mudslide.OCF.Berkeley.EDU> wrote:
>Barry Margolin <······@genuity.net> writes:
>
>> In article <····························@posting.google.com>,
>> Vijay L <······@lycos.com> wrote:
>>
>> >Any function defined by DEFUN is available in global scope, will a
>> >function defined the above specified way also be available the same
>> >way?
>>
>> SETF of SYMBOL-FUNCTION updates the symbol's global function binding.
>
>The only caveat is that defining a function this way might circumvent
>some niceties in your development environment.
In many cases, the same thing happens when the function is defined as a
result of expanding a macro.
--
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
······@lycos.com (Vijay L) writes:
>
> Barry Margolin <······@genuity.net> wrote in message news:<g%O69.6$%>
> > You wrote it, you can fix that, can't you? Instead of generating
> >
> > (defun next-token ()
> > (setf *current-token* (pop *sentence*)))
> >
> > it can execute:
> >
> > (setf (symbol-function 'next-token)
> > #'(lambda () (setf *current-token* (pop *sentence*))))
>
> If I do that, will I be able to compile the functions `generated' so?
You can always explicitly call the compiler at runtime:
(setf (symbol-function 'next-token)
(compile nil
#'(lambda () (setf *current-token* (pop *sentence*)))))
or more succinctly by
(compile 'next-token
#'(lambda () (setf *current-token* (pop *sentence*))))
> Any function defined by DEFUN is available in global scope, will a
> function defined the above specified way also be available the same
> way?
Yes.
--
Thomas A. Russ, USC/Information Sciences Institute ···@isi.edu