Язык программирования 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 символов
- Значения могут быть пустыми
- Скобки и кавычки в значениях могут не совпадать
- До и после оператора
=
in может быть любое количество места,%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 */
&
Сначала внутреннее решение, а разрешение продолжается вовне. Соответствие имени переменной выполняется жадно. Во втором %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.
удалить период?