LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (May 2009, week 2)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Wed, 13 May 2009 13:27:30 -0700
Reply-To:     "Huang, Ya" <Ya.Huang@AMYLIN.COM>
Sender:       "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From:         "Huang, Ya" <Ya.Huang@AMYLIN.COM>
Subject:      Re: Macro quoting again !
Comments: To: "Terjeson, Mark" <Mterjeson@russell.com>
Comments: cc: Chang Chung <chang_y_chung@HOTMAIL.COM>
In-Reply-To:  <16FD64291482A34F995D2AF14A5C932C07437D7E@MAIL002.prod.ds.russell.com>
Content-Type: text/plain; charset="us-ascii"

Thank you Chang and Mark, both suggestions work. Though I'm getting dizzy by these many of %%%%%%%% :-)

-----Original Message----- From: Terjeson, Mark [mailto:Mterjeson@russell.com] Sent: Wednesday, May 13, 2009 1:11 PM To: Huang, Ya; SAS-L@LISTSERV.UGA.EDU Subject: RE: Macro quoting again !

Hi Ya,

The resolving of macros, as I've mentioned before, when you think of SAS macros in terms of text substitution coupled with staying aware of how many times it will make passes until all macro goodies found have been resolved, will help you find the problem here.

Example: We know that on the first pass through the macro processor it looks for &, %, and other macro goodies. If we have &myvar the first pass will find one ampersand and then look in the macro variable lookup table for MYVAR and if found, return the contents.

If we want the contents of MYVAR to actually BE the macro variable name for some other storage item we would fetch the other storage item indirectly with &&&myvar for this the macro processor gobbles up double && and %% and leave you with just one. That way the first pass through, doing some mental text substitution the &&&myvar would find the first two && ampersands and return one ampersand as well as seeing next the &myvar and fetching the contents ofthe myvar storage. Let's say that the MYVAR storage contained ABC. Then &&&myvar after the first pass through would resolve to &abc and then on the second pass &abc would get resolved and the contents of abc loaded.

It gets a little tricky because having one macro call another macro DOES NOT process and resolve the inner macro call first and then process the outer macro. You may know other porogramming languages that have macro routines which like objects one could call the other. Here in SAS land, the SAS macro goodies are not entities or objects or independent routines being called. The SAS macro processing merely scans the code text submitted and looks for string patterns to do text substitution on. (of course in a much more glorified sense) Therefore, in your example below you must think of the macro processor scanning all the text from the top down (and it could care less of boundaries or statements, etc. It is just ignoring most of the code and only responding to the macro goodies and flagging. So when you original had %(%%%( the first pass gobbled up %( as an escape character on the parenthesis and resulted in just (, then the next two %% get consolidated to %, and the last %) turns into ). Then we are left with (%) but now because we have one more additional layer of nesting the macro processor will pass through again and the sequence of parsing and keeping track of opens and closes of the parens gets out of sync because there are now two passes of flagging characters getting gobbled up. To fix this, your original code for one non-nested macro with one pass through the parser, had %% in the middle. Knowing now that there is gonna be two passes through we find that if we just add another pair of %% to make four the first pass will take %%%% down to %% and then the second pass will take that pair down to % which is what you wanted to be left with after all said and done.

Thus, the following adjusted code works.

%macro b(mlst=); %unquote(&mlst); %mend;

%b(mlst=%nrstr( %a(tit=%str(Change %(%%%%%))) ));

Hope this is helpful.

Mark Terjeson Investment Business Intelligence Investment Management & Research Russell Investments 253-439-2367

Russell Global Leaders in Multi-Manager Investing

-----Original Message----- From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of Ya Huang Sent: Wednesday, May 13, 2009 10:52 AM To: SAS-L@LISTSERV.UGA.EDU Subject: Macro quoting again !

Hi there,

Macro a with a get the result as expected. But macro b is not, why is that?

Thanks

Ya

1 %macro a(tit=); 2 %put &tit; 3 %mend; 4 5 %a(tit=%str(Change %(%%%))); Change (%) 6 7 %macro b(mlst=); 8 %unquote(&mlst); 9 %mend; 10 11 %b(mlst=%nrstr( 12 %a(tit=%str(Change %(%%%))) 13 ));


Back to: Top of message | Previous page | Main SAS-L page