Hello all.
I made this tiny "decent recursive parser" using 2 macros, one for rules and
one for character classes.
An exemple character class definition would go like this :
(defcclass a-or-b (+ #\a #\b))
An exemple rule definition using the character class would go like this :
(defrule couple-letters (+ (cclass a-or-b))
It would match "a" , "ababa" "aaa" "bbb" etc ....pretty simple stuff.
My goal would be to create a reader macro so that the rule definition could
go like this :
(defrule couple-letters (+ $a-or-b))
which would expand to :
(defrule couple-letters (+ (cclass a-or-b))
Browsing the web, I found a couple exemples of reader macros , but they all
seem to be about reading lists using the function "read-delimited-list",
while i want to only read a symbol... Should i read each character and build
the symbol myself or is there a function for this ?
Also i'm a bit concerned by the hyper-spec saying that only a few characters
are reserved for the user.... I see that the $ character is "unspecified"
and could be used by an implementation, does the $ character have any
special meaning in some contexts or should i maybe use one of the standard
characters as an prefix ? (like !$a-or-b for instance)
btw i had a lot of fun making this parser, CL really makes this kind of
stuff quick to code and quick to execute =P
Thanks in advance.
Sacha
"Sacha" <··@address.spam> writes:
> Hello all.
>
> I made this tiny "decent recursive parser" using 2 macros, one for rules and
> one for character classes.
> An exemple character class definition would go like this :
> (defcclass a-or-b (+ #\a #\b))
>
> An exemple rule definition using the character class would go like this :
> (defrule couple-letters (+ (cclass a-or-b))
>
> It would match "a" , "ababa" "aaa" "bbb" etc ....pretty simple stuff.
>
> My goal would be to create a reader macro so that the rule definition could
> go like this :
>
> (defrule couple-letters (+ $a-or-b))
> which would expand to :
> (defrule couple-letters (+ (cclass a-or-b))
>
> Browsing the web, I found a couple exemples of reader macros , but they all
> seem to be about reading lists using the function "read-delimited-list",
> while i want to only read a symbol... Should i read each character and build
> the symbol myself or is there a function for this ?
You can use READ.
Mind the recursive-p parameter.
But do you really need a reader macro? Since you give the form to a
macro of yours, you can analyse it in your macro and expand everything
as you want, including the symbols. A reader macro would be in order
if you wanted to use it in any place, even out of the scope of your
own macro.
> Also i'm a bit concerned by the hyper-spec saying that only a few characters
> are reserved for the user.... I see that the $ character is "unspecified"
> and could be used by an implementation, does the $ character have any
> special meaning in some contexts or should i maybe use one of the standard
> characters as an prefix ? (like !$a-or-b for instance)
In any case, you can always define reader macros in your own readtable.
(let ((*readtable* (copy-readtable)))
(set-macro-character any-char any-fun)
...
(read your-own-stream))
> btw i had a lot of fun making this parser, CL really makes this kind of
> stuff quick to code and quick to execute =P
Yes.
--
__Pascal Bourguignon__ http://www.informatimago.com/
PUBLIC NOTICE AS REQUIRED BY LAW: Any use of this product, in any
manner whatsoever, will increase the amount of disorder in the
universe. Although no liability is implied herein, the consumer is
warned that this process will ultimately lead to the heat death of
the universe.
>
> You can use READ.
> Mind the recursive-p parameter.
That simple !
> But do you really need a reader macro? Since you give the form to a
> macro of yours, you can analyse it in your macro and expand everything
> as you want, including the symbols. A reader macro would be in order
> if you wanted to use it in any place, even out of the scope of your
> own macro.
even better
>> Also i'm a bit concerned by the hyper-spec saying that only a few
>> characters
>> are reserved for the user.... I see that the $ character is "unspecified"
>> and could be used by an implementation, does the $ character have any
>> special meaning in some contexts or should i maybe use one of the
>> standard
>> characters as an prefix ? (like !$a-or-b for instance)
>
> In any case, you can always define reader macros in your own readtable.
>
> (let ((*readtable* (copy-readtable)))
> (set-macro-character any-char any-fun)
> ...
> (read your-own-stream))
So as long as my thing is not calling "external code" i'm all good i guess
> __Pascal Bourguignon__
Thanks a lot Pascal, i'll follow your advice and just check for a $ in the
symbol name, expanding accordingly to it.
Sacha
"Sacha" <··@address.spam> writes:
> Thanks a lot Pascal, i'll follow your advice and just check for a $ in the
> symbol name, expanding accordingly to it.
Or do you need to prefix the symbol by a $?
Once you've defined a character class named a-or-b, it's expected you
can use it in a (+ a-or-b) rule expression.
When you analyse a rule, you check for each symbol if it's defined as
a character class (and then substitute the class for the symbol), or
if it's defined as something else (and else you do what ought to be
done).
--
__Pascal Bourguignon__ http://www.informatimago.com/
PUBLIC NOTICE AS REQUIRED BY LAW: Any use of this product, in any
manner whatsoever, will increase the amount of disorder in the
universe. Although no liability is implied herein, the consumer is
warned that this process will ultimately lead to the heat death of
the universe.
"Pascal Bourguignon" <···@informatimago.com> wrote in message
···················@thalassa.informatimago.com...
> "Sacha" <··@address.spam> writes:
>
>> Thanks a lot Pascal, i'll follow your advice and just check for a $ in
>> the
>> symbol name, expanding accordingly to it.
>
> Or do you need to prefix the symbol by a $?
>
> Once you've defined a character class named a-or-b, it's expected you
> can use it in a (+ a-or-b) rule expression.
>
> When you analyse a rule, you check for each symbol if it's defined as
> a character class (and then substitute the class for the symbol), or
> if it's defined as something else (and else you do what ought to be
> done).
This makes sense, but :
There are rules and character classes that can be refered to this way. They
have different semantic (rules are returning a match object or nil while
character classes only return T or nil)
What if the refered rule or character class is yet to be defined ? I won't
know yet how to handle it's return value.
This could be determined by a first pass , but then i'll need to enclose the
whole thing in an upper level macro (say def-parser).
mhh, maybe should i do it anyways, so that several parsers do not
interfere...
Sacha