Cây cú pháp trừu tượng có thể được bỏ qua trong thời gian phụ?


7

Mô tả vấn đề trừu tượng

Theo cách tôi nhìn thấy, unparsing có nghĩa là tạo ra một luồng mã thông báo từ AST, khi được phân tích lại sẽ tạo ra một AST bằng nhau, tức là parse(unparse(AST)) = ASTnên giữ.

Điều này tương đương với việc tìm một cây phân tích hợp lệ sẽ tạo ra cùng một AST.

Ngôn ngữ được mô tả bằng ngữ pháp do S tự do ngữ cảnh sử dụng biến thể eBNF.

Vì vậy, unparser phải tìm một 'đường dẫn' hợp lệ thông qua các nút được duyệt qua trong đó tất cả các ràng buộc ngữ pháp. Điều này về cơ bản có nghĩa là tìm sự phân bổ hợp lệ các nút AST cho các quy tắc sản xuất ngữ pháp. Đây là một vấn đề thỏa mãn ràng buộc (CSP) nói chung và có thể được giải quyết, như phân tích cú pháp, bằng cách quay lại trongÔi(en).

May mắn cho phân tích cú pháp, điều này có thể được thực hiện trong Ôi(n3)sử dụng GLR (hoặc tốt hơn là hạn chế ngữ pháp). Vì cấu trúc AST rất gần với cấu trúc quy tắc sản xuất ngữ pháp, tôi thực sự ngạc nhiên khi thấy một triển khai trong đó thời gian chạy tệ hơn phân tích cú pháp: Xtext sử dụng ANTLR để phân tích cú pháp và quay lui để bỏ mã.

Câu hỏi

  1. Là một ngữ pháp thuộc tính S miễn phí ngữ cảnh tất cả mọi thứ mà một trình phân tích cú pháp và trình duyệt không cần chia sẻ hoặc có các ràng buộc nào nữa, ví dụ về việc thực hiện phân tích cú pháp / trình phân tích cú pháp?
  2. Tôi có cảm giác vấn đề này không phải là Ôi(en) nói chung - một số thiên tài có thể giúp tôi với điều này?

Tôi đã không nhận được câu trả lời cho câu hỏi này trên StackOverflow . Nó được đề nghị để hỏi ở đây, nhưng tôi ghét sự dư thừa, vì vậy tôi hy vọng bạn tha thứ cho tôi vì đã yêu cầu bạn trả lời ở đây .


2
Chào mừng bạn Vui mừng bạn quyết định mang câu hỏi của bạn ở đây. Lưu ý rằng quy trình thích hợp sẽ là gắn cờ cho câu hỏi khác để di chuyển ở đây. Chúng ta có thể hợp nhất chúng sau đó. Bạn có thể liên kết các tài khoản của mình để bạn có thể theo dõi các bài đăng của mình tại đây ngay cả khi bạn lướt Stack Overflow .
Raphael

Câu trả lời:


3

Có một phiên bản câu hỏi của bạn mà việc giải mã dễ dàng và có thể được thực hiện trong thời gian tuyến tính. Tuy nhiên, tôi không hoàn toàn chắc chắn nếu câu hỏi của bạn liên quan đến phiên bản cụ thể này, vì vậy tôi sẽ xem xét điều đó trước.

Bạn nói trong câu hỏi của bạn tại StackOverflow rằng AST của bạn trông giống như "AnyObject -> AnyObject -> Xe [name =" Xe "]". Câu hỏi của bạn sẽ dễ dàng hơn rất nhiều nếu AST của bạn trông giống như "Khu vực -> Đường cao tốc -> Xe hơi", nghĩa là chúng tôi biết sản phẩm nào đã được thực hiện khi AST của bạn được xây dựng / phân tích cú pháp. Trong các trình phân tích cú pháp không ngữ cảnh thông thường, bạn (hầu như) luôn nhận được thông tin này: bạn có thể quyết định vứt nó đi, nhưng (gần như) tất cả các thuật toán phân tích cú pháp cũng có thể cung cấp cho bạn thông tin này.

Nếu bạn không có thông tin này, tôi khá chắc chắn thời gian theo cấp số nhân là tốt nhất bạn có thể làm, trừ khi bạn biết điều gì đó về biểu thức S của bạn. Vấn đề sau đó chỉ đơn giản là phục hồi AST "Khu vực -> Đường cao tốc -> Xe hơi", việc giải quyết sau đó là phần dễ dàng.

Nếu bạn có thông tin này, thì chúng ta chỉ cần nhìn vào ngữ pháp không ngữ cảnh và cố gắng phân tách chúng. Hãy xem xét ngữ pháp này:

1: Smột
2: SmộtSmột

Một AST cho ngữ pháp này có thể trông giống như Smột(Smột)một, trên đầu vào "aaa". Unparsing AST này rất dễ dàng: thực hiện một bước đi theo thứ tự của cây và xuất ra tất cả các thiết bị đầu cuối được tìm thấy trong bước đi này. Kết quả là "aaa" một lần nữa.

Mọi thứ trở nên phức tạp hơn một chút khi bạn nhìn vào ngữ pháp không ngữ cảnh mơ hồ. Một mặt, mọi thứ vẫn dễ dàng: bạn chỉ cần chọn bất kỳ cây phân tích cú pháp nào của bạn và làm như trên: bạn có thể xây dựng lại tất cả các cây phân tích khác từ kết quả.

Tuy nhiên, với sự có mặt của các quy tắc định hướng, bạn phải làm điều gì đó khéo léo. Cụ thể, đầu vào "(1 + 2) * 3" có thể không được xem là "1 + 2 * 3", khác với đầu vào. Có thể làm điều này trong thời gian tuyến tính trênLR(1) ngữ pháp (trong đó quyền ưu tiên và tính kết hợp được thi hành như trong Yacc) bằng cách thực hiện ngược lại LRphân tích tại thời điểm khác nhau. Tôi sẽ bỏ qua các chi tiết, vì đây không phải là một phần câu hỏi của bạn, nhưng nó có thể được thực hiện.

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.