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] Loại bỏ chú thích tôn trọng chuỗi ký tự

    Giai đoạn tiền xử lý của một lexer cần loại bỏ chú thích khỏi mã nguồn, nhưng phải tôn trọng chuỗi ký tự (string literal): chú thích chỉ được nhận diện khi nó nằm ngoài một chuỗi ký tự.

    Mã nguồn được quét từ trái sang phải theo đúng một trong bốn trạng thái sau:

    • CODE (mặc định): nếu gặp dấu ", chuyển sang trạng thái STRING (ký tự " được giữ lại). Nếu gặp //, chuyển sang LINE_COMMENT (hai ký tự này bị loại bỏ). Nếu gặp /*, chuyển sang BLOCK_COMMENT (hai ký tự này bị loại bỏ). Ngược lại, ký tự được giữ nguyên.
    • STRING: nếu gặp \ và còn ký tự tiếp theo, giữ nguyên cả hai ký tự (escape) và ở lại STRING. Nếu gặp ", giữ lại và quay về CODE. Ngược lại giữ nguyên ký tự, kể cả khi ký tự đó tạo thành chuỗi // hay /* — bên trong STRING các chuỗi này không được coi là chú thích.
    • LINE_COMMENT: nếu gặp \n, giữ lại ký tự xuống dòng đó và quay về CODE. Ngược lại, ký tự bị loại bỏ.
    • BLOCK_COMMENT: nếu gặp */, loại bỏ hai ký tự này và quay về CODE. Nếu gặp \n, giữ lại ký tự xuống dòng (để không làm lệch số dòng của phần còn lại) rồi tiếp tục ở BLOCK_COMMENT. Ngược lại, ký tự bị loại bỏ.

    Nếu mã nguồn kết thúc (EOF) khi đang ở LINE_COMMENT hoặc BLOCK_COMMENT (chú thích không đóng), phần còn lại coi như thuộc về chú thích đó. Nếu EOF xảy ra khi đang ở STRING (chuỗi không đóng), toàn bộ phần còn lại được giữ nguyên như nội dung chuỗi (không có gì bị loại bỏ).

    Cho mã nguồn, hãy tính:

    1. Tổng số ký tự đã bị loại bỏ vì là một phần của chú thích (bao gồm cả các dấu hiệu //, /*, */, nhưng không tính các ký tự \n được giữ lại bên trong BLOCK_COMMENT).
    2. Số dòng không rỗng (còn chứa ít nhất một ký tự khác khoảng trắng sau khi bỏ ký tự khoảng trắng ở đầu/cuối) của mã nguồn sau khi đã loại bỏ chú thích.
    • Định dạng đầu vào:

      Toàn bộ nội dung stdin (đọc tới EOF, có thể nhiều dòng, có thể rỗng) là mã nguồn cần xử lý.

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

      In ra một dòng gồm 2 số nguyên cách nhau một dấu cách: số ký tự bị loại bỏ vì là chú thích, và số dòng không rỗng còn lại sau khi loại bỏ chú thích.

    Ví dụ:

    Đầu vào:

    Đầu ra:

    0 0
    

    Đầu vào:

    // hello world

    Đầu ra:

    14 0
    

    Đang tải editor...