Bài tập lớn chương trình dịch xây dựng bộ phân tích từ vựng cho ngôn ngữ Slang Chương trình dịch nghiên cứu 2 vấn đề + Lý thuyết thiết kế các ngôn ngữ lập trình. + Cách viết chương trình chuyển đổi từ một ngôn ngữ lập trình này sang một ngôn ngữ lập trình khác.
Trang 1
Chương trình dịch
Bộ phân tích từ vựng cho ngôn ngữ Slang
Mục Lục
c Các bài toán cụ thể của chương trình dịch 4
e Lập bộ phân tích từ vựng bằng phương pháp diễn giải đồ thị chuyển 14
Trang 21.Giới thiệu về chương trình dịch
a Giới thiệu
- Ngôn ngữ lập trình là tập hợp các ký hiệu được chuẩn hóa theo quy tắc nhất định để viết các chương trình Nó được dùng trong lập trình máy tính để thực hiện các thuật toán để có thể giao tiếp với con người Cú pháp đơn giản, gần gũi với ngôn ngữ tự nhiên
- Ví dụ: C/Pascal/Java,
- Ngôn ngữ máy là ngôn ngữ duy nhất để viết chương trình
mà máy tính trực tiếp hiểu và thực hiện được Mỗi chương trình viết bằng ngôn ngữ khác muốn thực hiện trên máy tính đều phải được dịch ra ngôn ngữ máy bằng một chương trình dịch
- Chương trình dịch: chuyển tự động ngôn ngữ lập trình sang ngôn ngữ máy
- Chương trình dịch nghiên cứu 2 vấn đề
+ Lý thuyết thiết kế các ngôn ngữ lập trình
+ Cách viết chương trình chuyển đổi từ một ngôn ngữ lập trình này sang một ngôn ngữ lập trình khác
b Ứng dụng của chương trình dịch
- Các chương trình dịch dùng trong lập trình: Turbo Pascal, Turbo C/Borland C/Dev C v.v
- Các bộ chuyển đổi văn bản: Phần mềm convert từ MS Word sang Pdf và ngược lại v.v
- Xử lý ngôn ngữ tự nhiên: dịch Anh – Việt, Việt –Anh tự động v.v
Trang 3c Các bài toán cụ thể của chương trình dịch
- Dịch một ngôn ngữ lập trình thành mã máy
- Dịch một ngôn ngữ lập trình bậc cao thành ngôn ngữ bậc thấp hơn
- Chuyển đổi đoạn mã giữa các ngôn ngữ lập trình
- Kiểm tra chính tả, ngữ pháp của các đoạn văn
- Mô tả hình ảnh (dịch từ hình ảnh thành văn bản)
d Đặc trưng của chương trình dịch
- Tính toàn vẹn: kết quả ở ngôn ngữ đích phải hoàn toàn tương đương với đầu vào viết ở ngôn ngữ nguồn
- Tính trong suốt:
+ Chương trình phải chia thành các bước độc lập
+ Phải rõ ràng về kết quả sau từ bước thực hiện
+ Có thể thực hiện việc hiệu chỉnh, sửa lỗi và tối ưu sau mỗi bước
- Tính hiệu quả: chương trình dịch sử dụng không quá nhiều bộ nhớ
và công suất tính toán, kết quả ở ngôn ngữ đích là đủ tốt
- Tính chịu lỗi:
+ Chương trình có thể chấp nhận một số lỗi của đầu vào và đưa ra các gợi ý xử lý phù hợp
+ Chương trình dừng ở ngay lỗi đầu tiên không thể coi là tốt
Trang 4e Phân loại chương trình dịch
- Theo số lần duyệt
- Theo mục đích
- Theo độ phức tạp: Assembly, Preprocessor, Compiler
- Theo phương pháp dịch chạy: Thông dịch, biên dịch
- Theo lớp văn phạm: LL(1), LR(1)
f Cấu trúc của một chương trình dịch
Giai đoạn phân tích:
- Phân tích từ vựng (lexical analyzer):
+ Đọc CT nguồn từ phải sang trái, nhóm các ký hiệu được gọi
là từ tố: tên từ khóa, tên biến, số, phép toán v.v
- Phân tích cú pháp (syntax analyzer):
+ Phân tích cấu trúc ngữ pháp của chương trình
+ Các từ tố sẽ được nhóm lại theo các cấu trúc phân cấp
- Phân tích ngữ nghĩa (semantic analyzer):
+ Phân tích tất cả các đặc tính khác của chương trình
+ Tìm ra lỗi ngữ nghĩa, không tương thích Ví dụ: gán bản ghi cho biến số nguyên
Giai đoạn tổng hợp
- Sinh mã trung gian (intermediate code generator): sinh chương trình trong ngôn ngữ trung gian nhằm:
Trang 5+ Dễ sinh và tối ưu hơn mã máy
+ Dễ chuyển đổi về mã máy
- Tối ưu mã (code optimizer): Sửa đổi chương trình trong ngôn ngữ trung gian nhằm cải tiến chương trình đích về hiệu năng
- Sinh mã (code generator): Tạo ra chương trình đích từ ngôn ngữ trung gian đã tối ưu
Cấu trúc chi tiết của 1 chương trình dịch:
Các thành phần khác:
- Quản lý bảng ký hiệu
+ Ghi lại các ký hiệu, tên, Đã sử dụng trong chương trình nguồn cùng các thuộc tính kèm theo như kiểu, phạm vi, giá trị v.v
- Xử lý lỗi
+ Ghi lại các vị trí có lỗi, loại lỗi, những lỗi khác có thể liên quan
+ Giúp CCD có thể bỏ qua các lỗi không quan trọng
+ Giúp CCD biết lỗi dây chuyển: dịch tiếp hay không?
Trang 62.Ứng dụng của chương trình dịch
- Từ ứng dụng ban đầu là chương trình dịch cho ngôn ngữ lập trình, nhiều kĩ thuật đã được áp dụng vào các nhiều ngành khác
- Bộ kiểm tra chính tả
+ Dùng cho các ngôn ngữ tự nhiên (trong các phần mềm soạn thảo văn bản)
+ Trợ giúp việc soạn thảo (intellisense, word suggestion)
- Bộ kiểm tra ngữ pháp
+ Kiểm tra lỗi nhanh khi viết ngôn ngữ lập trình
+ Soát lỗi khi viết tài liệu bằng ngôn ngữ tự nhiên
- Sinh các bộ nhận dạng mã độc / virus:
+ Mỗi mã độc / virus được nhận dạng bởi một mẫu (pattern) hoặc một automat
+ Kết hợp nhiều automat làm một để tăng tốc độ của việc nhận dạng (thay vì phải chạy một otomat cho mỗi virus, ta chạy một automat phát hiện đồng thời nhiều virus)
- Các công cụ về ngôn ngữ:
+ Bộ tìm kiếm văn bản hiệu quả
+ Bộ phát hiện ngôn ngữ
+ Bộ diễn dịch các giao thức
3.Phát triển dự án về chương trình dịch
a Mục đích
- Tạo một ngôn ngữ lập trình mới
- Viết chương trình dịch hoàn chỉnh cho ngôn ngữ máy
b Các bước tiến hành
- Tìm hiểu/thiết kế ngôn ngữ nguồn/đích
+ Có nhu cầu NNLT mới hay không?
○ Vi mạch mới sáng chế + Các NNLT hiện tại không đáp ứng được nhu cầu mới
+ Điều kiện cần đảm bảo:
○ Thiết kế tốt
○ Tuân theo các tiêu chuẩn: begin, end, start, var v.v
Trang 7+ Xây dựng CCD bằng các kỹ thuật hiện tại.
- Thiết kế và viết chương trình dịch
+ Phân tích từ vựng: đọc văn bản tìm từ tố
+ Phân tích cú pháp: đọc từ tố phân tích cú pháp
+ Phân tích ngữ nghĩa: dựa vào luật xây dựng câu
+ Sinh mã trung gian: chuyển từ cây cú pháp sang MTG
+ Sinh mã: chương trình ở MTG → mã máy
+ Quản lý bảng ký hiệu
+ Xử lý lỗi
+ Xây dựng môi trường phát triển của CCD: gắn liền với một
hệ thống cụ thể (ví dụ Turbo pascal gắn với công cụ soạn thảo chương trình)
+ Kiểm tra và bảo trì
4.Vai trò của phân tích từ vựng
- Phân tích từ vựng (lexical analysis) là bước đầu tiên của trình dịch
+ Còn gọi là scanning hoặc lexing, bộ phân tích từ vựng là scanner hoặc lexer
- Khối phân tích từ vựng (PTTV):
+ Nhận dữ liệu đầu vào là mã nguồn cần dịch
+ Loại bỏ các đoạn mã không cần thiết
+ Chia đoạn mã còn lại thành dãy các từ tố (token)
+ Chuyển kết quả cho khối phân tích cú pháp
- Có nhiều quan điểm về sự tương tác giữa bộ PTTV và bộ phân tích cú pháp
+ Thiết kế cổ điển: coi PTTV như một tiến trình song song và phụ thuộc vào bộ phân tích cú pháp, quá trình phân tích cú pháp điều khiển việc phân tích từ vựng
+ Thiết kế hiện đại: tách PTTV thành một module độc lập, kết quả đầu ra của PTTV được tiêu chuẩn hóa để có thể được ghi ra file hoặc sử dụng bởi các mục đích khác
- Chú ý: việc chọn cách thiết kế là do mục tiêu xây dựng chương trình, không có nghĩa là thiết kế hiện đại thì tốt hơn thiết kế cổ điển
Trang 8- Trong thiết kế cổ điển, PTTV đóng vai trò như bộ cung cấp dữ liệu cho bộ phân tích cú pháp
+ Bộ phân tích cú pháp yêu cầu PTTV lấy từ tố tiếp theo
+ Bộ PTTV đọc chương trình nguồn từ đầu hoặc từ vị trí đang phân tích trong lần gọi trước,tách lấy từ tố tiếp theo trả lại cho bộ phân tích cú pháp
+ Quá trình lặp lại cho đến khi hết mã nguồn hoặc gặp lỗi
- Trong các thiết kế mới hơn, bộ PTTV có xu hướng đứng tách ra độc lập, việc này có nhiều lợi ích:
+ Thiết kế theo hướng module hóa, đơn giản hơn
+ Tăng hiệu quả hoạt động của bộ PTTV, chẳng hạn như PTTV có thể độc lập xử lý các macro, xử lý khoảng trắng, ghi chú,
+ Tối ưu hoạt động của trình dịch, bộ PTTV sau khi hoạt động
có thể giải phóng các tài nguyên mà nó sử dụng thay vì giữ lại cùng lúc với bộ phân tích cú pháp
+ Xử lý được ngay lập tức một số lỗi cơ bản về từ vựng mà không cần phân tích cú pháp
5.Nhiệm vụ của phân tích từ vựng
- PTTV đóng vai trò như một bộ chuẩn hóa dữ liệu đầu vào, ngoài
ra nó cũng giúp hạn chế các lỗi cơ bản (viết sai luật, sai từ khóa, sai cấu trúc, )
- Các nhiệm vụ chính (nhất thiết phải có để đảm bảo hoạt động của chương trình dịch):
+ Đọc chương trình nguồn, loại bỏ các ký hiệu vô ích (khoảng trắng, dấu tab, xuống dòng, ghi chú, )
+ Phát hiện một số lỗi cơ bản về từ vựng
Trang 9+ Xác định nội dung của từ vựng
+ Xác định từ loại của từ vựng đó
+ Đưa ra một số thông tin thuộc tính của từ vựng
6.Các bước để phân tích từ vựng
- Đầu vào của PTTV: Trong trường hợp tổng quát nhất, đầu vào của
bộ PTTV là mã nguồn cần phân tích, không có bất kì ràng buộc nào
- Đầu ra của bộ PTTV phụ thuộc vào các đặc điểm của ngôn ngữ nguồn và bộ phân tích cú pháp
+ Trong hầu hết các tình huống, bộ PTTV thường trả về kết quả ở dạng sau:
+ Danh sách các từ vựng ứng theo mã nguồn (thường là một danh sách liên kết, chẳng hạn – List<Word>)
● Với mỗi từ vựng, thông tin bao gồm:
● Từ loại của từ vựng
● Giá trị chính xác của từ vựng
● Giá trị mã hóa của từ vựng
● Vị trí của từ vựng trong mã nguồn
- Các bước thực hiện
+ Xóa bỏ các ký tự không có nghĩa: chú thích, dòng trống, các
ký tự xuống dòng, dấu tab, các khoảng trắng không cần thiết
+ Nhận dạng các ký hiệu: các kí tự liền nhau tạo thành một kí hiệu Các dạng kí hiệu gọi là các từ tố
Trang 10+ Số hoá ký hiệu.
- Ví dụ:
+ Đầu vào:
position := initial + rate * 60
+ Đầu ra:
Tên phép_gán tên toán_tử_cộng tên toán_tử_nhân số
chấm_phẩy
- Ví dụ:
Từ tố
(token) Từ vị Mẫu (luật mô tả) const const const
quan hệ <,<=,=,<>,>,>= <,<=,=,<>,>,>=
tên pi, count, i, d2 Chữ cái theo sau là các
chữ cái hoặc số
số 3.14, 0, 6.02E23 Bất cứ một hằng số nào
đó xâu “Xin chao cac ban” Bất cứ chữ nào đặt
trong dấu ", trừ dấu "
- Thuộc tính của các từ tố
+ Một từ tố có thể ứng với một tập các từ vị khác nhau, phải thêm một số thông tin nữa để khi cần có thể biết được cụ thể
đó là từ vị nào
- Ví dụ:
+ Cho biểu thức:
position := initial + rate * 60;
+ Dãy từ tố nhận được bao gồm:
<tên, con trỏ đến position trên bảng ký hiệu>
<phép_gán, >
<tên, con trỏ đến initial trên bảng ký hiệu>
<toán_tử_cộng, >
Trang 11<tên, con trỏ đến rate trên bảng ký hiệu>
<toán_tử_nhân, >
<số nguyên, giá trị số nguyên 60>
<chấm phẩy, >
7.Xác định từ tố
- Biểu diễn từ tố
+ Các từ tố khác nhau có các luật mô tả (mẫu) khác nhau Các luật mô tả này là cơ sở để nhận dạng được từ tố
+ Cách biểu diễn các luật này đơn giản và thông dụng nhất là bằng lời Nhược: nhập nhằng
+ Biểu diễn tốt nhất: dùng biểu thức chính quy và otomat hữu hạn - lớp ngôn ngữ chính quy
a Biểu thức chính quy
- Biểu diễn các khái niệm về chữ cái, chữ số, tên, phép quan hệ trong Slang như sau:
chữ cái → A | B | | Z | a | b | | z
chữ số → 0 | 1 | | 9
tên → chữ cái ( chữ cái | chữ số )*
quan hệ → < | <= | = | <> | > | >=
- Các quy ước bổ sung:
+ lặp lại một hoặc nhiều lần
? lặp lại không hoặc một lần
b Đồ thị chuyển
Ví dụ: Biểu diễn tên
Trang 12Ví dụ: Đồ thị kết hợp
c Viết chương trình cho đồ thị chuyển
- Tập hợp tất cả các mẫu của từ tố
- Lập bộ phân tích từ vựng bằng phương pháp diễn giải đồ thị chuyển
Trang 13- Lập bộ phân tích từ vựng điều khiển bằng bảng (mô phỏng otomat hữu hạn đơn định)
d Tập hợp tất cả các mẫu của từ tố
- Ví dụ:
số thực mũ → chữ số+ ( chữ số+ ) ? ( E ( + | - ) ? chữ số+) ?
số thực → chữ số+ chữ số+
số nguyên → chữ số+
e Lập bộ phân tích từ vựng bằng phương pháp diễn giải đồ thị chuyển
- Lần theo sơ đồ, dùng các câu lệnh lựa chọn if hoặc switch
- Ưu điểm: dễ hiểu, dễ viết
- Nhược điểm: gắn kết cấu đồ thị chuyển vào trong chương trình Khi thay đổi đồ thị thì phải viết lại chương trình nên khó bảo trì
- Kết hợp các đồ thị chuyển thành một đồ thị chuyển duy nhất
- Kết hợp các đồ thị chuyển thành một đồ thị chuyển duy nhất
- Đồ thị chuyển
+ 24 trạng thái
Trang 14+ Các ký tự vào từ chương trình nguồn được chia thành các loại: chữ cái, chữ số, E, , <, =, >,+/- (tức là có 8 loại khác nhau)
+ Lập một bảng 10 x 8
f Viết chương trình
- Dựa vào bảng chuyển để chuyển trạng thái
- Ưu điểm: tách dữ liệu độc lập với chương trình, do đó rất dễ biến đổi mà không cần phải sửa lại chương trình
- Nhược điểm: là khó hiểu hơn và khó lập bảng
g Cách xử lý lỗi
- Đơn giản nhất: hệ thống sẽ ngừng hoạt động và báo lỗi cho người
sử dụng
- Tốt hơn và hiệu quả hơn: ghi ra các lỗi này và cố gắng bỏ qua chúng để tiếp tục làm việc, nhằm phát hiện đồng thời thêm nhiều lỗi khác
- Các cách khắc phục có thể có:
+ Xóa hoặc nhảy qua các kí tự mà bộ phân tích không tìm được từ tố;
+ Thêm một ký tự bị thiếu;
+ Thay một ký tự sai bằng một ký tự đúng;
+ Tráo hai ký tự đứng cạnh nhau
8.Các bước để xây dựng một bộ PTTV
- Sưu tầm tất cả các luật từ vựng, các luật này thường được mô tả bằng lời
- Vẽ đồ thị chuyển cho từng luật một Trước đó có thể mô tả chúng bằng các biểu thức chính quy để tiện theo dõi và chỉnh sửa, và làm dễ cho việc dựng đồ thị
- Kết hợp các luật này thành một đồ thị chuyển duy nhất
- Chuyển đồ thị này thành bảng
- Thêm phần chương trình ở trên để thành bộ phân tích hoạt động được
Trang 15- Thêm phần báo lỗi để thành bộ phân tích từ vựng hoàn chỉnh
9.Demo chương trình
a Ngôn ngữ SLANG
- Ngôn ngữ lập trình Slang tương tự về mặt cú pháp với Java và tương tự về mặt chức năng với C (do đó là tiếng lóng) Ngược lại với Java, nó cung cấp các tính năng nâng cao hơn như nạp chồng toán tử và RAII (cả hai đều được biết đến từ C) và phụ thuộc rất nhiều vào tính đúng hằng số
- 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)
num_token – số nguyên
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)
if_token – từ khóa if
then_token – từ khóa then
else_token – từ khóa else
Trang 16fi_token – từ khóa fi (kết thúc if)
while_token – từ khóa while
do_token – từ khóa do
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
list_token – dấu phẩy
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 (!=)
less_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 (>=)
Trang 17err_token – lỗi từ vựng
- Lưu ý: SLANG phân biệt chữ hoa chữ thường
b Kết quả