Các ngôn ngữ lập trình SAS là một phiền phức, cổ ngôn ngữ có niên đại đến 1966 đó là vẫn còn sử dụng ngày nay. Trình biên dịch gốc được viết bằng PL / I và thực sự phần lớn cú pháp xuất phát từ PL / I. SAS cũng có một tiền xử lý ngôn ngữ macro mà xuất phát từ đó PL / I là tốt. Trong thử thách này, bạn sẽ diễn giải một số yếu tố đơn giản của ngôn ngữ macro SAS.
Trong ngôn ngữ macro của SAS, các biến macro được xác định bằng cách sử dụng %let
từ khóa và in vào nhật ký được thực hiện với %put
. Báo cáo kết thúc bằng dấu chấm phẩy. Dưới đây là một số ví dụ:
%let x = 5;
%let cool_beans =Cool beans;
%let what123=46.lel"{)-++;
Tên biến macro không phân biệt chữ hoa chữ thường và luôn khớp với biểu thức chính quy /[a-z_][a-z0-9_]*/i
. Đối với mục đích của thử thách này, chúng tôi sẽ nói như sau:
- Biến vĩ mô chỉ có thể giữ giá trị bao gồm toàn bộ các ký tự ASCII in trừ
;
,&
và%
- Sẽ không có khoảng trắng ở đầu hoặc cuối trong các giá trị
- Các giá trị sẽ không bao giờ dài hơn 255 ký tự
- Giá trị có thể trống
- Chân đế và dấu ngoặc kép trong các giá trị có thể không thể so sánh được
- Có thể có bất kỳ khoảng không gian trước và sau khi
=
trong%let
tuyên bố và không gian này nên bỏ qua - Có thể có bất kỳ dung lượng nào trước thiết bị đầu cuối
;
trong%let
câu lệnh và không gian này tương tự nên được bỏ qua
Khi một biến vĩ mô được gọi, chúng ta nói nó "giải quyết" giá trị của nó. Các biến vĩ mô được giải quyết bằng cách thêm trước &
. Có một dấu vết tùy chọn.
biểu thị sự kết thúc của định danh. Ví dụ,
%put The value of x is &X..;
ghi The value of x is 5.
vào nhật ký. Lưu ý rằng hai giai đoạn là bắt buộc vì một giai đoạn duy nhất sẽ được sử dụng &X.
và giải quyết 5
. Cũng lưu ý rằng mặc dù chúng tôi đã định nghĩa x
bằng chữ thường, &X
cũng giống như &x
vì tên biến macro không phân biệt chữ hoa chữ thường.
Đây là nơi mà nó trở nên khó khăn. Nhiều &
s có thể được xâu chuỗi lại với nhau để giải quyết các biến và &
s ở cùng một mức độ phân giải lồng nhau cùng một lúc. Ví dụ,
%let i = 1;
%let coolbeans1 = broseph;
%let broseph = 5;
%put &&coolbeans&i; /* Prints broseph */
%put &&&coolbeans&i; /* Prints 5 */
Trong cùng &
giải quyết đầu tiên, và giải quyết tiếp tục ra bên ngoài. Kết hợp tên biến được thực hiện một cách tham lam. Trong %put
câu lệnh thứ hai , bộ xử lý thực hiện các bước sau:
&i
quyết tâm1
, và hàng đầu trong cùng&
được tiêu thụ, mang lại cho chúng tôi&&coolbeans1
&coolbeans1
quyết tâmbroseph
, cho chúng tôi&broseph
&broseph
quyết tâm5
.
Nếu có dấu .
s , chỉ một cái duy nhất .
được tiêu thụ ở độ phân giải, ngay cả khi có nhiều &
s.
Bài tập
Đưa ra từ 1 đến 10 %let
câu cách nhau bởi dòng mới và một câu%put
câu lệnh, in hoặc trả về kết quả của %put
câu lệnh. Đầu vào có thể được chấp nhận theo bất kỳ cách tiêu chuẩn nào.
Bạn có thể giả định rằng đầu vào sẽ luôn hợp lệ và các %let
câu lệnh sẽ đi trước%put
câu lệnh. Các biến được định nghĩa sẽ không được xác định lại trong các %let
câu lệnh sau .
Nếu thực sự chạy trong SAS, sẽ không có vấn đề gì với các biến giải quyết thành các biến không tồn tại và mọi thứ sẽ đúng về mặt cú pháp như được mô tả ở trên.
Ví dụ
Đầu vào:
%let dude=stuff; %let stuff=bEaNs; %put &&dude..;
Đầu ra:
bEaNs.
Đầu vào:
%let __6 = 6__; %put __6&__6;
Đầu ra:
__66__
Đầu vào:
%let i=1; %let hOt1Dog = BUNS; %put &&HoT&i.Dog are FUNS&i!");
Đầu ra:
BUNS are FUNS1!")
Đầu vào:
%let x = {*':TT7d; %put SAS is weird.;
Đầu ra:
SAS is weird.
Đầu vào:
%let var1 = Hm?; %let var11 = var1; %let UNUSED = ; %put &&var11.....;
Đầu ra:
Hm?....
Lưu ý rằng
&&var11
khớpvar11
từ khi khớp tên là tham lam. Nếu đã có một.
, tức là&&var1.1
, thìvar1
sẽ được khớp và thêm 1 sẽ không là một phần của bất kỳ tên nào.
Đây là mã golf, vì vậy giải pháp ngắn nhất tính bằng byte sẽ thắng!
&&&&&&&&&a......................
vẫn sẽ chỉ loại bỏ một thời gian?
&stuff.
xóa thời gian?