Khi một macro đối tượng (object-like macro) có thân chứa chính tên của nó (tự tham chiếu trực tiếp) hoặc tham chiếu vòng qua các macro khác (tự tham chiếu gián tiếp), tiền xử lý C áp dụng quy tắc ngăn đệ quy vô hạn thường gọi là "sơn xanh" (blue paint / hide set): trong quá trình mở rộng (rescanning) thân của một macro M, nếu gặp lại chính token M, token đó không được mở rộng thêm nữa (được giữ nguyên là văn bản M) — kể cả khi M xuất hiện gián tiếp qua một chuỗi macro khác đang trong quá trình mở rộng.
Hình thức hóa: gọi H là tập tên các macro đang được mở rộng trên đường đi hiện tại (ban đầu H=∅). Hàm mở rộng dãy token expand(tokens, H) xử lý từng token tok:
expand(thân(tok), H \cup \{tok\}).Cho n macro đối tượng (mỗi macro có tên và thân là một dãy token, thân có thể tham chiếu đến bất kỳ macro nào kể cả chính nó hoặc tạo thành chu trình) và m dòng mã nguồn. Với mỗi dòng, áp dụng expand(tokens_của_dòng, \emptyset) và in ra kết quả.
Ví dụ: #define A B, #define B A. Mở rộng A: H=∅, A là macro, chưa bị chặn ⇒ mở rộng thân B với H={A}: B là macro, chưa bị chặn ⇒ mở rộng thân A với H={A,B}: A là macro nhưng A∈H ⇒ giữ nguyên A. Kết quả cuối cùng: A (macro tự tham chiếu vòng quay trở lại chính tên của nó).
Dòng 1: số nguyên n (1≤n≤50) — số macro đối tượng. n dòng tiếp theo, mỗi dòng dạng TÊN tok_1 tok_2 ... tok_r (r≥0) — tên macro và các token trong thân (nếu r=0, dòng chỉ có TÊN, nghĩa là macro mở rộng ra rỗng). Tên các macro đôi một khác nhau. Dòng tiếp theo: số nguyên m (0≤m≤100) — số dòng mã nguồn. m dòng tiếp theo là các dòng mã nguồn, token cách nhau bởi khoảng trắng (dòng có thể rỗng).
In ra m dòng, dòng thứ i là kết quả mở rộng đầy đủ (theo quy tắc sơn xanh ở trên) của dòng mã nguồn thứ i, các token cách nhau đúng 1 khoảng trắng (nếu dòng mở rộng ra rỗng thì in ra dòng rỗng).
Ví dụ:
Đầu vào:
3
A B
B A
C 1 A 2
2
A
C
Đầu ra:
A
1 A 2
Đầu vào:
1
X X + 1
2
X
X + X
Đầu ra:
X + 1
X + 1 + X + 1
Đang tải editor...