Tất cả các trình phân tích cú pháp SLR, LALR và LR đều có thể được thực hiện bằng cách sử dụng chính xác cùng một máy điều khiển bảng.
Về cơ bản, thuật toán phân tích cú pháp thu thập mã thông báo đầu vào tiếp theo T và tham khảo trạng thái hiện tại S (và các bảng tìm kiếm, GOTO và rút gọn được liên kết) để quyết định phải làm gì:
- SHIFT: Nếu bảng hiện tại cho biết SHIFT trên mã thông báo T, cặp (S, T) được đẩy vào ngăn xếp phân tích cú pháp, trạng thái được thay đổi theo những gì bảng GOTO cho biết đối với mã thông báo hiện tại (ví dụ: GOTO (T) ), một mã thông báo đầu vào khác T 'được tìm nạp và quá trình lặp lại
- GIẢM: Mỗi tiểu bang đều có 0, 1 hoặc nhiều mức giảm có thể xảy ra trong tiểu bang. Nếu trình phân tích cú pháp là LR hoặc LALR, mã thông báo sẽ được kiểm tra dựa trên bộ lookahead cho tất cả các lần giảm hợp lệ cho trạng thái. Nếu mã thông báo khớp với bộ lookahead để giảm quy tắc ngữ pháp G = R1 R2 .. Rn, giảm và dịch chuyển ngăn xếp xảy ra: hành động ngữ nghĩa cho G được gọi, ngăn xếp được bật n (từ Rn) lần, cặp ( S, G) được đẩy lên ngăn xếp, trạng thái mới S 'được đặt thành GOTO (G) và chu kỳ lặp lại với cùng một mã thông báo T. Nếu trình phân tích cú pháp là trình phân tích SLR, có nhiều nhất một quy tắc giảm cho và do đó, hành động giảm có thể được thực hiện một cách mù quáng mà không cần tìm kiếm để xem mức giảm nào được áp dụng. Nó rất hữu ích cho một phân tích cú pháp SLR để biết nếu có làgiảm hay không; điều này thật dễ dàng để biết nếu mỗi trạng thái ghi lại rõ ràng số lần giảm liên quan đến nó và số lượng đó vẫn cần thiết cho các phiên bản L (AL) R trong thực tế.
- LỖI: Nếu cả SHIFT và REDUCE đều không thể thực hiện được, lỗi cú pháp được khai báo.
Vì vậy, nếu tất cả họ đều sử dụng cùng một máy móc, thì vấn đề là gì?
Giá trị được đề xuất trong SLR là sự đơn giản trong việc thực hiện; bạn không phải quét qua các bộ lookahead kiểm tra giảm thiểu có thể có vì chỉ có nhiều nhất một bộ và đây là hành động khả thi duy nhất nếu không có SHIFT thoát khỏi trạng thái. Mức giảm nào áp dụng có thể được đính kèm cụ thể vào tiểu bang, vì vậy máy móc phân tích cú pháp SLR không cần phải tìm kiếm nó. Trong thực tế, trình phân tích cú pháp L (AL) R xử lý một tập hợp các ngôn ngữ lớn hơn một cách hữu ích và quá ít công việc để triển khai nên không ai triển khai SLR ngoại trừ như một bài tập học thuật.
Sự khác biệt giữa LALR và LR liên quan đến trình tạo bảng. Trình tạo phân tích cú pháp LR theo dõi tất cả các mức giảm có thể xảy ra từ các trạng thái cụ thể và bộ tìm kiếm chính xác của chúng; bạn kết thúc với các trạng thái trong đó mỗi lần giảm được liên kết với bộ tiêu đề chính xác từ ngữ cảnh bên trái của nó. Điều này có xu hướng xây dựng các tập hợp trạng thái khá lớn. Trình tạo phân tích cú pháp LALR sẵn sàng kết hợp các trạng thái nếu bảng GOTO và bộ tìm kiếm để giảm thiểu tương thích và không xung đột; điều này tạo ra số lượng trạng thái nhỏ hơn đáng kể, với cái giá là không thể phân biệt các chuỗi ký hiệu nhất định mà LR có thể phân biệt. Vì vậy, trình phân tích cú pháp LR có thể phân tích cú pháp một nhóm ngôn ngữ lớn hơn trình phân tích cú pháp LALR, nhưng có bảng phân tích cú pháp lớn hơn rất nhiều. Trong thực tế, người ta có thể tìm thấy ngữ pháp LALR đủ gần với ngôn ngữ đích mà kích thước của máy trạng thái đáng để tối ưu hóa;
Vì vậy: Cả ba đều sử dụng máy móc như nhau. SLR là "dễ dàng" theo nghĩa là bạn có thể bỏ qua một chút nhỏ của máy móc nhưng nó không đáng để gặp rắc rối. LR phân tích cú pháp một tập hợp các ngôn ngữ rộng hơn nhưng các bảng trạng thái có xu hướng khá lớn. Điều đó khiến LALR là lựa chọn thiết thực.
Đã nói tất cả những điều này, cần biết rằng trình phân tích cú pháp GLR có thể phân tích cú pháp bất kỳ ngôn ngữ không có ngữ cảnh nào, sử dụng máy móc phức tạp hơn nhưng chính xác là các bảng (bao gồm cả phiên bản nhỏ hơn được sử dụng bởi LALR). Điều này có nghĩa là GLR mạnh hơn LR, LALR và SLR; khá nhiều nếu bạn có thể viết một ngữ pháp BNF chuẩn, GLR sẽ phân tích cú pháp theo nó. Sự khác biệt trong máy móc là GLR sẵn sàng thử nhiều phân tích cú pháp khi có xung đột giữa bảng GOTO và hoặc các bộ lookahead. (Cách GLR thực hiện điều này một cách hiệu quả là tuyệt đối thiên tài [không phải của tôi] nhưng sẽ không phù hợp trong bài đăng SO này).
Điều đó đối với tôi là một sự thật vô cùng hữu ích. Tôi xây dựng chương trình phân tích và máy biến áp mã và phân tích cú pháp là cần thiết nhưng "không thú vị"; công việc thú vị là những gì bạn làm với kết quả được phân tích cú pháp và do đó, trọng tâm là thực hiện công việc sau phân tích cú pháp. Sử dụng GLR có nghĩa là tôi có thể tương đối dễ dàng xây dựng ngữ pháp làm việc, so với việc hack ngữ pháp để chuyển sang dạng có thể sử dụng LALR. Điều này rất quan trọng khi cố gắng xử lý các ngôn ngữ không mang tính học thuật như C ++ hoặc Fortran, nơi bạn thực sự cần hàng nghìn quy tắc để xử lý tốt toàn bộ ngôn ngữ và bạn không muốn dành cả đời để cố gắng hack các quy tắc ngữ pháp để đáp ứng các hạn chế của LALR (hoặc thậm chí LR).
Như một loại ví dụ nổi tiếng, C ++ được coi là cực kỳ khó phân tích cú pháp ... bởi những người làm công việc phân tích cú pháp LALR. C ++ dễ dàng phân tích cú pháp bằng cách sử dụng máy móc GLR sử dụng khá nhiều quy tắc được cung cấp ở phía sau của sổ tay tham chiếu C ++. (Tôi chính xác là một trình phân tích cú pháp như vậy và nó xử lý không chỉ vani C ++ mà còn xử lý nhiều phương ngữ khác nhau của nhà cung cấp. Điều này chỉ có thể thực hiện được trong thực tế vì chúng tôi đang sử dụng trình phân tích cú pháp GLR, IMHO).
[CHỈNH SỬA Tháng 11 năm 2011: Chúng tôi đã mở rộng trình phân tích cú pháp của mình để xử lý tất cả C ++ 11. GLR đã làm điều đó dễ dàng hơn rất nhiều. CHỈNH SỬA tháng 8 năm 2014: Hiện đang xử lý tất cả C ++ 17. Không có gì bị hỏng hoặc trở nên tồi tệ hơn, GLR vẫn là tiếng meo meo của con mèo.]