Các ngôn ngữ hiện đại vẫn sử dụng trình tạo phân tích cú pháp?


38

Tôi đã nghiên cứu về bộ trình biên dịch gcc trên wikipedia ở đây , khi điều này xuất hiện:

GCC bắt đầu sử dụng các trình phân tích cú pháp LALR được tạo bằng Bison, nhưng dần dần chuyển sang các trình phân tích cú pháp đệ quy gốc viết tay; cho C ++ năm 2004 và cho C và Objective-C năm 2006. Hiện tại tất cả các giao diện người dùng đều sử dụng trình phân tích cú pháp đệ quy gốc viết tay

Vì vậy, bằng câu cuối cùng đó, (và nhiều như tôi tin tưởng wikipedia) tôi chắc chắn có thể nói rằng "C (gcc), C ++ (g ++), Objective-C, Objective-C ++, Fortran (gfortran), Java (gcj), Ada (GNAT), Go (gccgo), Pascal (gpc), ... Mercury, Modula-2, Modula-3, PL / I, D (gdc) và VHDL (ghdl) "đều là những mặt trước không có sử dụng trình tạo phân tích cú pháp lâu hơn. Đó là, tất cả đều sử dụng trình phân tích cú pháp viết tay.

Câu hỏi của tôi là, thực tế này có mặt khắp nơi? Cụ thể, tôi đang tìm câu trả lời chính xác cho "việc triển khai chuẩn / chính thức của x có trình phân tích cú pháp viết tay" cho x trong [Python, Swift, Ruby, Java, Scala, ML, Haskell] không? (Trên thực tế, thông tin về bất kỳ ngôn ngữ nào khác cũng được chào đón ở đây.) Tôi chắc chắn rằng tôi có thể tự mình tìm thấy ngôn ngữ này sau khi đào rất nhiều. Nhưng tôi cũng chắc chắn rằng cộng đồng có thể dễ dàng trả lời được. Cảm ơn!


3
Điểm dữ liệu: CPython có trình tạo bộ phân tích cú pháp LALR (pgen) tại nhà. Không biết về phần còn lại.

8
Điểm dữ liệu: Ghc (haskell) sử dụng trình tạo trình phân tích cú pháp LALR (hạnh phúc), cũng như OCaml.
Twan van Laarhoven

1
Nên là "Trình biên dịch hiệu suất cao hiện đại ..." hoặc tương tự, vì ngôn ngữ là thông số không phải là triển khai, trong khi đó là trình biên dịch không hoặc không sử dụng trình phân tích cú pháp do máy tạo.
dmckee

@dmckee, vâng bạn đúng. Tuy nhiên, việc đặt tên bắt đầu dài và ít đi đến điểm. Hãy thoải mái chỉnh sửa nó mặc dù nếu bạn sáng tạo hơn tôi!
eatonphil

Về ML: MLton sử dụng trình tạo trình phân tích cú pháp dành riêng cho ML, tôi chắc chắn 90% rằng SML / NJ cũng vậy mặc dù tôi không quen với nó. Bạn có thể hoặc không muốn xem xét "viết tay".
Patrick Collins

Câu trả lời:


34

AFAIK, GCC sử dụng các trình phân tích cú pháp viết tay đặc biệt để cải thiện chẩn đoán lỗi cú pháp (nghĩa là đưa ra các thông điệp có ý nghĩa của con người về lỗi cú pháp).

Lý thuyết phân tích cú pháp (và các trình tạo phân tích cú pháp giảm dần từ nó) chủ yếu là về việc nhận ra và phân tích một cụm từ đầu vào chính xác . Nhưng chúng tôi mong đợi từ các trình biên dịch rằng chúng đưa ra một thông báo lỗi có ý nghĩa (và chúng có thể phân tích một cách có ý nghĩa phần còn lại của đầu vào sau lỗi cú pháp), đối với một số đầu vào không chính xác.

Ngoài ra, các ngôn ngữ cũ - như C11 hoặc C ++ 11- (đã cũ về mặt khái niệm, ngay cả khi bản sửa đổi mới nhất của chúng chỉ mới ba tuổi) hoàn toàn không có ngữ cảnh. Đối phó với sự nhạy cảm ngữ cảnh đó trong ngữ pháp cho các trình tạo phân tích cú pháp (ví dụ như bò rừng hoặc thậm chí menhir ) là rất khó khăn.


2
Đồng tình. Phục hồi tốt từ các lỗi phân tích cú pháp (khi bạn không muốn dừng phân tích cú pháp ở lỗi đầu tiên, là Borland Pascal cũ) và tạo các thông báo lỗi chất lượng tốt (bao gồm các gợi ý và đề xuất để giải quyết, như con người muốn) nhiệm vụ nhạy cảm, heuristic. Chúng có thể được thực hiện trên đầu ra trình tạo trình phân tích cú pháp chứng khoán, phần nào, nhưng đó là một khẩu hiệu.
Jonathan Eunice

2
Dealing with that context sensitiveness in grammars for parser generators is boringly difficult. Cũng ít nhiều không thể vì các công cụ này tạo ra các trình phân tích cú pháp không ngữ cảnh. Vị trí chính xác để kiểm tra xem có tất cả các ràng buộc theo ngữ cảnh hay không là sau khi bạn đã tạo cây phân tích cú pháp nếu bạn đang sử dụng các công cụ như thế này.
dtech

7

Trình tạo phân tích cú pháp và công cụ phân tích cú pháp khá chung chung. Ưu điểm của tính tổng quát là việc xây dựng một trình phân tích cú pháp chính xác một cách nhanh chóng và làm cho nó hoạt động dễ dàng, trong sơ đồ tổng thể của mọi thứ.

Công cụ phân tích cú pháp tự chịu đựng trên mặt trận hiệu suất vì tính tổng quát của nó. Bất kỳ mã viết tay nào cũng sẽ luôn nhanh hơn đáng kể so với các công cụ phân tích cú pháp điều khiển bảng.

Khu vực thứ hai mà các trình tạo / trình phân tích cú pháp gặp khó khăn là tất cả các ngôn ngữ lập trình thực đều nhạy cảm với ngữ cảnh, thường theo những cách khá tinh tế. Các ngôn ngữ LR không có ngữ cảnh, có nghĩa là có nhiều sự tinh tế về định vị và môi trường không thể truyền đạt đúng trong cú pháp. Các ngữ pháp được quy cho cố gắng giải quyết các quy tắc ngôn ngữ cơ bản như "khai báo trước khi sử dụng", v.v. Việc kết nối độ nhạy ngữ cảnh này vào mã viết tay là điều dễ dàng.


15
Trích dẫn cho yêu cầu thực hiện xin vui lòng? Được điều khiển theo bảng có thể là một tối ưu hóa hiệu suất đáng kể và các trình tạo có quyền truy cập vào các thuật toán rất hiệu quả nhưng hầu như không bao giờ được thực hiện bằng tay (chính xác vì chúng là một mớ hỗn độn không thể xuyên thủng của các bảng và số ma thuật).

2
Và về khu vực thứ hai: Nhiều nhiều ngôn ngữ lập trình động sản lớn không phải là bối cảnh nhạy cảm trong bất kỳ ý nghĩa áp dụng (bạn phải tham khảo các tập tất cả các giá trị chương trình sau khi kiểm tra kiểu và như vậy, đó là không bao giờ những gì một viết tay hoặc trình phân tích cú pháp tạo ra cố gắng phân tích cú pháp). Đúng là các trình phân tích cú pháp viết tay linh hoạt hơn và điều này hữu ích đối với một số ngôn ngữ, nhưng chủ yếu là trong lĩnh vực phục hồi và báo cáo lỗi, gia tăng, v.v. muốn viết một ngữ pháp như vậy là một câu chuyện khác nhau). -1

Nếu bạn sử dụng thông tin bảng biểu tượng trong quá trình phân tích cú pháp, thì bạn cũng có thể gọi nó là phân biệt ngữ cảnh. Các ngữ pháp được quy cho chắc chắn không có ngữ cảnh, mặc dù tôi không nghĩ chúng hoàn toàn nhạy cảm với ngữ cảnh. Các điểm khác của bạn về phục hồi lỗi và báo cáo được thực hiện tốt.
BobDalgleish

1
C và C ++ cần thông tin bảng biểu tượng trong quá trình phân tích cú pháp (hoặc chấp nhận một cây phân tích ít cụ thể hơn, trong đó không có sự phân biệt nào được thực hiện giữa, ví dụ, các câu lệnh biểu thức và khai báo biến). Nhưng tôi đã không nghĩ về những điều đó. Các ngôn ngữ như Java, Lisps, JavaScript, Ruby, Python, Go, Rust, Scala, Swift, Haskell (và có thể nhiều ngôn ngữ khác, có thể là C # và ML nữa?) Không cần bất kỳ thông tin nào như vậy để xây dựng loại AST bạn muốn dù sao cũng muốn Nhiều người trong số họ thực sự có ngữ pháp LL (1), hoặc thậm chí là ngữ pháp LALR.

1
trích dẫn cho tất cả các ngôn ngữ thực sự nhạy cảm bối cảnh xin vui lòng?
psr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.