Giới thiệu
Trong lab này, chúng ta sẽ khám phá lệnh bison, một công cụ tạo trình phân tích cú pháp được sử dụng trong quá trình phát triển trình biên dịch và trình thông dịch. Bison là một phần mềm mã nguồn mở triển khai YACC, một công cụ mạnh mẽ để tạo trình phân tích cú pháp từ một đặc tả ngữ pháp phi ngữ cảnh. Chúng ta sẽ bắt đầu bằng cách cài đặt gói bison trên môi trường Ubuntu 22.04 của mình, sau đó tạo một tệp ngữ pháp đơn giản và tạo một trình phân tích cú pháp bằng lệnh bison. Cuối cùng, chúng ta sẽ tìm hiểu cách xử lý lỗi cú pháp trong trình phân tích cú pháp đã tạo.
Lab này bao gồm các bước sau:
- Giới thiệu về Lệnh bison
- Tạo Trình Phân Tích Cú Pháp với bison
- Xử Lý Lỗi Cú Pháp trong bison
Giới thiệu về Lệnh bison
Trong bước này, chúng ta sẽ khám phá lệnh bison, là một công cụ tạo trình phân tích cú pháp được sử dụng trong quá trình phát triển trình biên dịch và trình thông dịch. Bison là một phần mềm mã nguồn mở triển khai YACC (Yet Another Compiler-Compiler), một công cụ mạnh mẽ để tạo trình phân tích cú pháp từ một đặc tả ngữ pháp phi ngữ cảnh.
Đầu tiên, hãy cài đặt gói bison trong môi trường Ubuntu 22.04 của chúng ta:
sudo apt-get update
sudo apt-get install -y bison
Ví dụ đầu ra:
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
m4
Suggested packages:
bison-doc
The following NEW packages will be installed:
bison m4
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,141 kB of archives.
After this operation, 4,470 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
...
Bây giờ chúng ta đã cài đặt bison, hãy tạo một tệp ngữ pháp đơn giản để tạo trình phân tích cú pháp. Tạo một tệp mới có tên example.y
trong thư mục ~/project
với nội dung sau:
%{
#include <stdio.h>
%}
%token NUM
%%
input:
| input line
;
line:
NUM '\n' { printf("Received number: %d\n", $1); }
;
%%
int main() {
yyparse();
return 0;
}
Tệp ngữ pháp này định nghĩa một ngôn ngữ đơn giản giống như máy tính có thể nhận ra và xử lý các số. Dòng %token NUM
khai báo một kiểu token cho các số và quy tắc line
chỉ định rằng một dòng hợp lệ bao gồm một số theo sau là một ký tự dòng mới.
Tạo Trình Phân Tích Cú Pháp với bison
Trong bước này, chúng ta sẽ tạo một trình phân tích cú pháp bằng lệnh bison dựa trên tệp ngữ pháp mà chúng ta đã tạo ở bước trước.
Đầu tiên, hãy tạo mã nguồn trình phân tích cú pháp từ tệp example.y
:
bison -d example.y
Lệnh này sẽ tạo hai tệp: example.tab.c
và example.tab.h
. Tệp example.tab.c
chứa triển khai trình phân tích cú pháp, trong khi example.tab.h
chứa các định nghĩa token.
Tiếp theo, chúng ta cần biên dịch mã nguồn trình phân tích cú pháp và liên kết nó với một lexer (scanner) để tạo ra tệp thực thi cuối cùng. Chúng ta sẽ sử dụng công cụ flex
để tạo lexer:
sudo apt update
sudo apt-get install -y flex
flex -o example.lex.c example.l
gcc -o example example.tab.c example.lex.c
Lệnh flex
tạo ra tệp example.lex.c
, chứa triển khai lexer. Lệnh gcc
biên dịch các nguồn trình phân tích cú pháp và lexer và liên kết chúng để tạo ra tệp thực thi example
cuối cùng.
Bây giờ, hãy kiểm tra trình phân tích cú pháp của chúng ta bằng cách chạy chương trình example
:
./example
123
Received number: 123
456
Received number: 456
Như bạn có thể thấy, trình phân tích cú pháp nhận dạng và xử lý chính xác các số đầu vào.
Xử Lý Lỗi Cú Pháp trong bison
Trong bước này, chúng ta sẽ tìm hiểu cách xử lý lỗi cú pháp trong trình phân tích cú pháp được tạo bởi bison.
Hãy sửa đổi tệp example.y
để bao gồm xử lý lỗi:
%{
#include <stdio.h>
%}
%token NUM
%error-verbose
%%
input:
| input line
| input error '\n' { yyerrok; }
;
line:
NUM '\n' { printf("Received number: %d\n", $1); }
| error '\n' { yyerror("Invalid input"); }
;
%%
void yyerror(const char *s) {
fprintf(stderr, "%s\n", s);
}
int main() {
yyparse();
return 0;
}
Các thay đổi chính là:
- Đã thêm
%error-verbose
để cung cấp thông báo lỗi chi tiết hơn. - Đã thêm một quy tắc
error
trong các productioninput
vàline
để xử lý lỗi cú pháp. - Đã triển khai hàm
yyerror
để in thông báo lỗi.
Bây giờ, hãy tạo lại trình phân tích cú pháp và kiểm tra nó:
bison -d example.y
flex -o example.lex.c example.l
gcc -o example example.tab.c example.lex.c
Hãy thử chạy chương trình example
và nhập một số đầu vào không hợp lệ:
./example
abc
example.y:12: syntax error, unexpected error, expecting NUM
Invalid input
123
Received number: 123
Như bạn có thể thấy, trình phân tích cú pháp xác định và báo cáo chính xác lỗi cú pháp khi chúng ta nhập "abc" thay vì một số.
Tóm tắt
Trong lab này, chúng ta đã khám phá lệnh bison, là một công cụ tạo trình phân tích cú pháp được sử dụng trong quá trình phát triển trình biên dịch và trình thông dịch. Đầu tiên, chúng ta đã học cách cài đặt gói bison trên Ubuntu 22.04 và sau đó tạo một tệp ngữ pháp đơn giản để định nghĩa một ngôn ngữ giống như máy tính. Sau đó, chúng ta đã tạo mã nguồn trình phân tích cú pháp bằng lệnh bison, lệnh này tạo ra hai tệp: triển khai trình phân tích cú pháp và tệp tiêu đề. Cuối cùng, chúng ta đã học cách xử lý lỗi cú pháp trong trình phân tích cú pháp đã tạo.