Từ vựng của ngôn ngữ SLANG SLANG gồm các từ loại sau ident_token – tên bắt đầu bằng chữ cái hoặc dấu gạch dưới, theo sau là chữ cái, chữ số hoặc dấu gạch dưới comment_token – chú thích
Trang 1Bài tập lập trình số 01 Phân tích từ vựng
I Từ vựng của ngôn ngữ SLANG
SLANG gồm các từ loại sau
ident_token – tên (bắt đầu bằng chữ cái hoặc dấu gạch dưới, theo
sau là chữ cái, chữ số hoặc dấu gạch dưới)
comment_token – chú thích (chú thích kiểu C – trong cặp /* comment
*/)
begin_token – từ khóa begin
end_token – từ khóa end
int_token – từ khóa kiểu int
var_token – từ khóa var (khai báo biến)
procedure_token – từ khóa procedure (khai báo thủ tục)
call_token – từ khóa call (gọi thủ tục)
read_token – từ khóa read (đọc từ bàn phím)
write_token – từ khóa write (viết ra màn hình)
then_token – từ khóa then
else_token – từ khóa else
fi_token – từ khóa fi (kết thúc if)
while_token – từ khóa while
od_token – từ khóa od (kết thúc do)
negate_token – toán tử neg
absolute_token – toán tử abs
open_token – dấu mở ngoặc
close_token – dấu đóng ngoặc
period_token – dấu chấm
separator_token – dấu chấm phẩy
becomes_token – dấu gán (=)
plus_token – dấu cộng (+)
minus_token – dấu trừ (-)
times_token – dấu nhân (*)
over_token – dấu chia (/)
modulo_token – dấu lấy phần dư (%)
equal_token – dấu bằng (==)
not_equal_token – dấu khác (!=)
Trang 2less_than_token – dấu nhỏ hơn (<)
less_or_equal_token – dấu nhỏ hơn hoặc bằng (<=)
greater_than_token – dấu lớn hơn (>)
greater_or_equal_token – dấu lớn hơn hoặc bằng (>=)
err_token – lỗi từ vựng
Lưu ý: SLANG phân biệt chữ hoa chữ thường
II Lập trình
Viết bộ phân tích từ vựng của ngôn ngữ SLANG
- Khai báo lớp Token thể hiện từ tố gồm các thành viên: từ loại, thuộc tính,
tên file, số dòng Các hàm thành viên bao gồm: các hàm set, get thuộc tính,
hàm in từ tố ra màn hình
- Viết lớp Lexer có thành viên là tên file hoặc một luồng nhập (C++ istream hoặc Java InputStream) và hàm thành viên next_token() có kiểu trả về là Token
- Hàm next_token() đọc từ file hoặc luồng nhập và trả lại lần lượt các từ vựng thuộc ngôn ngữ SLANG hoặc err_token nếu có lỗi từ vựng
- Viết một hàm main() để thử chạy hàm next_token() với một chương trình thuộc ngôn ngữ SLANG
Ví dụ:
Mã nguồn:
begin var int number, sum;
sum = 0;
read(number);
while number != 0 do sum = sum + num;
read(number);
od;
write(sum);
end
Output (ví dụ)
<begin_token, >
<var_token, >
<int_token, >
<ident_token, number>
<list_token, >
<ident_token, sum>
<separator_token, >
<ident_token, sum>
Trang 3<becomes_token, >
<num_token, 0>
<separator_token, >
<read_token, >
<open_token, >
<ident_token, number>
<close_token, >
<separator_token, >
<while_token, >
<ident_token, number>
<not_equal_token, >
<num_token, 0>
<do_token, >
<ident_token, sum>
<becomes_token, >
<ident_token, sum>
<plus_token, >
<ident_token, number>
<separator_token, >
<read_token, >
<open_token, >
<ident_token, number>
<close_token, >
<separator_token, >
<od_token, >
<separator_token, >
<write_token, >
<open_token, >
<ident_token, sum>
<close_token, >
<separator_token, >
<end_token, >
III Cải tiến chương trình phân tích từ vựng
- Thêm vào các từ tố cho các câu lệnh for, switch … case
- Thông báo lỗi từ vựng: chỉ ra vị trí xảy ra lỗi
- Hồi phục lỗi: bỏ qua lỗi và dịch tiếp để bắt hết các lỗi từ vựng
IV Nộp bài tập
Sinh viên cần nộp các tài liệu sau
- Chương trình
- Tài liệu: khoảng 2 trang A4
o Giới thiệu nhóm
o Tóm tắt giải pháp
o Nêu các khó khăn và cách giải quyết
Trang 41 Xét ngôn ngữ sử dụng các thẻ (tags) được mô tả như sau:
Ký hiệu kết thúc: { < , > , / , = , word }
Mỗi thẻ bắt đầu bằng < và kết thúc bằng >
Có hai loại thẻ: thẻ mở và thẻ đóng
Thẻ mở có dạng <word word = word … >, tức là bắt đầu bằng word, tiếp theo là các cặp word được nối với nhau bằng dấu =, thể hiện các thuộc tính
của thẻ
Thẻ đóng có dạng </word>
Mỗi thẻ mở phải có một thẻ đóng tương ứng phía sau Giữa cặp thẻ mở và
đóng đó có thể có dãy các word dài tuỳ ý
Ví dụ: xâu <word word=word word=word><word>word word word</word><word></word></word> thuộc ngôn ngữ trên
a, Hãy viết văn phạm phi ngữ cảnh cho ngôn ngữ trên
b, Tìm các kí hiệu có thể triệt tiêu được
c, Tính các tập FIRST, FOLLOW cho văn phạm trên
d, Lập bảng phân tích LL(1), chỉ ra những vị trí xung đột trên bảng
e, Hãy chỉ ra nguyên nhân khiến văn phạm này không phải là LL(1)
2 Xét văn phạm sau
E E op E | (E) | num
op + | * | ^
Văn phạm này thể hiện ngôn ngữ gồm các công thức sử dụng phép cộng, nhân và hàm mũ Tuy nhiên, văn phạm này bị nhập nhằng Ta muốn có một văn phạm không nhập nhằng với phép mũ (^) được ưu tiên cao nhất, sau đó đến phép nhân (*) rồi đến phép cộng (+)
a, Viết một văn phạm thuộc lớp LL(1) cho ngôn ngữ trên, cho phép tạo ra cây suy dẫn theo thứ tự ưu tiên các phép toán như mong muốn Hãy chứng minh văn phạm của bạn là văn phạm thuộc lớp LL(1)
b, Viết cây suy dẫn của biểu thức 2 ^ 3 + 4 * 5 sử dụng văn phạm của phần a)
Trang 5c, Viết một văn phạm thuộc lớp LR(1) cuả ngôn ngữ này, sử dụng thứ tự ưu tiên các phép toán như trên và bắt buộc các phép toán kết hợp về bên trái
3 Java hoặc C++ cho phép gán được sử dụng nhiều lần trong cùng một biểu thức
Ví dụ: a = b = c, a = b = c + d
Phép gán kiểu này có tính kết hợp về bên phải, tức là a = b = c tương đương với
a = (b = c) Văn phạm sau thể hiện ngôn ngữ này
S A
A id = R
R A | E
E E + T | T
T id | (A)
a, Xây dựng bảng phân tích LR(0) cho văn phạm này
b, Văn phạm này thuộc lớp LR(0) hay không? Cho lý do
c, Văn phạm này thuộc lớp SLR hay không? Cho lý do
d, Văn phạm này thuộc lớp LR(1) hay không? Cho lý do
4 Hai kỹ thuật phân tích LL(1) và LALR(1) là hai kỹ thuật được sử dụng rộng rãi hiện nay Mỗi kỹ thuật đều có điểm mạnh riêng Hãy so sánh hai kỹ thuật phân tích này trong khoảng nửa trang giấy (A4)
Gợi ý: thử đánh giá trên các tiêu chí: tính đơn giản (của bộ phân tích và văn phạm), khả năng phân tích (lớp ngôn ngữ), kích thước bảng phân tích, v.v… và các tiêu chí khác mà bạn nghĩ ra
Trang 6Bài tập về nhà 1 (nộp bài vào ngày có buổi học của tuần thứ 2)
1 Viết biểu thức chính quy cho các URL của phương thức HTTP, biết rằng mỗi URL gồm 4 phần: phương thức (http://), DNS name (coltech.vnu.edu.vn) hoặc địa chỉ IP (203.162.0.181), cổng (:8080) – có thể có hoặc không, và đường dẫn tới file Để đơn giản, quy ước như sau:
• DNS name: gồm các xâu chữ cái tiếng Anh khác rỗng phân cách bởi dấu chấm
• Địa chỉ IP: gồm 4 số nguyên dương phân cách bởi dấu chấm
• Cổng: là một số nguyên dương đi sau dấu hai chấm (“:”)
• Đường dẫn: là một đường dẫn hợp lệ theo kiểu Unix, bao gồm các chữ cái, chữ số, dấu chấm và dấu sổ chéo (“/”) Không cho phép 2 dấu sổ chéo đi liền nhau - tức là không được phép có thư mục không có tên Đường dẫn phải bắt đầu bằng dấu sổ chéo và có thể kết thúc bằng dấu sổ chéo
2 Ghi chú trong ngôn ngữ C được bắt đầu bằng “/*”, tiếp đó là nội dung ghi chú và kết thúc bằng “*/” Nội dung ghi chú không được phép có “*/” đi liền nhau, tuy nhiên vẫn cho phép “*” và “/” nếu chúng không đứng cạnh nhau Hãy viết biểu thức chính quy cho các trường hợp sau, hoặc giải thích lí do không tồn tại biểu thức chính quy tương ứng
• Ghi chú trong ngôn ngữ C
VD: /* C-style comment */
• Ghi chú trong ngôn ngữ C, tuy nhiên cho phép “*/” nếu chúng được đặt trong cặp nháy kép “”
VD: /* C-style comment with “*/” extension */
• Ghi chú trong ngôn ngữ C, tuy nhiên cho phép các ghi chú lồng nhau VD: /* C-style comment with /* nested comment */ extension */