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] Đếm token theo loại trong ngôn ngữ Zephyr-mini

    Người ta định nghĩa một ngôn ngữ lập trình đồ chơi có tên Zephyr-mini. Bộ phân tích từ vựng (lexer) của Zephyr-mini quét mã nguồn từ trái sang phải theo nguyên tắc so khớp dài nhất (maximal munch) và sinh ra các token thuộc đúng 5 loại sau:

    • KEYWORD: một trong 5 từ khóa cố định if, else, while, return, let (chỉ chữ thường).
    • IDENT: một dãy ký tự tối đa thỏa mãn biểu thức chính quy [a-z][a-z0-9_]∗[a\text{-}z][a\text{-}z0\text{-}9\_]^{*}[a-z][a-z0-9_]∗ (bắt đầu bằng chữ thường, theo sau là chữ thường/chữ số/gạch dưới) và không trùng với bất kỳ từ khóa nào ở trên.
    • NUMBER: một số nguyên không dấu (dãy chữ số tối đa), có thể có thêm phần thập phân dạng . theo sau bởi ít nhất một chữ số chỉ khi ngay sau dấu . là một chữ số (nếu không, dấu . không thuộc về số mà được xét riêng).
    • OP: một trong các toán tử == != <= >= && || + - * / = < > ( ) { } ; ,. Các toán tử hai ký tự (==, !=, <=, >=, &&, ||) luôn được ưu tiên khớp trước một ký tự đơn.
    • UNKNOWN: bất kỳ ký tự nào (đứng một mình, độ dài 1) không rơi vào 4 loại trên.

    Khoảng trắng (dấu cách, tab, xuống dòng, \r) chỉ dùng để phân tách token, bản thân nó không tạo ra token nào.

    Cho mã nguồn Zephyr-mini (có thể nhiều dòng, có thể rỗng), hãy đếm số token mỗi loại.

    Ví dụ: với mã nguồn

    let x = 10;
    if (x >= 5) { return x; } else { return 0; }
    

    kết quả đếm được là KEYWORD=5, IDENT=3, NUMBER=3, OP=11, UNKNOWN=0, tổng cộng 22 token.

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

      Toàn bộ nội dung đứng trong stdin (đọc tới EOF) chính là mã nguồn Zephyr-mini cần phân tích. Mã nguồn có thể có nhiều dòng và có thể rỗng.

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

      In ra một dòng gồm 6 số nguyên cách nhau bởi một dấu cách, theo đúng thứ tự: số token KEYWORD, số token IDENT, số token NUMBER, số token OP, số token UNKNOWN, và tổng số token.

    Ví dụ:

    Đầu vào:

    Đầu ra:

    0 0 0 0 0 0
    

    Đầu vào:

    let x = 10;
    if (x >= 5) { return x; } else { return 0; }
    

    Đầu ra:

    5 3 3 11 0 22
    

    Đang tải editor...