Cách Sử Dụng Từ “Backus Normal Form”
Trong bài viết này, chúng ta sẽ khám phá thuật ngữ “Backus Normal Form” (BNF) – một ký pháp dùng để định nghĩa cú pháp của ngôn ngữ lập trình. Bài viết cung cấp 20 ví dụ sử dụng (ở dạng quy tắc BNF) chính xác và có nghĩa, cùng hướng dẫn chi tiết về ý nghĩa, cách dùng, các ký hiệu phổ biến, và các lưu ý quan trọng.
Phần 1: Hướng dẫn sử dụng “Backus Normal Form” và các lưu ý
1. Ý nghĩa cơ bản của “Backus Normal Form”
“Backus Normal Form” (BNF) là một ký pháp (notation) được sử dụng để định nghĩa cú pháp của ngôn ngữ hình thức, thường là ngôn ngữ lập trình. Nó xác định cách các thành phần của ngôn ngữ kết hợp với nhau để tạo thành các câu lệnh hợp lệ.
Dạng liên quan: Extended Backus-Naur Form (EBNF) (phiên bản mở rộng của BNF).
Ví dụ:
<expression> ::= <term> | <expression> + <term>
(Định nghĩa biểu thức)
2. Cách sử dụng “Backus Normal Form”
a. Các ký hiệu cơ bản
::=
Được định nghĩa là (is defined as). Biểu thị vế trái được định nghĩa bởi vế phải.
Ví dụ:<digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
|
Hoặc (or). Biểu thị một trong các lựa chọn.
Ví dụ:<letter> ::= a | b | c | ... | z
<...>
Non-terminal. Biểu thị một ký hiệu chưa được định nghĩa hoàn toàn, cần được định nghĩa thêm.
Ví dụ:<identifier>
- Terminal
Một ký tự hoặc chuỗi ký tự cụ thể, không cần định nghĩa thêm.
Ví dụ:+
,-
,*
,/
,(
,)
b. Ví dụ về quy tắc BNF
- Định nghĩa một số nguyên:
<integer> ::= <digit> | <integer> <digit>
- Định nghĩa một số thực:
<real> ::= <integer> . <integer>
c. Biến thể và cách dùng trong biểu thức
Ký hiệu | Ý nghĩa | Ví dụ | Giải thích |
---|---|---|---|
::= |
Được định nghĩa là | <statement> ::= <assignment> | <conditional> |
Một câu lệnh có thể là phép gán hoặc câu lệnh điều kiện. |
| |
Hoặc | <boolean> ::= true | false |
Một giá trị boolean có thể là “true” hoặc “false”. |
<...> |
Non-terminal | <expression> ::= <term> + <term> |
<expression> là một non-terminal. |
3. Một số ứng dụng thông dụng của BNF
- Định nghĩa cú pháp ngôn ngữ lập trình: BNF được sử dụng rộng rãi để mô tả cú pháp của các ngôn ngữ lập trình như C, Java, Python.
- Trình biên dịch (Compiler): BNF giúp xây dựng trình phân tích cú pháp (parser) trong trình biên dịch.
- Công cụ phân tích cú pháp: BNF được sử dụng trong các công cụ như Yacc và Bison để tạo ra trình phân tích cú pháp tự động.
4. Lưu ý khi sử dụng BNF
a. Tính chính xác và rõ ràng
- Quy tắc BNF phải chính xác và không mơ hồ để đảm bảo cú pháp được định nghĩa rõ ràng.
Ví dụ: Tránh các định nghĩa đệ quy không có điểm dừng.
b. Khả năng đọc hiểu
- Quy tắc BNF nên dễ đọc và dễ hiểu để người khác có thể hiểu được cú pháp của ngôn ngữ.
Ví dụ: Sử dụng tên non-terminal có ý nghĩa.
c. Phân biệt Terminal và Non-terminal
- Terminal (ký tự cụ thể) và Non-terminal (ký hiệu cần định nghĩa thêm) cần được phân biệt rõ ràng.
Ví dụ:<variable> ::= a | b | c
(a
,b
,c
là Terminal).
5. Những lỗi cần tránh
- Định nghĩa đệ quy không có điểm dừng:
– Sai: *<expression> ::= <expression> + <expression>
* (Thiếu trường hợp cơ bản)
– Đúng:<expression> ::= <term> | <expression> + <term>
- Sử dụng ký hiệu không nhất quán:
– Sai: *<Number> ::= 1 | 2 | <number> 3
* (Không nhất quán trong cách đặt tên)
– Đúng:<number> ::= 1 | 2 | <number> 3
- Định nghĩa mơ hồ:
– Sai: *<statement> ::= if <condition> then <statement> | if <condition> then <statement> else <statement>
* (Dẫn đến dangling else problem).
6. Mẹo để ghi nhớ và sử dụng hiệu quả
- Hiểu rõ ý nghĩa của các ký hiệu:
::=
,|
,<...>
. - Bắt đầu với các quy tắc đơn giản: Sau đó mở rộng dần.
- Kiểm tra tính chính xác: Đảm bảo không có lỗi cú pháp và định nghĩa không mơ hồ.
Phần 2: Ví dụ sử dụng “Backus Normal Form” và các dạng liên quan
Ví dụ minh họa
<program> ::= <statements>
(Một chương trình là một tập hợp các câu lệnh)<statements> ::= <statement> | <statements> <statement>
(Câu lệnh có thể là một hoặc nhiều câu lệnh)<statement> ::= <assignment> | <conditional> | <loop>
(Một câu lệnh có thể là phép gán, điều kiện hoặc vòng lặp)<assignment> ::= <variable> = <expression>
(Phép gán là biến bằng biểu thức)<conditional> ::= if <condition> then <statements> else <statements>
(Câu lệnh điều kiện)<loop> ::= while <condition> do <statements>
(Vòng lặp while)<expression> ::= <term> | <expression> + <term> | <expression> - <term>
(Biểu thức bao gồm các số hạng)<term> ::= <factor> | <term> * <factor> | <term> / <factor>
(Số hạng bao gồm các thừa số)<factor> ::= <variable> | <number> | ( <expression> )
(Thừa số)<condition> ::= <expression> <relation> <expression>
(Điều kiện)<relation> ::= == | != | < | > | <= | >=
(Quan hệ)<variable> ::= a | b | c | ... | z
(Biến)<number> ::= <digit> | <number> <digit>
(Số)<digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
(Chữ số)<string> ::= " <characters> "
(Chuỗi)<characters> ::= <character> | <characters> <character>
(Ký tự)<character> ::= a | b | c | ... | z | 0 | 1 | ... | 9 | | ...
(Ký tự có thể là chữ cái, số, dấu cách…)<boolean> ::= true | false
(Giá trị boolean)<function_call> ::= <function_name> ( <arguments> )
(Gọi hàm)<arguments> ::= <expression> | <arguments> , <expression>
(Đối số)