BookmarkSubscribeRSS Feed
Michael_Weiss
Fluorite | Level 6

Hi all,

I'm currently trying to understand how SAS processes code. I noticed some weired things where I can not find an explanation in any of the SAS support documents.

The following code does work when included in a macro, but gives the expected error message outside:

%PUT %NRBQUOTE("this is a);%NRBQUOTE("test);

%MACRO abc();

    %PUT %NRBQUOTE("this is a);%NRBQUOTE("test);

%MEND;

%abc();

It seams as the SAS code processor treats thefirst double quote as the start of a string and processes all following chars as string chars until the next double quote.

The more interesting effect can be seen in the following statement:


%PUT - This is a %NRBQUOTE(") test;

This statement works correct outside of a macro, but it crashes the macro compiler when used in a macro definition like:

%MACRO abc();

    %PUT - This is a %NRBQUOTE(") test;

%MEND;

A workaround that was used in our department was as follows:

%MACRO abc();

    %PUT - This is a %NRBQUOTE(") test; %*%NRBQUOTE(");

%MEND;

This leads to an other point, does anybody know if the following behaviour is somewhere documented:

DATA _NULL_;

   %*This is " the first comment;

   PUT 'Hello World';

   %*This is " the second comment;

   PUT 'Nothing more to say';

RUN;

In this example the first PUT statement is not processed, because it belongs to the first comment which is not closed by the semicolon because of the single quote. Correctly highlighted the code would look like:

DATA _NULL_;

    %*This is " the first comment;

    PUT 'Hello World';

    %*This is " the second comment;

    PUT 'Nothing more to say';

RUN;


I guess this should have been posted on a friday afternoon 😉 So have a nice weekend!

7 REPLIES 7
data_null__
Jade | Level 19

9    %MACRO abc();

10      %PUT - This is a %str(%") test;

11      %MEND;

12   %abc;

- This is a " test

For complied macro code you need functions that work at compile time.  STR or NRSTR

Michael_Weiss
Fluorite | Level 6

Hi and thanks for the reply Smiley Happy.

Please don't take the question to serious. I know how quoting works (at least as far as this is written in the SAS documentation), but wondered on how this is sometimes processed by SAS :smileysilly: and if this is written somewhere, e.g. the manual of BQUOTE does not say that it handles quotation marks that do not appear in pairs in open code differently than in a macro definition.

The question here is more like is this a behaviour, that is to be expected? And if so, is there a documentation for this?

data_null__
Jade | Level 19

Michael.Weiss wrote:

, e.g. the manual of BQUOTE does not say that it handles quotation marks that do not appear in pairs in open code differently than in a macro definition.

Perhaps not in the exact words you want to see.  BQUOTE and NRBQUOTE work when the macro is executed not when the macro code is compiled.

Michael_Weiss
Fluorite | Level 6

Ok, lets phrase it different, is it somewhere explained, that for the following code

%MACRO abc();

    %PUT %NRBQUOTE("this is a);%NRBQUOTE("test);

%MEND;

The double quotation marks in the %PUT command prevents the first semicolon from closing the command Smiley Wink.

From my point of view, even when the double quotation mark is quoted at runtime, the semicolon is not inside a string and not quoted by a quoting function.

data_null__
Jade | Level 19

Michael.Weiss wrote:

Ok, lets phrase it different, is it somewhere explained, that for the following code

%MACRO abc();

    %PUT %NRBQUOTE("this is a);%NRBQUOTE("test);

%MEND;

The double quotation marks in the %PUT command prevents the first semicolon from closing the command .

From my point of view, even when the double quotation mark is quoted at runtime, the semicolon is not inside a string and not quoted by a quoting function.

I believe relevant line from this page
http://support.sas.com/documentation/cdl/en/mcrolref/62978/HTML/default/viewer.htm#p0frhtfqvguv78n1o...

is "(It does not mask parentheses or quotation marks that are in the argument at compile time.)"

You need to use STR or NRSTR so that the unmatched quote is quoted at compile time.

%put %str(%")this is a;

Michael_Weiss
Fluorite | Level 6

Good point, but if this would mean that the quotation marks ar not masked and therefore the semicolon is inside a text string, than I would expect a different log message (e.g. the parentheses within the text).

This can be demonstrated even better for single quotation marks like in:

%MACRO abc();

    %PUT %NRBQUOTE('this is a);%NRBQUOTE('test);

%MEND;

%abc();

Here I would expect the second NRBQUOTE macro call as part of the log message.

Additionally you can easily check if the quotation marks are quoted or not with the following code:

%MACRO abc();

   %LET val = %NRBQUOTE('this is a);%NRBQUOTE('test);

   proc sql; select value from dictionary.macros where name eq 'VAL'; quit;

%MEND;

%abc();

The result shows that the quotation marks are correctly masked.

And also it does not explain why the next example works, here the first quotation mark is not quoted, but the second is:

%MACRO abc();

    %PUT %NRBQUOTE("this is a%STR(%") test);

%MEND;

%abc();

And again, I do not need a solution for the quotation, I just wanted to know if this is an documented / expected behaviour.

The background is, I'm currently working on a correct syntax highlighter for SAS code and therefore I would like to highlight code as it is processed by the SAS code parser.

data_null__
Jade | Level 19

Michael.Weiss wrote:

The background is, I'm currently working on a correct syntax highlighter for SAS code and therefore I would like to highlight code as it is processed by the SAS code parser.

If that is the case then I think your highlighter should at least consider your first two examples syntax errors.  Proper usage as mentioned is %STR or %NRSTR.  To make it easy on yourself flag any use of %BQUOTE or %NRBQUOTE (that appear in a macro) where the argument is not a macro variable reference as a "potential syntax error".   Does your syntax highligher know if it is looking at statements defined between %MACRO and %MEND.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 7 replies
  • 1521 views
  • 0 likes
  • 2 in conversation