Sự khác biệt giữa phân tích cú pháp LR (0) và SLR là gì?


82

Tôi đang nghiên cứu các khái niệm về trình biên dịch của mình tuy nhiên tôi hơi bối rối ... Google không tìm được câu trả lời chắc chắn cho tôi.

Bộ phân tích cú pháp SLR và LR (0) có phải là một và giống nhau không? Nếu không, sự khác biệt là gì?

Câu trả lời:


248

Cả hai trình phân tích cú pháp LR (0) và SLR (1) đều là trình phân tích cú pháp từ dưới lên, định hướng, dự đoán . Điều này có nghĩa rằng

  • Bộ phân tích cú pháp cố gắng áp dụng sản phẩm ngược lại để giảm câu đầu vào trở lại biểu tượng bắt đầu ( từ dưới lên )
  • Bộ phân tích cú pháp quét đầu vào từ trái sang phải ( hướng )
  • Bộ phân tích cú pháp cố gắng dự đoán những cắt giảm nào sẽ áp dụng mà không nhất thiết phải nhìn thấy tất cả đầu vào ( dự đoán )

Cả LR (0) và SLR (1) đều là trình phân tích cú pháp dịch chuyển / giảm , có nghĩa là chúng xử lý các mã thông báo của luồng đầu vào bằng cách đặt chúng trên một ngăn xếp và tại mỗi điểm hoặc dịch chuyển mã thông báo bằng cách đẩy nó lên ngăn xếp hoặc giảm bớt một số trình tự của các thiết bị đầu cuối và danh nghĩa trên đỉnh ngăn xếp trở lại một số ký hiệu danh nghĩa. Có thể chỉ ra rằng bất kỳ ngữ pháp nào cũng có thể được phân tích cú pháp từ dưới lên bằng trình phân tích cú pháp shift / Reduce, nhưng trình phân tích cú pháp đó có thể không xác định . Có nghĩa là, trình phân tích cú pháp có thể phải "đoán" xem nên áp dụng sự thay đổi hoặc giảm bớt, và cuối cùng có thể phải quay lại để nhận ra rằng nó đã lựa chọn sai. Cho dù bạn xây dựng trình phân tích cú pháp chuyển / giảm xác định mạnh đến mức nào, nó sẽ không bao giờ có thể phân tích cú pháp tất cả các ngữ pháp.

Khi một trình phân tích cú pháp shift / Reduce xác định được sử dụng để phân tích cú pháp ngữ pháp mà nó không thể xử lý, nó dẫn đến chuyển đổi / giảm xung đột hoặc giảm / giảm xung đột , trong đó trình phân tích cú pháp có thể đi vào trạng thái mà nó không thể cho biết hành động cần thực hiện. Trong xung đột shift / giảm, nó không thể biết liệu nó có nên thêm một ký hiệu khác vào ngăn xếp hay thực hiện một số giảm bớt các biểu tượng trên cùng của ngăn xếp. Trong xung đột giảm / giảm, trình phân tích cú pháp biết rằng nó cần phải thay thế các ký hiệu trên cùng của ngăn xếp bằng một số ký hiệu nhỏ nhất, nhưng nó không thể cho biết mức giảm nào sẽ sử dụng.

Tôi xin lỗi nếu đây là một giải thích dài dòng, nhưng chúng tôi cần điều này để có thể giải quyết sự khác biệt giữa phân tích cú pháp LR (0) và SLR (1). Trình phân tích cú pháp LR (0) là trình phân tích cú pháp shift / giảm sử dụng không mã thông báo tìm kiếm để xác định hành động cần thực hiện (do đó là 0). Điều này có nghĩa là trong bất kỳ cấu hình nào của trình phân tích cú pháp, trình phân tích cú pháp phải có một hành động rõ ràng để lựa chọn - nó thay đổi một ký hiệu cụ thể hoặc áp dụng một mức giảm cụ thể. Nếu có hai hoặc nhiều lựa chọn phải thực hiện, trình phân tích cú pháp không thành công và chúng tôi nói rằng ngữ pháp không phải là LR (0).

Nhớ lại rằng hai xung đột LR có thể xảy ra là thay đổi / giảm và giảm / giảm. Trong cả hai trường hợp này, có ít nhất hai hành động mà Automaton LR (0) có thể thực hiện và nó không thể cho biết chúng sẽ được sử dụng. Vì ít nhất một trong những hành động xung đột là giảm, một đường tấn công hợp lý sẽ là cố gắng để trình phân tích cú pháp cẩn thận hơn khi nó thực hiện một giảm cụ thể. Cụ thể hơn, giả sử rằng trình phân tích cú pháp được phép xem xét mã thông báo đầu vào tiếp theo để xác định xem nó nên thay đổi hay giảm bớt. Nếu chúng tôi chỉ cho phép trình phân tích cú pháp giảm khi nó "hợp lý" để làm như vậy (đối với một số định nghĩa về "có ý nghĩa"), thì chúng tôi có thể loại bỏ xung đột bằng cách để bộ tự động chọn cụ thể thay đổi hoặc giảm trong một bước cụ thể.

Trong SLR (1) ("LR đơn giản (1)"), trình phân tích cú pháp được phép xem xét một mã thông báo của lookahead khi quyết định xem nó nên thay đổi hay giảm bớt. Đặc biệt, khi trình phân tích cú pháp muốn thử giảm một thứ gì đó có dạng A → w (đối với chuỗi A và chuỗi w), nó sẽ xem xét mã thông báo đầu vào tiếp theo. Nếu mã thông báo đó có thể xuất hiện hợp pháp sau chữ A danh nghĩa trong một số dẫn xuất, trình phân tích cú pháp sẽ giảm. Nếu không, nó không. Trực giác ở đây là trong một số trường hợp, không có ý nghĩa gì khi cố gắng giảm, bởi vì với các mã thông báo mà chúng tôi đã thấy cho đến nay và mã thông báo sắp tới, không có cách nào có thể là giảm chính xác.

Sự khác biệt duy nhất giữa LR (0) và SLR (1) là khả năng bổ sung này giúp quyết định hành động cần thực hiện khi có xung đột. Do đó, bất kỳ ngữ pháp nào có thể được phân tích bằng trình phân tích cú pháp LR (0) đều có thể được phân tích bởi trình phân tích cú pháp SLR (1). Tuy nhiên, trình phân tích cú pháp SLR (1) có thể phân tích cú pháp số lượng ngữ pháp lớn hơn LR (0).

Tuy nhiên, trên thực tế, SLR (1) vẫn là một phương pháp phân tích cú pháp khá yếu. Thông thường hơn, bạn sẽ thấy bộ phân tích cú pháp LALR (1) ("Lookahead LR (1)") đang được sử dụng. Chúng cũng hoạt động bằng cách cố gắng giải quyết xung đột trong trình phân tích cú pháp LR (0), nhưng các quy tắc mà chúng sử dụng để giải quyết xung đột chính xác hơn nhiều so với các quy tắc được sử dụng trong SLR (1) và do đó, số lượng ngữ pháp lớn hơn nhiều là LALR (1) hơn là SLR (1). Cụ thể hơn một chút, trình phân tích cú pháp SLR (1) cố gắng giải quyết xung đột bằng cách xem cấu trúc của ngữ pháp để tìm hiểu thêm thông tin về thời điểm cần thay đổi và thời điểm giảm bớt. Bộ phân tích cú pháp LALR (1) xem xét cả ngữ pháp và bộ phân tích cú pháp LR (0) để có thêm thông tin cụ thể hơn về thời điểm thay đổi và khi nào cần giảm. Bởi vì LALR (1) có thể xem xét cấu trúc của bộ phân tích cú pháp LR (0), nó có thể xác định chính xác hơn khi có một số xung đột nhất định là giả.yaccbisontheo mặc định, tạo bộ phân tích cú pháp LALR (1).

Trong lịch sử, trình phân tích cú pháp LALR (1) thường được xây dựng thông qua một phương pháp khác dựa trên trình phân tích cú pháp LR (1) mạnh mẽ hơn nhiều, vì vậy bạn sẽ thường thấy LALR (1) được mô tả theo cách đó. Để hiểu điều này, chúng ta cần nói về trình phân tích cú pháp LR (1). Trong trình phân tích cú pháp LR (0), trình phân tích cú pháp hoạt động bằng cách theo dõi vị trí của nó trong quá trình sản xuất. Một khi nhận thấy rằng nó đã kết thúc quá trình sản xuất, nó sẽ cố gắng giảm bớt. Tuy nhiên, trình phân tích cú pháp có thể không thể biết liệu nó đang ở cuối sản xuất này và giữa sản xuất khác, điều này dẫn đến sự thay đổi / giảm xung đột, hoặc sản phẩm nào trong hai sản phẩm khác nhau mà nó đã đi đến cuối (giảm / giảm xung đột). Trong LR (0), điều này ngay lập tức dẫn đến xung đột và trình phân tích cú pháp không thành công. Trong SLR (1) hoặc LALR (1),

Trong trình phân tích cú pháp LR (1), trình phân tích cú pháp theo dõi thông tin bổ sung khi nó hoạt động. Ngoài việc theo dõi quá trình sản xuất mà trình phân tích cú pháp tin rằng đang được sử dụng, nó còn theo dõi những mã thông báo có thể xuất hiện sau khi quá trình sản xuất đó hoàn thành. Bởi vì trình phân tích cú pháp theo dõi thông tin này ở mỗi bước và không chỉ khi nó cần đưa ra quyết định, trình phân tích cú pháp LR (1) về cơ bản mạnh mẽ và chính xác hơn bất kỳ LR (0), SLR (1) hoặc Bộ phân tích cú pháp LALR (1) mà chúng ta đã nói đến cho đến nay. LR (1) là một kỹ thuật phân tích cú pháp cực kỳ mạnh mẽ và nó có thể được hiển thị bằng cách sử dụng một số phép toán khó mà bất kỳ ngôn ngữ nào có thể được phân tích cú pháp một cách xác định bằng bất kỳ trình phân tích cú pháp shift / giảm nào đều có một số ngữ pháp có thể được phân tích cú pháp bằng một tự động LR (1). (Lưu ý rằng điều này không có nghĩa là tất cả các ngữ phápcó thể được phân tích cú pháp một cách xác định là LR (1); điều này chỉ nói rằng một ngôn ngữ có thể được phân tích cú pháp một cách xác định có một số ngữ pháp LR (1)). Tuy nhiên, sức mạnh này phải có giá và trình phân tích cú pháp LR (1) được tạo ra có thể yêu cầu quá nhiều thông tin để hoạt động đến mức nó không thể được sử dụng trong thực tế. Ví dụ, một trình phân tích cú pháp LR (1) cho một ngôn ngữ lập trình thực, có thể yêu cầu hàng chục đến hàng trăm MB thông tin bổ sung để hoạt động chính xác. Vì lý do này, LR (1) thường không được sử dụng trong thực tế và các trình phân tích cú pháp yếu hơn như LALR (1) hoặc SLR (1) được sử dụng thay thế.

Gần đây, một thuật toán phân tích cú pháp mới được gọi là GLR (0) ("LR tổng quát (0)") đã trở nên phổ biến. Thay vì cố gắng giải quyết các xung đột xuất hiện trong trình phân tích cú pháp LR (0), trình phân tích cú pháp GLR (0) hoạt động bằng cách thử song song tất cả các tùy chọn có thể. Sử dụng một số thủ thuật thông minh, điều này có thể được thực hiện để chạy rất hiệu quả cho nhiều ngữ pháp. Hơn nữa, GLR (0) có thể phân tích cú pháp bất kỳ ngữ pháp không có ngữ cảnh nào , ngay cả những ngữ pháp không thể được phân tích bằng trình phân tích cú pháp LR (k) cho bất kỳ k nào. Các trình phân tích cú pháp khác cũng có khả năng làm điều này (ví dụ: trình phân tích cú pháp Earley hoặc trình phân tích cú pháp CYK), mặc dù GLR (0) có xu hướng nhanh hơn trong thực tế.

Nếu bạn muốn tìm hiểu thêm, trong mùa hè này, tôi đã dạy một khóa học giới thiệu về trình biên dịch và chỉ dành dưới hai tuần để nói về các kỹ thuật phân tích cú pháp. Nếu bạn muốn được giới thiệu chặt chẽ hơn về LR (0), SLR (1) và một loạt các kỹ thuật phân tích cú pháp mạnh mẽ khác, bạn có thể thích các trang trình bày bài giảng và bài tập về nhà của tôi về phân tích cú pháp. Tất cả các tài liệu của khóa học có sẵn ở đây trên trang cá nhân của tôi .

Hi vọng điêu nay co ich!


23
Đây là một câu trả lời xuất sắc. Trả lời chính xác câu hỏi một cách rất rõ ràng và giáo dục. Một trong những câu trả lời hay nhất mà tôi đã gặp trên SO.
NealB

2
@templatetypedef: Tôi nghĩ bạn nên giải thích một chút về sự khác biệt giữa L (AL) R (1) và SLR (1), đó là lý do SLR (1) tồn tại như một sự lựa chọn thú vị. Nhưng +1.
Ira Baxter

@Ira Baxter- Tôi vừa cập nhật cuộc thảo luận để nói thêm một chút về LALR (1) và LR (1). Bạn có thể xem qua điều này và cho tôi biết nếu bạn nghĩ tôi nên thêm điều gì không?
templatetypedef,

1
Bộ phân tích cú pháp @newbie LR (0) có bảng ACTION, nhưng hành động hoàn toàn phụ thuộc vào trạng thái, không phải trạng thái cộng với mã thông báo tiếp theo.
templatetypedef

1
@newbie Mặt hàng bạn đưa ra ở trên là mặt hàng giảm giá. Mục nhập ACTION cho trạng thái này sẽ giảm.
templatetypedef

1

Đây là những gì tôi đã học được. Thông thường trình phân tích cú pháp LR (0) có thể có sự không rõ ràng, tức là một hộp của bảng (bạn lấy ra để tạo trình phân tích cú pháp) có thể có nhiều giá trị (hoặc) để nói tốt hơn: trình phân tích cú pháp dẫn đến hai trạng thái cuối cùng với cùng một đầu vào. Vì vậy, trình phân tích cú pháp SLR được tạo ra để loại bỏ sự mơ hồ này. Inorder để xây dựng nó sẽ tìm tất cả các quá trình sản xuất dẫn đến trạng thái goto, tìm phần theo dõi cho biểu tượng sản xuất ở phía bên trái và chỉ bao gồm các trạng thái goto có trong phần sau. Inturn này có nghĩa là bạn không bao gồm sản xuất không thể sử dụng máy cắt gốc (có nghĩa là trạng thái đó không có trong tập hợp sau)

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.