Мова програмування 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 */
Сама внутрішня &
сек рішучість першої, а дозвіл продовжує назовні. Зміна відповідності змінних імен робиться жадібно. У другому %put
твердженні процесор робить такі кроки:
&i
вирішується на1
, і найпотужніше провідне&
споживається, даючи нам&&coolbeans1
&coolbeans1
вирішуєbroseph
, даруючи нам&broseph
&broseph
вирішує до5
.
Якщо є кінцеві .
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.
видаляти період?