Unquoting Text

Restoring the Significance of Symbols

To unquote a value means to restore the significance of symbols in an item that was previously masked by a macro quoting function.
Usually, after an item has been masked by a macro quoting function, it retains its special status until one of the following occurs:
  • You enclose the item with the %UNQUOTE function. (See %UNQUOTE Function.)
  • The item leaves the word scanner and is passed to the DATA step compiler, SAS procedures, SAS macro facility, or other parts of the SAS System.
  • The item is returned as an unquoted result by the %SCAN, %SUBSTR, or %UPCASE function. (To retain a value's masked status during one of these operations, use the %QSCAN, %QSUBSTR, or %QUPCASE function. See Other Functions That Perform Macro Quoting for more details.)
As a rule, you do not need to unquote an item because it is automatically unquoted when the item is passed from the word scanner to the rest of SAS. Under two circumstances, however, you might need to use the %UNQUOTE function to restore the original significance to a masked item:
  • when you want to use a value with its restored meaning later in the same macro in which its value was previously masked by a macro quoting function
  • when, as in a few cases, masking text with a macro quoting function changes the way the word scanner tokenizes it, producing SAS statements that look correct but that the SAS compiler does not recognize

Example of Unquoting

The following example illustrates using a value twice: once in macro quoted form and once in unquoted form. Suppose the macro ANALYZE is part of a system that enables you to compare the output of two statistical models interactively. First, you enter an operator to specify the relationship that you want to test (one result greater than another, equal to another, and so on). The macro ANALYZE tests the macro quoted value of the operator to verify that you have entered it correctly, uses the unquoted value to compare the values indicated, and writes a message. Match the numbers in the comments to the paragraphs below.
%macro analyze(stat);
   data _null_;
      set out1;
      call symput('v1',&stat);
   run;

   data _null_;
      set out2;
      call symput('v2',&stat);
   run;

   %put Preliminary test. Enter the operator.;
   %input;
   %let op=%bquote(&sysbuffr);
   %if &op=%str(=<) %then %let op=%str(<=);
   %else %if &op=%str(=>) %then %let op=%str(>=);
   %if &v1 %unquote(&op) &v2 %then
      %put You might proceed with the analysis.;
   %else
      %do;
         %put &stat from out1 is not &op &stat from out2.;
         %put Please check your previous models.;
      %end;
%mend analyze;
You mask the value of SYSBUFFR with the %BQUOTE function, which masks resolved items including unmatched, unmarked quotation marks and parentheses (but excluding the ampersand and percent sign).
The %IF condition compares the value of the macro variable OP to a string to see whether the value of OP contains the correct symbols for the operator. If the value contains symbols in the wrong order, the %THEN statement corrects the symbols. Because a value masked by a macro quoting function remains masked, you do not need to mask the reference &OP in the left side of the %IF condition.
Because you can see the characters in the right side of the %IF condition and in the %LET statement when you define the macro, you can use the %STR function to mask them. Masking them once at compilation is more efficient than masking them at each execution of ANALYZE.
To use the value of the macro variable OP as the operator in the %IF condition, you must restore the meaning of the operator with the %UNQUOTE function.

What to Do When Automatic Unquoting Does Not Work

When the macro processor generates text from an item masked by a macro quoting function, you can usually allow SAS to unquote the macro quoted items automatically. For example, suppose you define a macro variable PRINTIT:
%let printit=%str(proc print; run;);
Then you use that macro variable in your program:
%put *** This code prints the data set: &printit ***;
When the macro processor generates the text from the macro variable, the items masked by macro quoting functions are automatically unquoted, and the previously masked semicolons work normally when they are passed to the rest of SAS.
In rare cases, masking text with a macro quoting function changes the way the word scanner tokenizes the text. (The word scanner and tokenization are discussed in SAS Programs and Macro Processing and Macro Processing.) For example, a single or double quotation mark produced by resolution within the %BQUOTE function becomes a separate token. The word scanner does not use it as the boundary of a literal token in the input stack. If generated text that was once masked by the %BQUOTE function looks correct but SAS does not accept it, you might need to use the %UNQUOTE function to restore normal tokenization.