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