2 điểm bởi GN⁺ 2024-11-09 | 1 bình luận | Chia sẻ qua WhatsApp

Macro

  • Macro trong Rust được dùng để loại bỏ mã trùng lặp và giảm bớt các phần lặp lại.
  • Các nút câu lệnh của sqleibniz phải triển khai trait Node, điều này dẫn đến nhiều mã bị lặp.
  • Có thể dùng macro để tự động hóa việc định nghĩa struct và triển khai trait Node.

Macro loại bỏ mã trùng lặp

  • Macro định nghĩa struct, thêm chú thích tài liệu và triển khai các hàm đáp ứng trait Node.
  • Macro có thể thêm nhiều trường khác nhau thông qua các định nghĩa metavariable lặp lại.

Kiểm thử

  • Trong Rust, có thể triển khai cách làm tương tự như kiểm thử dạng bảng của Go.
  • Có thể dùng các macro test_group_pass_assert!test_group_fail! để kiểm thử nhiều cặp đầu vào và đầu ra kỳ vọng.

Kiểm thử parser

  • Trong mô-đun parser cũng dùng các macro tương tự để kiểm thử kết quả của các câu lệnh SQL.
  • Hàm sql_stmt_prefix được dùng để kiểm thử câu lệnh SQL EXPLAIN.

Nhược điểm của macro

  • rust-analyzer không hoạt động tốt bên trong macro, và tài liệu còn thiếu.

So khớp ký tự

  • Có thể dùng macro matches! của Rust để so sánh ký tự một cách dễ dàng.
  • Có ví dụ kiểm tra xem một ký tự cho trước có phải là chữ số theo chuẩn SQLite hay không.

So khớp token

  • Sau khi lexer chuyển đổi luồng ký tự thành luồng token, parser sẽ dùng chúng để tạo cây cú pháp.
  • Dùng câu lệnh match để nhận diện loại token.

Hiển thị lỗi

  • Thông qua xử lý lỗi, có thể cung cấp cho người dùng thông báo lỗi rõ ràng.

Tính năng tùy chọn

  • Có thể dùng kiểu Option của Rust để kiểm tra sự tồn tại của giá trị, kiểm tra điều kiện hoặc cung cấp giá trị mặc định.
  • Các phương thức như is_some_and, map, map_or giúp cải thiện độ dễ đọc của mã.

Iterator

  • Có thể dùng iterator của Rust để lọc ký tự và xử lý theo quy tắc phân tích số của SQLite.

1 bình luận

 
GN⁺ 2024-11-09
Bình luận Hacker News
  • Gặp khó khăn khi dùng Rust do borrow checker và sự phức tạp của quản lý bộ nhớ. Thích các yếu tố lập trình hàm (FP) của Rust nhưng cuối cùng quyết định tìm ngôn ngữ khác. Sau đó phát hiện ra OCaml và cảm thấy hài lòng

  • Có vẻ như tác giả chưa có nhiều kinh nghiệm với Rust và các ý tưởng PL. AST có lẽ sẽ đơn giản hơn nếu được định nghĩa bằng kiểu dữ liệu đại số. Macro hoạt động khác nhau ở hầu hết các ngôn ngữ, nhưng chủ yếu được dùng để loại bỏ trùng lặp mã và giảm lặp lại

  • Trình phân tích cú pháp viết bằng Haskell rất nổi bật về độ đơn giản và tính dễ đọc. Nó gần như đọc giống BNF, hầu như không có các bước thủ tục kỹ thuật nên có thể tập trung vào chính ngữ pháp thực tế

  • Đã có kinh nghiệm viết parser bằng Ragel, Go, Java, C++, C. Viết parser JSON bằng C có thể còn đơn giản hơn mã Rust. Hạ tầng parser đã phát triển đến mức có thể tạo parser từ eBNF

  • Đã viết một trình disassembler và emulator eBPF bằng Rust, và cho rằng Rust phù hợp với công việc parsing. Tuy nhiên, việc dùng macro lại mang cảm giác khác với làm việc trong chính ngôn ngữ

  • Thích bài nói chuyện của Rob Pike về lexical scanning trong Go. Đây là một cách tiếp cận mang tính giáo dục và thanh lịch

  • Có thể dùng thư viện parser combinator để triển khai parser giao thức hiệu năng cao trong môi trường nhúng. Cũng có thể dùng cùng thư viện đó để viết parser giao thức nhúng

  • Khi viết một parser AST hoàn chỉnh bằng Rust, việc biểu diễn hệ phân cấp của các kiểu AST cụ thể khá khó khăn. Phải dùng những mẹo kiểu dữ liệu kỳ lạ và macro

  • Phân tích cú pháp sqlite là một công việc khó. sqlite là một nguồn cảm hứng. Sơ đồ railroad rất hữu ích, và trình tạo parser Lemon chưa được đánh giá đúng mức

  • Các ngôn ngữ có kiểu dữ liệu đại số rất phù hợp để phân tích cú pháp sqlite. TypeScript cũng có thể là một lựa chọn tốt. Đã viết một phần giới thiệu ngắn về cách viết parser bằng Rust