<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Tahoma
}
--></style>
</head>
<body class='hmmessage'><div dir='ltr'>
Thank you, Neil.<BR>
<BR>
I really appreciate your answer. I've just started programming with syntax-rules and I see now that I have lot to learn further about these scheme-way macros.<BR>
Unfortunately, i'm currently unable to produce this macro with syntax-rules or syntax-case.<BR>
<BR>
But i have done it in classic, "old fasioned" way:<BR>
<BR>
#lang racket<BR>
<BR>
(require mzlib/defmacro (for-syntax racket))<BR>
<BR>
(define-macro (automaton init-state transitions)<BR> (let* ([curr-state (gensym)]<BR> [make-transition (lambda (transition)<BR> (let ([state (first transition)]<BR> [endstate (third transition)])<BR> `((,state) (set! ,curr-state ,endstate) ,(if (eq? endstate 'END) <BR> ''endstate<BR> ''ok))))]<BR> [make-state (lambda (state-def)<BR> (let ([state-name (first state-def)]<BR> [transitions (cddr state-def)])<BR> `(,state-name<BR> (lambda (symbol)<BR> (case symbol<BR> ,@(map make-transition transitions)<BR> (else 'transition-error))))))])<BR> `(letrec ([,curr-state null]<BR> [END<BR> (lambda (symbol)<BR> 'read-past-end-error)]<BR> ,@(map make-state transitions))<BR> (set! ,curr-state ,init-state)<BR> (lambda (c)<BR> (,curr-state c)))))<BR>
<BR>
<BR>(define mydfa<BR> (automaton start<BR> ((start : (c -> more))<BR> (more : (a -> more)<BR> (d -> more)<BR> (r -> END)))))<BR> <BR><BR>
<BR>
By the way, i have created stateful dfa purposely (by using variable curr-state as DFA's state) so that i can "feed" it with symbols, one by one, i.e.<BR>
<BR>
> (mydfa 'c)<BR>ok<BR>> (mydfa 'a)<BR>ok<BR>> (mydfa 'd)<BR>ok<BR>> (mydfa 'r)<BR>endstate<BR>
<BR>
Shriram's approach (described here: <A href="http://www.cs.brown.edu/~sk/Publications/Papers/Published/sk-automata-macros/paper.pdf">http://www.cs.brown.edu/~sk/Publications/Papers/Published/sk-automata-macros/paper.pdf</A> ) forces us to give input all in one take.<BR>
<BR>
<BR>
Racket Noob<BR> <BR>
<DIV>
> Date: Fri, 12 Aug 2011 10:22:18 -0400<BR>> From: neil@neilvandyke.org<BR>> To: racketnoob@hotmail.com<BR>> CC: users@racket-lang.org<BR>> Subject: Re: [racket] Problem with macro<BR>> <BR>> 1. Without trying it, I'm pretty sure this particular syntax <BR>> transformation can be done in "syntax-rules", but I'm not certain it can <BR>> be done using only the power of "..." in "syntax-rules", without a <BR>> helper macro. Your life might be easier if you do this particular <BR>> transformation in "syntax-case" rather than "syntax-rules".<BR>> <BR>> 2. If you use "syntax-rules" instead of "syntax-case", three tips: (1) <BR>> break it up into mutiple macros, so you can have secret recursive helper <BR>> macros that have arguments for lists of input that you haven't processed <BR>> and arguments for lists of output from that processing, such as for <BR>> assembling lists of "letrec" or "case" clauses; (2) instead of <BR>> "process-state", you can have your helper macros assemble some of the <BR>> ultimate code *bottom-up*, so that, for example, things like the <BR>> "letrec" clauses (or "case" clauses, or parts of "case" clauses) get <BR>> assembled first, and only after all the clauses are assembled do the <BR>> "letrec" and other unchanging stuff around them get assembled; and (3) <BR>> it's good to expand to "case"/"if"/"and"/"or" for control flow, but <BR>> avoid expanding to "cond", because it's syntactic-sugary, and you'd have <BR>> to worry about "else" and "=>" appearing in your macro input.<BR>> <BR>> 3. You've picked a somewhat tricky macro for "syntax-rules" -- harder <BR>> than most "syntax-rules" macros you'll usually want to implement. But <BR>> once you can implement this macro, I think you'll then have the tools to <BR>> implement most any other "syntax-rules" macro you want to in the <BR>> future. If you get stuck on this one, try simpler ones that isolate a <BR>> single tricky part. For example, contrive a programming exercise of a <BR>> macro that's a thin veneer around "case", and implement your macro using <BR>> a recursive helper macro rather than "...", to assemble each "case" <BR>> clause, one clause per recursion step. (Or just use "syntax-case", and <BR>> be done with it.)<BR>> <BR>> 4. Before you spend too much time writing a macro for that particular <BR>> transformation, you might want to experiment some more with that example <BR>> you gave of code you're trying to transform to. See whether your state <BR>> transitions can simply can use tail calls to your "letrec" bindings for <BR>> the state closures, so that you need neither the "curr-state" variable <BR>> not the "ok" and "endstate" values. That would be more <BR>> Racket-idiomatic, the compiler might be able to optimize the code <BR>> better, and it might make your macro easier to implement.<BR>> <BR>> (Pardon the writing in enumerations, but someone erroneously put caf <BR>> coffee in the decaf coffee carafe.)<BR>> <BR>> -- <BR>> http://www.neilvandyke.org/<BR></DIV>                                            </div></body>
</html>