Chương trình dịch
Bộ phân tích từ vựng cho ngơn ngữ Slang
Mục Lục
1. Giới thiệu về chương trình dịch
3
a. Giới thiệu
3
b. Ứng dụng của chương trình dịch
3
c. Các bài tốn cụ thể của chương trình dịch
4
d. Đặc trưng của chương trình dịch
4
e. Phân loại chương trình dịch
4
f. Cấu trúc của một chương trình dịch
5
2. Ứng dụng của chương trình dịch
6
3. Phát triển dự án về chương trình dịch
7
a. Mục đích
7
b. Các bước tiến hành
7
4. Vai trị của phân tích từ vựng
8
5. Nhiệm vụ của phân tích từ vựng
9
6. Các bước để phân tích từ vựng
10
7. Xác định từ tố
12
a. Biểu thức chính quy
12
b. Đồ thị chuyển
13
c. Viết chương trình cho đồ thị chuyển
14
d. Tập hợp tất cả các mẫu của từ tố
14
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
f. Viết chương trình
15
g. Cách xử lý lỗi
15
8. Các bước để xây dựng một bộ PTTV
16
9. Demo chương trình
16
a. Ngơn ngữ SLANG
16
b. Kết quả
18
1.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 tố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..
c. Các bài tố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 tồn vẹn: kết quả ở ngơn ngữ đích phải hồn tồ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 q nhiều bộ nhớ
và cơng suất tính tố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.
e. 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 tố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:
+ 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?
2.Ứ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.
+ Số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 hồ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..
+ 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, q 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
- 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.
+ Q 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, ngồ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
+ 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ố.
+ Số hố 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 tố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
if
if
if
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>
>
<tên, con trỏ đến initial trên bảng ký hiệu>
<toán_tử_cộng, >
<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>
>
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
Ví 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
- 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
+ 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.
- Thêm phần báo lỗi để thành bộ phân tích từ vựng hồ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
tố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
comment */)
– chú thích (chú thích kiểu C – trong cặp /*
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
fi_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
– tốn tử neg
absolute_token
– tố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 (>=)
err_token
– lỗi từ vựng
- Lưu ý: SLANG phân biệt chữ hoa chữ thường
b. Kết quả