Hãy cài đặt một bộ quét từ vựng (lexer) hoàn chỉnh hơn cho một ngôn ngữ lập trình đơn giản, xử lý nhiều dòng mã nguồn và phải báo chính xác vị trí lỗi (dòng, cột) khi gặp ký tự không hợp lệ — giống cách một trình biên dịch thật thông báo lỗi cú pháp/từ vựng.
Bộ từ khoá cố định của ngôn ngữ (không đọc từ input): if, else, while, return, int, float.
Quy tắc quét (áp dụng maximal munch, ưu tiên theo thứ tự liệt kê):
\n: tăng số hiệu dòng lên 1, đưa số hiệu cột về 1, không sinh token.6.02e-23, 1E+5) là tuỳ chọn; nếu sau một thành phần (dấu chấm, hoặc e/E) không có đủ chữ số hợp lệ theo đúng cấu trúc, thành phần đó không được gộp vào token số (ví dụ 3.5e chỉ cho ra token số 3.5, còn e được xét là token riêng ở bước sau).KEYWORD, ngược lại là ID.Nếu một ký tự không khớp bất kỳ quy tắc nào ở trên, đó là lỗi từ vựng: in ra tất cả các token hợp lệ đã nhận diện được trước thời điểm đó, rồi in thêm đúng một dòng thông báo lỗi và dừng ngay lập tức (không đọc/xử lý phần dữ liệu còn lại, kể cả khi còn nhiều dòng phía sau).
Nhiều dòng mã nguồn, đọc đến hết input (EOF). Có thể rỗng.
Mỗi token hợp lệ in trên một dòng theo định dạng LOAI GIA_TRI (LOAI ∈ {KEYWORD, ID, NUMBER, OP, PUNCT}), theo đúng thứ tự quét.
Nếu gặp lỗi từ vựng tại dòng L, cột C (đều đánh số từ 1) với ký tự c, sau các token hợp lệ in thêm đúng một dòng:
Loi tu vung tai dong L, cot C: ky tu khong hop le 'c'
Ví dụ:
Đầu vào:
int x = 5;
float y = x @ 2;
Đầu ra:
KEYWORD int
ID x
OP =
NUMBER 5
PUNCT ;
KEYWORD float
ID y
OP =
ID x
Loi tu vung tai dong 2, cot 13: ky tu khong hop le '@'
Đầu vào:
int x = 10;
float y = 3.14;
if (x >= 5 && y <= 4.0) {
return x;
}
Đầu ra:
KEYWORD int
ID x
OP =
NUMBER 10
PUNCT ;
KEYWORD float
ID y
OP =
NUMBER 3.14
PUNCT ;
KEYWORD if
PUNCT (
ID x
OP >=
NUMBER 5
OP &&
ID y
OP <=
NUMBER 4.0
PUNCT )
PUNCT {
KEYWORD return
ID x
PUNCT ;
PUNCT }
Đang tải editor...