Ebook miễn phí xin giới thiệu chương trình dịch (compiler) là một chương trình làm nhiệm vụ đọc một chương trình được viết bằng một ngôn ngữ ngôn ngữ nguồn (source language) rồi dịch nó thành một chương trình tương đương ở một ngôn ngữ khác ngôn ngữ đích (target languague). Ebook miễn phí xin giới thiệu một phần quan trọng trong quá trình dịch là ghi nhận lại các lỗi có trong chương trình nguồn để thông báo lại cho người viết chương trình Ebook miễn phí giúp giúp người dùng tạo ra một chương trình đích có khả năng thực thi (excutable) thì ngoài trình biên dịch ta phải có thêm một số chương trình khác nữa. Ebook miễn phí xin giới thiệu sơ đồ sau mô tả ngữ cảnh của một trình biên dịch trong một hệ thống xử lí ngôn ngữ (languageprocessing system) Ebook miễn phí tổng hợp quá trình biên dịch được chia thành nhiều giai đoạn • Qua mỗi giai đoạn chương trình nguồn được chuyển đổi từ dạng biểu này sang một dạng biểu diễn khác • Trong thục tế xây dựng trình biên dịch, đôi khi các giai đoạn này được nhóm lại với nhau • Giai đoạn phân tích từ vựng sẽ đọc chương trình nguồn từ trái sang phải (linear analysisscanning) để tách ra thành các mã thông báo (token) • Trong quá trình phân tích từ vựng các khoảng trắng (blank) sẽ bị bỏ qua. Ebook miễn phí cũng tổng hợp giai đoạn phân tích cú pháp thực hiện công việc nhóm các token của chương trình nguồn thành các cụm từ văn phạm (grammatical phrase) Thông thường các cụm từ văn phạm này được biểu diễn bằng cây phân tích cú pháp (parse tree) với : Ngôn ngữ được định nghĩa bởi các luật sinh (production) Phân tích cú pháp dựa vào luật sinh để xây dựng cây phân tích cú pháp.
CHƯƠNG Giới thiệu chương trình dịch Mục tiêu: Giới thiệu khái niệm bản, giai đoạn biên dịch chương trình Khái niệm chương trình dịch • Chương trình dịch (compiler) chương trình làm nhiệm vụ đọc chương trình viết ngôn ngữ - ngôn ngữ nguồn (source language) - dịch thành chương trình tương đương ngôn ngữ khác - ngôn ngữ đích (target languague) • Chương trình dịch ta gọi trình biên dịch • Một phần quan trọng trình dịch ghi nhận lại lỗi có chương trình nguồn để thông báo lại cho người viết chương trình Chương trình nguồn Trình biên dịch Chương trình đích (Source program) (Compiler) (Target program) Thông báo lỗi (Error messages ) Ngữ cảnh trình biên dịch • Để tạo tra chương trình đích có khả thực thi (excutable) trình biên dịch ta phải có thêm số chương trình khác • Sơ đồ sau mô tả ngữ cảnh trình biên dịch hệ thống xử lí ngôn ngữ (language-processing system) Chương trình nguồn khung (Skeletal source program) Bộ tiền xử lí (Preprocessor) Chương trình nguồn (Source program) Trình biên dịch (Compiler) Chương trình hợp ngữ đích (Target assembly program) Trình dịch hợp ngữ (Assembler) Mã máy tái khả định (Relocatable machine code) Trình tải/liên kết (Loader/link-editor) Mã máy tuyệt đối (Absolute machine code) Thư viện/tập tin đối tượng (Library/object files) Các giai đoạn biên dịch chương trình • Quá trình biên dịch chia thành nhiều giai đoạn • Qua giai đoạn chương trình nguồn chuyển đổi từ dạng biểu sang dạng biểu diễn khác • Trong thục tế xây dựng trình biên dịch, giai đoạn nhóm lại với • Các giai doạn biên dịch minh hoạ hình vẽ Chương trình nguồn (Source program) Phân tích từ vựng (Lexical analyzer) Phân tích cú pháp (Syntax analyzer) Phân tích ngữ nghĩa (Semantic analyzer) Quản lí bảng kí tự (Symbol-table manager) Sinh mã trung gian (Intermediate code generator) Tối ưu mã (Code optimizer) Sinh mã (Code generator) Chương trình đích (Target program) Quản lí lỗi (Error handler) Phân tích từ vựng (Lexical Analysis) • Giai đoạn phân tích từ vựng đọc chương trình nguồn từ trái sang phải (linear analysis/scanning) để tách thành mã thông báo (token) • Trong trình phân tích từ vựng khoảng trắng (blank) bị bỏ qua • Ví dụ : Quá trình phân tích từ vựng cho câu lệnh gán position := initial + rate * 60 tách thành token sau: Định danh (identifier) position Ký hiệu phép gán := Định danh initial Ký hiệu phép cộng + Định danh rate Ký hiệu phép nhân * Số 60 Phân tích cú pháp (Syntax Analysis) • Giai đoạn phân tích cú pháp thực công việc nhóm token chương trình nguồn thành cụm từ văn phạm (grammatical phrase) • Thông thường cụm từ văn phạm biểu diễn phân tích cú pháp (parse tree) với : - Ngôn ngữ định nghĩa luật sinh (production) - Phân tích cú pháp dựa vào luật sinh để xây dựng phân tích cú pháp Lược đồ dịch • Lược đồ dịch (translation scheme) văn phạm phi ngữ cảnh thuộc tính kết hợp với ký hiệu văn phạm hành vi ngữ nghĩa đặt cặp dấu { } xen vào bên phải luật sinh Ví dụ 4.11: Lược đồ dịch biểu thức trung tố với phép cộng trừ thành dạng hậu tố: ETR R addop T { print ( addop.lexeme) } R1 | T num { print ( num.val) } • Với biểu thức - + ta có phân tích cú pháp phía Khi áp dụng phép duyệt depth- first có kết dạng hậu tố 95-2+ E T { print('9') } R { print('-') } - T { print('5') } + R T { print('+') } R { print('2') } • Cách xây dựng lược đồ dịch - Trường hợp chứa thuộc tính tổng hợp: Với luật ngữ nghĩa, ta tạo lệnh gán tương ứng đặt vào cuối vế phải luật sinh Ví dụ 4.12: Luật sinh Luật ngữ nghĩa T T1 * F T.val := T1.val * F.val Ta có lược đồ dịch: T T1 * F { T.val := T1.val * F.val} - Trường hợp chứa thuộc tính tổng hợp thuộc tính kế thừa phải thoả mãn điều kiện: Thuộc tính kế thừa ký hiệu vế phải luật sinh phải xác định hành vi nằm trước ký hiệu Một hành vi không tham khảo tới thuộc tính tổng hợp ký hiệu nằm bên phải hành vi Thuộc tính tổng hợp ký hiệu chưa kết thúc vế trái xác định sau tất thuộc tính mà tham khảo xác định Hành vi xác định thuộc tính đặt cuối vế phải luật sinh CHƯƠNG V Kiểm tra kiểu Mục tiêu: • Nắm cách định nghĩa hệ thống kiểu ngôn ngữ lập trình • Cách kiểm tra kiểu trình biên dịch Biểu thức kiểu • Kiểu ngôn ngữ lập trình kí hiệu biểu thức kiểu (type expression) • Biểu thức kiểu định nghĩa sau: Kiểu sở biểu thức kiểu: boolean, char, integer, real, type_error, void Một tên kiểu biểu thức kiểu Mỗi kiểu liệu có cấu trúc biểu thức kiểu, cấu trúc bao gồm: a Mảng (array): Nếu T biểu thức kiểu array(I, T) biểu thức kiểu Một mảng có tập số I phần tử có kiểu T b Tích (product): Nếu T1, T2 biểu thức kiểu tích Đề- T1* T2 biểu thức kiểu c Bản ghi (record): Là cấu trúc bao gồm tên trường, kiểu trường d Con trỏ (pointer): Nếu T biểu thức kiểu pointer(T) biểu thức kiểu T e Hàm (function): Hàm ánh xạ phần tử tập xác định (domain) D lên tập giá trị (range) R Một hàm biểu thức kiểu D R Đặc tả kiểm tra kiểu đơn giản • Trong phần mô tả kiểm tra kiểu cho ngôn ngữ đơn giản kiểu định danh khai báo trước sử dụng • Bộ kiểm tra kiểu (type checker) lược đồ dịch, tổng hợp kiểu biểu thức từ kiểu biểu thức • Định nghĩa ngôn ngữ đơn giản: Văn phạm sau sinh chương trình, biểu diễn ký hiệu chưa kết thúc P chứa chuỗi khai báo D biểu thức đơn giản E PD;E D D ; D | id : T T char | integer | array[num] of T | T E literal | num | id | E mod E | E [E] | E Ví dụ 5.1: Chương trình sau sinh văn phạm key: integer; key mod 1999 • Ta có lược đồ dịch để lưu trữ kiểu định danh PD;E DD;D D id : T {addtype(id.entry, T.type) } T char {T.type := char } T integer {T.type := integer } T T1 {T.type := pointer(T1.type) } T array[num] of T1 {T.type := array(1 num.val, T1.type) } Kiểm tra kiểu biểu thức • Lược đồ dịch cho kiểm tra kiểu biểu thức: E literal E num E id E E1 mod E2 E E1[E2] E E1 {E.type := char } {E.type := integer } {E.type := lookup(id.entry) } {E.type := if E1.type = integer and E2.type = integer then integer else type_error } {E.type := if E2.type =integer and E1.type = array(s,t) then t else type_error } { E.type := if E1.type = pointer(t) then t else type_error } Kiểm tra kiểu câu lệnh • Các câu lệnh cấu tạo lên ngôn ngữ giá trị, ta gán cho chúng kiểu void • Lược đồ dịch cho kiểm tra kiểu lệnh: S id := E S if E then S1 S while E S1 S S1 ; S2 { S.type := if id.type = E.type then void else type_error } {S.type := if E.type = boolean then S1.type else type_error } {S.type := if E.type = boolean then S1.type else type_error } {S.type := if S1.type = void and S2.type = void then void else type_error } Kiểm tra kiểu hàm • Việc ghép hàm với đối (argument) diễn đạt luật sinh: E E ( E ) • Lược đồ dịch kiểm tra kiểu cho hàm: E E1 (E2) {E.type := if E2.type = s and E1.type = s -> t then t else type_error } • Nếu có nhiều đối có kiểu tương ứng T1, T2, , Tn coi đối có kiểu T1*T2* *Tn Chuyển đổi kiểu • Xét biểu thức x + i x có kiểu real i có kiểu integer Trình biên dịch thực việc chuyển đổi kiểu để hai toán hạng có kiểu phép toán cộng xảy • Bộ kiểm tra kiểu trình biên dịch thêm phép toán biến đổi kiểu vào biểu diễn trung gian chương trình nguồn • Chẳng hạn ký hiệu hậu tố x + i là: x i inttoreal real+ (inttoreal đổi số nguyên i thành số thực, real+ thực phép cộng số thực) 10 • Ép kiểu (coercion): Việc chuyển kiểu liệu sang kiểu khác gọi ẩn (implicit) làm tự động compiler gọi (explicit) giải người lập trình Ví dụ 5.2: Hàm ord() pascal chuyển kiểu kí tự sang số nguyên, phép chuyển đổi Lệnh a:=b; a kiểu real, b kiểu integer thực compiler thực ép kiểu biến b sang kiểu real trước thực lệnh gán, phép chuyển đổi ẩn 11 [...]... CHƯƠNG II Phân tích từ vựng Mục tiêu: Nắm được vai trò của giai đoạn phân tích từ vựng, sử dụng các khái niệm biểu thức chính qui (regular expression) và ô- tô- mát hứu hạn (finite automata) trong việc biểu diễn và nhận biết ngôn ngữ 1 Vai trò của phân tích từ vựng • Đây là giai đoạn đầu tiên của quá trình biên dịch • Nhiệm vụ chính: Đọc từng kí tự vào (input characters) từ chương trình nguồn và nhóm lại... giai đoạn biên dịch có thể gặp nhiều lỗi, ví dụ: Giai đoạn phân tích từ vựng gặp lỗi khi các ký tự không thể ghép thành một token Giai đoạn phân tích cú pháp gặp lỗi khi các token không thể kết hợp với nhau theo đúng cấu trúc ngôn ngữ Giai đoạn phân tích ngữ nghĩa gặp lỗi khi các toán hạng có kiểu không đúng yêu cầu của phép toán • Sau khi phát hiện ra lỗi, tùy thuộc vào trình biên dịch mà có... position 60 * rate inttoreal 60 4 Sinh mã trung gian (Intermediate Code Generator) • Sau khi phân tích cấu trúc và ngữ nghĩa, một số trình biên dịch sẽ tạo ra một dạng biểu diễn trung gian của chương trình nguồn • Mã trung gian có 2 đặc tính quan trọng: Dễ tạo và dễ dàng chuyển đổi thành chương trình ích • Mã trung gian có cách biểu diễn Thông thường người ta sử dụng dạng "mã máy 3 địa chỉ" (three-address... giai đoạn phân tích cú pháp sau đó Source Lexical program analyzer Token Parser Get next token Symbol table 2 • Phân tích từ vựng giúp cho các giai đoạn biên dịch tiếp theo dễ dàng hơn, ví dụ: Giai đoạn phân tích cú pháp không phải quan tâm đến các khoảng trắng cũng như các lời chú trích vì nó đã được loại bỏ khi khi phân tích từ vựng • Giảm đáng kể thời gian đọc chương trình nguồn và nhóm thành các... phân cấp của giai đoạn phân tích cú pháp để xác định các toán tử, toán hạng của các biểu thức và câu lệnh • Một phần quan trọng trong giai đoạn phân tích ngữ nghĩa là kiểm tra kiểu (type checking) và ép chuyển đổi kiểu Ví dụ: Trong câu lệnh position := initial + rate * 60 Giả sử các biến rate, initial và position được khai báo là real, 60 là số integer vì vậy trình biên dịch sẽ đổi số nguyên 60 thành... toán • Sau khi phát hiện ra lỗi, tùy thuộc vào trình biên dịch mà có các cách xử lý lỗi khác nhau: Quá trình biên dịch có thể dừng lại hoặc tiếp tục Ví dụ: Biên dịch 1 câu lệnh gán position := initial + rate * 60 Phân tích từ vựng id1 := id2 + id3 * 60 Phân tích cú pháp := + id1 id2 * id3 60 Phân tích ngữ nghĩa := + id1 id2 * id3 Inttoreal | 60 Sinh mã trung gian temp1 := inttoreal (60) temp2 := id3... id3 thay thế cho position, initial và rate để nhấn mạnh rằng tên của một nhận dạng sẽ bị thay đổi khi ta biên dịch chương trình 5 Tối ưu mã (Code Optimizer) • Giai đoạn tối ưu mã cố gắng tối ưu mã trung gian để thu được mã máy thực hiện nhanh hơn Ví dụ: Mã trung gian nêu trên có thể tối ưu thành: temp1 := id3 * 60.0 id1 := id2 + temp1 6 Sinh mã (Code generation) • Giai đoạn cuối cùng của biên dịch. .. trình biên dịch là ghi lại các định danh được sử dụng trong chương trình nguồn và thu thập các thông tin về các thuộc tính khác nhau của mỗi định danh • Các thuộc tính cung cấp thông tin về vị trí bộ nhớ được cấp phát cho một định danh, kiểu và phạm vi của định danh • Nếu định danh là tên của một thủ tục thì thuộc tính là các thông tin về số lượng và kiểu của các đối số, phương pháp truyền đối số và. .. của định danh • Trong quá trình phân tích từ vựng, tên các định danh được tìm thấy và nó được đưa vào bảng ký hiệu nhưng thường thì các thuộc tính của nó chưa xác định được trong giai đoạn này • Các thuộc tính khác của các định danh sẽ được bổ sung trong các giai đoạn biên dịch tiếp theo Ví dụ: Trong Pascal câu lệnh khai báo biến Var position, initial, rate: real; Sau khi phân tích từ vựng bảng quản lí... như sau : 1) Nếu id1 là một định danh và expr2 là một biểu thức thì id1 := expr2 là một lệnh (stmt) 2) Nếu expr1 là một biểu thức và stmt2 là một lệnh thì while (expr1) do stmt2 If (expr1) then stmt2 đều là các lệnh 3 Phân tích ngữ nghĩa (Semantic Analysis) • Giai đoạn phân tích ngữ nghĩa sẽ thực hiện việc kiểm tra xem chương trình nguồn có chứa lỗi về ngữ nghĩa hay không • Tập hợp thông tin về các