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 %lettừ 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%lettuyê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%letcâ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 xbằng chữ thường, &Xcũng giống như &xvì 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 %putcâu lệnh thứ hai , bộ xử lý thực hiện các bước sau:
- &iquyết tâm- 1, và hàng đầu trong cùng- &được tiêu thụ, mang lại cho chúng tôi- &&coolbeans1
- &coolbeans1quyết tâm- broseph, cho chúng tôi- &broseph
- &brosephquyết tâm- 5.
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 %letcâ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 %putcâ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 %letcâ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 %letcâ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 - &&var11khớp- var11từ khi khớp tên là tham lam. Nếu đã có một- ., tức là- &&var1.1, thì- var1sẽ đượ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?