在SAS编程语言是笨重的,古老的语言可以追溯到1966年的今天这仍然在使用。原始的编译器是用PL / I编写的,实际上许多语法都来自PL / I。SAS还具有从PL / I的语言衍生而来的预处理器宏语言。在这个挑战中,您将解释SAS宏语言的一些简单元素。
在SAS宏语言中,宏%let
关键字是使用关键字定义的,并使用进行打印到日志%put
。语句以分号结尾。这里有些例子:
%let x = 5;
%let cool_beans =Cool beans;
%let what123=46.lel"{)-++;
宏变量名称不区分大小写,并且始终与正则表达式匹配/[a-z_][a-z0-9_]*/i
。出于此挑战的目的,我们将讲以下内容:
- 宏变量只能保存完全由可打印ASCII字符组成的值,,和除外
;
。&
%
- 值中将没有前导或尾随空格
- 值的长度不得超过255个字符
- 值可能为空
- 值中的方括号和引号可能不匹配
- 可以有任何空间量前后
=
的%let
语句和这个空间应该被忽略 - 可以有空间的任何数量的终端之前
;
的%let
声明,这个空间应该同样被忽略
当调用宏变量时,我们说它“解析”为其值。宏变量通过前置来解决&
。有一个可选的结尾.
表示标识符的末尾。例如,
%put The value of x is &X..;
写入The value of x is 5.
日志。请注意,需要两个期间,因为单个期间将被消耗&X.
并解析为5
。还要注意,即使我们x
以小写字母定义,&X
也是如此,&x
因为宏变量名称不区分大小写。
这就是棘手的地方。&
可以将多个s串在一起以解析变量,并且&
处于同一嵌套级别的s可以同时解析。例如,
%let i = 1;
%let coolbeans1 = broseph;
%let broseph = 5;
%put &&coolbeans&i; /* Prints broseph */
%put &&&coolbeans&i; /* Prints 5 */
最里面的&
s首先解析,而解析继续向外扩展。变量名匹配是贪婪地完成的。在第二条%put
语句中,处理器执行以下步骤:
&i
解析为1
,并且&
消耗了最里面的领导力,这给了我们&&coolbeans1
&coolbeans1
解决broseph
,给我们&broseph
&broseph
决定解决5
。
如果存在尾随的.
s,.
则即使有多个&
s 也仅消耗一个分辨率。
任务
给定1到10个%let
由换行符分隔的语句和一个%put
语句,则打印或返回%put
语句的结果。可以以任何标准方式接受输入。
您可以假定输入将始终有效,并且%let
语句将位于该%put
语句之前。定义的变量将不会在以后的%let
语句中重新定义。
如果实际在SAS中运行,则将变量解析为不存在的变量将不会有问题,并且如上所述,所有语法都将正确。
例子
输入:
%let dude=stuff; %let stuff=bEaNs; %put &&dude..;
输出:
bEaNs.
输入:
%let __6 = 6__; %put __6&__6;
输出:
__66__
输入:
%let i=1; %let hOt1Dog = BUNS; %put &&HoT&i.Dog are FUNS&i!");
输出:
BUNS are FUNS1!")
输入:
%let x = {*':TT7d; %put SAS is weird.;
输出:
SAS is weird.
输入:
%let var1 = Hm?; %let var11 = var1; %let UNUSED = ; %put &&var11.....;
输出:
Hm?....
请注意,由于名称匹配是贪婪的,因此
&&var11
匹配var11
。如果存在.
,即&&var1.1
,var1
则将被匹配,多余的1将不属于任何名称。
这是代码高尔夫,所以最短的解决方案以字节为单位!
&&&&&&&&&a......................
仍然只删除一个期间?
&stuff.
删除期限吗?