Go Back   Rhinocerus > Newsgroup > Newsgroup comp.soft-sys.sas

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 03-24-2006, 11:00 PM
Terjeson, Mark
Guest
 
Posts: n/a
Default Re: Understanding How Macro Processor Works

Hi,

Basically, you cannot intermix macro goodies
and datastep goodies. I will explain. The
%IF GRD = 'D' is where the misperception is.

All macro goodies, i.e. macro variables, macro
expressions, macro evaluations is all character
string text -and- ALL macro environment stuff.
In other words, you cannot use datastep variables
and datastep goodies in the %IF expression. It
is easier to interpret macro handling as text
substitution. See post:
http://listserv.uga.edu/cgi-bin/wa?A...sas-l&P=R29031

Let us see what your example is doing with that
in mind. Take your sample code:

%MACRO GRADE;
%IF GRD = 'D' | GRD = 'F' %THEN POOR = 1;
%ELSE POOR = 0;
%MEND GRADE;

DATA F2;
SET F1;
%GRADE
run;

The macro pre-processor is going to make as
many passes through the text until it resolves
as much as it can. So the first thing we can
do is use our editor by hand to simulate what
the macro pre-processor "results with if we
were hand do it by hand". Of course this is
not exact per se, but you will get the missing
piece of your understanding if we do this.

Therefore, if text-substitution is the name
of the game... (and by the way, it may prove
helpful to review the linked post referenced
above before you continue on here. First
understand the SAS macro stuff doesn't really
execute anything, it's more like a code parser
and re-writer. Everyone has their way of
thinking what it is, but if you use this
interpretation for a couple minutes, at least
you will understand what functionality you
are going to get.

Okay, if we have:

DATA F2;
SET F1;
%GRADE
run;

if we grab all the text that was (imaginarily)
saved off. i.e. take all the text between the
MACRO and MEND and replace it where the %GRADE
was located.

Replace %GRADE with contents of MACRO/MEND:
so our code text in our editor buffer is now:

DATA F2;
SET F1;
%IF GRD = 'D' | GRD = 'F' %THEN POOR = 1;
%ELSE POOR = 0;
run;

So far, so good, just keep thinking text-substitution.

Now remember that the macro expressions, such
as the goodies between the %IF and the %THEN
are *not* datastep objects! Just macro environment
string text characters. In other words, the
GRD = 'D' is *not* the datastep variable named
GRD and the 'D' is *not* a datastep string literal.
It is merely macro environment text characters.
The whitespace will be ignored and the text
characters "GRD" and the text characters
"<singlequote>D<singlequote>" will be compared
for equality due to the = operator. So yes,
3 characters is being compared to 3 characters
"GRD" eq "'D'" and the match of 3 chars to
3 chars fails so this portion of the true/false
checking in the expression resolves to 0 (zero)
for false. So now we have:
%IF GRD = 'D' | GRD = 'F' %THEN
becoming
%IF 0 | GRD = 'F' %THEN
then the next comparison of macro environment
text characters GRD = 'F' get evaluated in the
same way and we then result in
%IF 0 | 0 %THEN
which then evaluates the 0 | 0
as false or false
which yeilds a resulting FALSE. So the completed
expression now is:
DATA F2;
SET F1;
%IF 0 %THEN POOR = 1;
%ELSE POOR = 0;
run;

Now all the text characters found between the
%THEN and the following semicolon, or all the
text characters found between the %ELSE and the
following semicolon, BUT NOT INCLUDING THE SEMINCOLON
is indeed placed into the editor buffer resulting in:

DATA F2;
SET F1;

POOR = 0
run;

At this point, there are no more % or & macro notations
and the substituted/replaced text is submitted to
the runtime compiler for execution. The compiler will
give you the expected error of a missing semicolon
after the POOR = 0 line. If a semicolon was added
after the %GRADE, such as %GRADE; then this error
will go away.

So the logic of the macro %IF statement is more
along the lines of:

%IF<macro text expression>%THEN<return_this_text_if_
the_expression_is_true>;%ELSE<return_this_text_if_
the_expression_is_false>;


Think of SAS macros as a way to "assist" writing code
especially when repetitiousness or dynamic code
variations are needed.

Your macro should really not intermix datastep and
macro, since it really can't, so you would have:


%MACRO GRADE;
IF GRD = 'D' | GRD = 'F' THEN POOR = 1;
ELSE POOR = 0;
%MEND GRADE;


DATA F2;
SET F1;
%GRADE
run;

Which has no % characters, meaning ALL text found
between MACRO and MEND will be replaced where %GRADE
is located, resulting in:

DATA F2;
SET F1;
IF GRD = 'D' | GRD = 'F' THEN POOR = 1;
ELSE POOR = 0;
run;

which is indeed proper syntax for the datastep
and the compiler would like this. However, you
see that since there is no repetition, having
two lines in the macro really doesn't save you
anything.

Now if dynamic text content changes were passed
to the macro via arguments to the macro, or you
needed a %DO loop to make you multiple copies,
then using a macro would come into play.




Hope this is helpful.


Mark Terjeson
Senior Programmer Analyst, IM&R
Russell Investment Group


Russell
Global Leaders in Multi-Manager Investing













-----Original Message-----
From: SAS(r) Discussion [mailto:SAS-L@LISTSERV.UGA.EDU] On Behalf Of
Pitruzzello, Anthony J
Sent: Friday, March 24, 2006 2:44 PM
To: SAS-L@LISTSERV.UGA.EDU
Subject: Understanding How Macro Processor Works


I would like to get a better understanding of how the input stack, word
scanner, compiler, symbol table, and macro processor interact. SAS
Macro Language: Reference, V.8, provides a very simple example, based on
a single global macro variable. I would like to be able to extend that
to something one step more complicated, like the code below. (I
realize that there is no reason to use a macro in this code and that,
because the macro is processed before the data step, the conditions that
execute in DATA F2 are empty. I'm just trying to understand exactly how
this code is processed.)
__________________________________________________ ____________

%MACRO GRADE;
%IF GRD = 'D' | GRD = 'F' %THEN POOR = 1;
%ELSE POOR = 0;
%MEND GRADE;

DATA F1; INPUT @1 SID 1. @2 GRD $1. @4 X $2.;
CARDS;
1F MN
1B OP
2C QR
3D ST
3F UV
RUN;

DATA F2; SET F1;
%GRADE
PROC PRINT; __________________________________________________ ___

The first thing I noted is that, without a semicolon following the macro
call, %GRADE generates the following:

ERROR 388-185: Expecting an arithmetic operator.

Put a semicolon after %GRADE and it runs, but it produces this:
Obs SID GRD X POOR
1 1 F MN 0
2 1 B OP 0
3 2 C QR 0
4 3 D ST 0
5 3 F UV 0
__________________________________________________ ____

This is my understanding of what is happening:
1) The word scanner first encounters "%" and triggers the macro
processor (MP), which assumes control.
2) The MP inserts GRADE into the symbol table. It continues to process
the macro.
3) I want to say that because "GRD" is not a macro variable, control is
passed back to the word scanner at that point. However, if that
occurred, and if the word scanner placed "GRD = 'D' | GRD = 'F'" into
the input stack before the "DATA" statement, it would be rejected by the
compiler.
4) From the output, It's obvious that first "POOR = 1" and then "POOR =
0" are being placed in the input stack after the "DATA" statement, and
they are being compiled, so that the last value ("POOR = 0") is
retained. But I really don't see exactly how control is passed to and
from the macro processor in that "%IF GRD = 'D' | GRD = 'F' %THEN POOR
= 1; %ELSE POOR = 0;" segment. Can anyone clue me in?
Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Macro Quoting Question Kevin Morgan Newsgroup comp.soft-sys.sas 1 07-06-2007 02:47 AM
SCL Joe (was RE: macro structure) Gregg P. Snell Newsgroup comp.soft-sys.sas 0 06-27-2006 07:59 PM
Re: Understanding macro quoting (WAS: enterprise guide Jiann-Shiun Huang Newsgroup comp.soft-sys.sas 0 05-25-2006 05:27 PM
Re: Understanding macro quoting (WAS: enterprise guide Hans Schneider Newsgroup comp.soft-sys.sas 0 05-25-2006 05:19 PM
Re: MAcro Design was (Re: Macro quoting essentials) Ian Whitlock Newsgroup comp.soft-sys.sas 3 12-11-2005 11:18 PM



All times are GMT. The time now is 05:30 AM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.