Các lượt nộp
    Danh sách bài
    Trang chủ
    Báo lỗi

    solution

    Đề bài: [Trình biên dịch] Macro Biến đổi Số lượng Tham số (__VA_ARGS__) và Phân tích Ngoặc Lồng nhau

    Macro hàm trong C có thể nhận số lượng đối số thay đổi bằng cú pháp ... ở cuối danh sách tham số, và trong thân macro, __VA_ARGS__ được thay bằng toàn bộ các đối số "thừa" (sau các tham số cố định), nối với nhau bởi , (dấu phẩy và một khoảng trắng).

    Điểm khó khi phân tích lời gọi macro là: các đối số được phân tách bởi dấu phẩy ở cấp lồng ngoặc cao nhất (cấp 0) — dấu phẩy nằm bên trong một cặp ngoặc đơn (...) lồng bên trong một đối số (ví dụ do gọi hàm f(a,b) làm đối số) không được coi là dấu phân tách đối số.

    Cho macro có kkk tham số cố định và thân gồm ttt token (mỗi token là: tên một tham số cố định, chuỗi __VA_ARGS__, hoặc một token cố định khác). Cho phần bên trong dấu ngoặc của lời gọi macro dưới dạng một chuỗi duy nhất, trong đó các đối số cấp cao nhất được phân tách bởi , (dấu phẩy + đúng 1 khoảng trắng), và có thể chứa ngoặc đơn lồng nhau bên trong một đối số.

    Hãy: (1) phân tích chuỗi lời gọi thành danh sách đối số ở cấp cao nhất (dùng bộ đếm độ sâu ngoặc); (2) gán kkk đối số đầu tiên cho các tham số cố định theo đúng thứ tự khai báo; (3) các đối số còn lại (có thể là 000 đối số) là phần biến đổi, nối lại bởi , để thay cho __VA_ARGS__; nếu không có đối số biến đổi nào thì __VA_ARGS__ được thay bằng chuỗi rỗng và bị loại hoàn toàn khỏi kết quả (không để lại token nào ở vị trí đó); (4) in ra thân macro sau khi thay thế, các token/đoạn cách nhau đúng 1 khoảng trắng.

    Ví dụ: macro 1 tham số cố định fmt, thân printf ( fmt , __VA_ARGS__ ), lời gọi với chuỗi "x=%d", x, foo(1,2). Phân tích cấp cao nhất cho 3 đối số: "x=%d", x, foo(1,2) (dấu phẩy bên trong foo(1,2) không tách đối số vì nó ở độ sâu ngoặc 1). Với k=1k=1k=1: fmt = "x=%d"; phần biến đổi là x và foo(1,2), nối lại: x, foo(1,2). Kết quả: printf ( "x=%d" , x, foo(1,2) ).

    • Định dạng đầu vào:

      Dòng 1: tên macro (không dùng đến). Dòng 2: số nguyên kkk (0≤k≤50 \le k \le 50≤k≤5) — số tham số cố định. Dòng 3: kkk tên tham số cách nhau bởi khoảng trắng (nếu k=0k=0k=0, dòng này rỗng). Dòng 4: số nguyên ttt (1≤t≤301 \le t \le 301≤t≤30) — số token trong thân macro. Dòng 5: ttt token của thân macro cách nhau bởi đúng 1 khoảng trắng. Dòng 6: một chuỗi duy nhất — phần bên trong ngoặc của lời gọi macro (có thể rỗng nếu lời gọi không có đối số nào), các đối số cấp cao nhất cách nhau bởi , , có thể chứa ngoặc đơn (,) lồng nhau bên trong một đối số. Dữ liệu đảm bảo số đối số cấp cao nhất luôn ≥k\ge k≥k và ngoặc trong dòng 6 luôn cân bằng.

    • Định dạng đầu ra:

      In ra một dòng duy nhất — thân macro sau khi thay thế tham số cố định và __VA_ARGS__ như mô tả, các token/đoạn cách nhau đúng 1 khoảng trắng.

    Ví dụ:

    Đầu vào:

    SUM_ALL
    0
    
    4
    sum ( __VA_ARGS__ )
    1, 2, 3, 4
    

    Đầu ra:

    sum ( 1, 2, 3, 4 )
    

    Đầu vào:

    LOG
    1
    fmt
    6
    printf ( fmt , __VA_ARGS__ )
    "x=%d", x, foo(1,2)
    

    Đầu ra:

    printf ( "x=%d" , x, foo(1,2) )
    

    Đang tải editor...