Loại trình phân tích cú pháp mạnh nhất là gì?


28

Là một dự án phụ, tôi đang viết một ngôn ngữ bằng Python. Tôi đã bắt đầu bằng cách sử dụng một bản sao flex / bison có tên gọi là Ply, nhưng đang đi ngược lại với sức mạnh của những gì tôi có thể diễn đạt với phong cách ngữ pháp đó và tôi không quan tâm đến việc hack ngôn ngữ của mình vì không khớp với trở kháng công cụ. Do đó, tôi không ác cảm với việc viết của riêng mình.

Vì vậy, loại trình phân tích cú pháp mạnh nhất là gì? Trích dẫn cho các bài báo (cũng như các bài viết giới thiệu nhiều hơn) sẽ được hoan nghênh.

(Tôi biết rằng 'mạnh mẽ' không được xác định chính xác, nhưng hãy thả lỏng một chút và xem câu trả lời đi đâu)


1
Downvote: không nghiên cứu cấp độ.
Warren Schudy

3
@Warren: Tôi đã kiểm tra Câu hỏi thường gặp trước khi hỏi - đó dường như không phải là một yêu cầu.
Paul Biggar

1
thực tế có hai Câu hỏi thường gặp, một cho trang web chung và một cho CStheory. Câu hỏi CSthe chỉ ra rằng các câu hỏi có thể được trả lời bằng cách đọc Wikipedia là lạc đề; xem "Những loại câu hỏi quá cơ bản?" trong meta.cstheory.stackexchange.com/questions/225/ .
Warren Schudy

1
@Warren: Đó là câu hỏi thường gặp tôi đọc. Tôi đã đọc wikipedia, nhưng tôi cảm thấy điều này cần cái nhìn sâu sắc thực tế.
Paul Biggar

1
Theo bạn, có nghĩa là các trình phân tích cú pháp trong sản xuất hoặc lý thuyết, tức là các trình phân tích bao gồm các loại ngữ pháp khác với CFG?
Raphael

Câu trả lời:


33

Một ngữ pháp thường được định nghĩa là ngữ pháp Không ngữ cảnh - một định nghĩa chính xác được đưa ra trên trang Wikipedia, nhưng nó hoạt động giống như trong PLY, dựa trên Bison , lần lượt dựa trên yacc .

Ở đây nói rằng PLY sử dụng trình phân tích cú pháp LALR . Đây thực chất là một trình phân tích cú pháp LR , trong đó các bảng tra cứu được cô đọng, có thể đưa ra các xung đột phân tích cú pháp, làm giảm một số biểu cảm của ngữ pháp LR (nghĩa là một ngữ pháp không ngữ cảnh mà trình phân tích cú pháp LR có thể phân tích cú pháp). Nếu bạn muốn biết về những hạn chế của nhánh trình phân tích cú pháp cụ thể này và những hạn chế của các trình phân tích cú pháp khác, tổng quan về tất cả các loại kỹ thuật phân tích cú pháp (LL, LR và các loại khác) được đưa ra ở đây .

Để trả lời câu hỏi của bạn: tồn tại các thuật toán phân tích cú pháp có khả năng phân tích bất kỳ ngôn ngữ không ngữ cảnh nào, ngay cả khi ngôn ngữ không rõ ràng (nghĩa là có nhiều hơn một cách để diễn giải đầu vào):

Thuật toán đầu tiên như vậy là thuật toán CYK , không may có thời gian chạy là , trong đó n là độ dài của chuỗi đầu vào và | G | là kích thước của ngữ pháp và do đó không thực tế để phân tích ngôn ngữ.O(n3|G|)n|G|

Thuật toán thứ hai là thuật toán Earley . Thuật toán này cũng có khả năng phân tích cú pháp ngữ pháp miễn phí. Mặc dù thuật toán cần thời gian để phân tích một ngôn ngữ mơ hồ, nhưng nó chỉ cần thời gian O ( n 2 ) để phân tích một ngôn ngữ không rõ ràng. Ngoài ra, nó rõ ràng hoạt động trong thời gian tuyến tính đối với hầu hết các ngữ pháp LR và hoạt động đặc biệt tốt đối với các ngữ pháp đệ quy trái.O(n3)O(n2)

Ở đây bạn có thể tìm thấy một bài báo thảo luận về việc triển khai thực tế (một sự thích ứng) của thuật toán Earley. Họ kết luận: "Với tính tổng quát của phân tích Earley so với phân tích cú pháp LALR (1) ((gần như là những gì PLY làm)), và xem xét rằng ngay cả PEP ((thực hiện thuật toán Earley của họ)) thời gian tồi tệ nhất sẽ không được chú ý bởi người dùng, đây là một kết quả tuyệt vời ".

Loại trình phân tích cú pháp cuối cùng là trình phân tích cú pháp GLR . Đây là phiên bản tổng quát của phân tích cú pháp LR, có khả năng phân tích cú pháp bất kỳ ngôn ngữ không ngữ cảnh nào.

Một triển khai GLR hoàn thiện là ASF + SDF . Bison cũng có thể tạo trình phân tích cú pháp GLR, mặc dù việc triển khai của nó hơi khác so với thuật toán GLR 'tiêu chuẩn'. Các Elkhound Thuật toán là một thuật toán lai GLR / LALR. Nó sử dụng LALR khi có thể và GLR khi cần, để vừa nhanh và có khả năng phân tích cú pháp bất kỳ ngữ pháp nào.

Ngoài ngữ pháp miễn phí ngữ cảnh còn có ngữ pháp nhạy cảm ngữ cảnh , nhưng nói chung chúng khó phân tích và không thêm nhiều tính biểu cảm: bạn có thể làm nhiều hơn với chúng, nhưng đối với hầu hết các ứng dụng, việc sử dụng thêm không liên quan, trừ khi bạn phân tích cú pháp một ngôn ngữ tự nhiên.

Là bước cuối cùng có ngữ pháp không hạn chế . Tại thời điểm này, ngữ pháp đã hoàn tất, vì vậy không có ràng buộc nào có thể đưa ra về việc mất bao lâu để phân tích một ngôn ngữ cụ thể, điều không mong muốn đối với hầu hết các ứng dụng phân tích cú pháp. Sức mạnh thêm là gần như không bao giờ cần thiết. Nếu bạn muốn sử dụng tất cả sức mạnh đó, có sẵn máy ngôn ngữ .

Cuối cùng, việc thực hiện trình tạo trình phân tích cú pháp của riêng bạn không phải là chuyện nhỏ, đặc biệt là làm cho nó trở nên nhanh chóng. Cá nhân tôi vừa hoàn thành việc tạo phiên bản flex của riêng mình (trình tạo lexer) và trong khi điều này có vẻ như là một bài tập trong các vấn đề thuật toán tương đối đơn giản, đặc biệt là khi tôi cố gắng hỗ trợ Unicode. Cân nhắc sử dụng một triển khai đã có sẵn thay vì viết của riêng bạn.


1
Câu trả lời tuyệt vời !! Bất kỳ suy nghĩ về cách PEG phù hợp?
Paul Biggar

2
PEG là "khác biệt" so với CFG: có những CFG không phải là PEG và ngược lại. Tôi giới thiệu bạn đến đây: stackoverflow.com/questions/1857022/ cấp .
Alex ten Brink

Điều này cũng có thể được quan tâm: blog.ethz.ch/copton/2009/07/08/parsing-expression-grammars .
Alex ten Brink

1
Trên thực tế, hầu hết các trình tạo trình phân tích cú pháp phổ biến (yacc, Antlr, bison) cho phép các khái niệm không phải CF bằng các vị từ hoặc mã tùy ý kiểm tra một quy tắc có thể được áp dụng. quyết định ưu tiên. Điều này có thể được sử dụng để thực hiện ngữ nghĩa tĩnh chủ yếu vì cú pháp cơ bản vẫn còn trong ngữ cảnh tự nhiên.
Raphael

1
Các ngôn ngữ đệ quy chính xác là các ngôn ngữ có thể quyết định bằng các máy Turing luôn luôn tạm dừng. Do đó, bất kỳ ngôn ngữ nhạy cảm ngữ cảnh nào cũng được đệ quy, nhưng vì các ngôn ngữ nhạy cảm ngữ cảnh có thể quyết định theo thời gian theo cấp số nhân, nên có các ngôn ngữ đệ quy không nhạy cảm theo ngữ cảnh. Các ngữ pháp không bị hạn chế thậm chí còn mạnh hơn: vấn đề tạm dừng có thể được mô tả bằng một ngữ pháp không hạn chế, nhưng không phải là một ngôn ngữ đệ quy.
Alex ten Brink

15

Một bài báo tại ICFP 2010 năm nay, Total Parser Combinators , mô tả một thư viện kết hợp trình phân tích cú pháp có thể chứng minh được và cũng xác định rằng trong thư viện này "các trình kết hợp trình phân tích cú pháp càng biểu cảm càng tốt" cho rằng trình phân tích cú pháp được đảm bảo chấm dứt. Thật không may, tôi không nhớ lời giải thích mà tác giả đã đưa ra cho ý nghĩa "càng biểu cảm càng tốt", nhưng nó chắc chắn có vẻ phù hợp với câu hỏi của bạn về "sức mạnh".


1
Tôi có một chiếc xe không gây ô nhiễm, Thật ra nó cũng không di chuyển ... Vậy câu hỏi đặt ra là: loại ngôn ngữ nào được thư viện này phân tích? Tất nhiên không có nghĩa là công việc này không thú vị.
babou

2

Nếu bạn muốn vượt xa các ngữ pháp không ngữ cảnh để phân tích các ngôn ngữ lập trình, nhưng vẫn phân tích cú pháp trong thời gian đa thức, bạn có thể sử dụng các phân tích ngữ pháp biểu thức hoặc ngữ pháp boolean - sau này cũng có sẵn trong các hương vị LL và LR (xem tại đây ). Trong lý thuyết ngôn ngữ chính thức, cũng đã nghiên cứu các ngôn ngữ Church-Rosser mạnh mẽ nhưng có thể nhận biết theo thời gian tuyến tính , nhưng tôi không biết về bất kỳ trình tạo trình phân tích cú pháp đã triển khai nào cho các ngôn ngữ này.

Trong xử lý ngôn ngữ tự nhiên, ví dụ, thị hiếu là khác nhau, đối phó với sự mơ hồ (cũng: sự mơ hồ vốn có) và trật tự từ miễn phí đóng một vai trò rất nổi bật. Ở đây các từ khóa nhẹ ngữ cảnh nhạy cảmkhởi động lại automata có thể giúp bạn bắt đầu đọc.


1
Xem xét cách câu hỏi được hỏi và khiếu nại rằng CF quá hạn chế, câu trả lời của bạn rõ ràng là tốt nhất. Vì vậy, nó đi ...
babou

0

Công cụ tạo trình phân tích cú pháp:

ANTLR là rất tốt. Ngoài ra, bạn có thể xem JavaCC


Tôi không phải là một nhà khoa học máy tính nhất (mặc dù bằng cấp của tôi nói gì;), vì vậy lời nói của tôi có thể nặng ở đây. Tôi đồng ý với Sazzad - ANTLR là một công cụ rất mạnh. Nó rất đầy đủ và tôi vẫn chưa tìm thấy bất kỳ vấn đề nào với trình tạo trình phân tích cú pháp (LL (k) nếu tôi nhớ lại chính xác). Mặt khác, tôi vẫn chưa triển khai trình biên dịch cho một ngữ pháp hơi phức tạp ...
Jörgen Sigvardsson

5
Tôi nghĩ rằng bạn đang thiếu điểm của câu hỏi và có lẽ là toàn bộ trang web. Đó là về lý thuyết phân tích cú pháp, không phải về việc triển khai và các công cụ.
Paul Biggar
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.