2010-03-20 16 views
11

Tôi đã cân nhắc sử dụng thư viện phân tích cú pháp Parsec của Haskell để phân tích cú pháp một tập hợp con của Java như một trình phân tích cú pháp đệ quy như là một giải pháp thay thế cho các giải pháp trình tạo phân tích cú pháp truyền thống như Happy. Parsec có vẻ rất dễ sử dụng, và phân tích tốc độ chắc chắn không phải là một yếu tố đối với tôi. Tôi tự hỏi, mặc dù, nếu nó có thể thực hiện "sao lưu" với Parsec, một kỹ thuật mà tìm thấy sản xuất chính xác để sử dụng bằng cách cố gắng mỗi một lần lượt. Đối với một ví dụ đơn giản, hãy xem xét khởi đầu rất của ngữ pháp JLS Java:Thư viện Parsec của Haskell có thể được sử dụng để triển khai trình phân tích cú pháp gốc đệ quy với sao lưu không?

Literal: 
    IntegerLiteral 
    FloatingPointLiteral 

Tôi muốn một cách để không phải tìm ra làm thế nào tôi nên đặt hai quy tắc này để có được những phân tích cú pháp để thành công. Khi đứng, một thực hiện ngây thơ như thế này: ""

literal = do { 
    x <- try (do { v <- integer; return (IntLiteral v)}) <|> 
     (do { v <- float; return (FPLiteral v)}); 
    return(Literal x) 
} 

sẽ không hoạt động ... đầu vào như "15,2" sẽ gây ra các phân tích cú pháp số nguyên để thành công đầu tiên, và sau đó toàn bộ điều sẽ nghẹt thở trên ký hiệu. Trong trường hợp này, tất nhiên, rõ ràng là bạn có thể giải quyết vấn đề bằng cách sắp xếp lại hai sản phẩm. Tuy nhiên, trong trường hợp chung, việc tìm kiếm những thứ như thế này sẽ là một cơn ác mộng, và rất có khả năng tôi sẽ bỏ lỡ một số trường hợp. Lý tưởng nhất, tôi muốn một cách để có Parsec tìm ra những thứ như thế này cho tôi. Điều này có thể, hoặc tôi chỉ đơn giản là cố gắng làm quá nhiều với thư viện? Tài liệu Parsec tuyên bố rằng nó có thể "phân tích cú pháp ngữ cảnh vô cùng nhạy cảm, vô hạn ngữ cảnh", vì vậy có vẻ như tôi có thể làm điều gì đó ở đây.

Trả lời

2

Hoặc sử dụng Parsec của notFollowedBy để đảm bảo rằng tất cả mọi thứ integer tiêu thụ lên đến một số tách token (phương pháp này sẽ mở rộng để kịch bản tùy ý hầu hết thời gian), hoặc hãy xem combinators phân tích cú pháp mà khám phá tất cả lựa chọn thay thế phân tích cú pháp có thể. Đầu tiên cần lưu ý là thư viện UU_Parsing.

8

Một cách bạn có thể thực hiện việc này là sử dụng bộ phối hợp try, cho phép trình phân tích cú pháp tiêu thụ đầu vào và lỗi mà không làm hỏng toàn bộ phân tích cú pháp.

Cách khác là sử dụng Text.ParserCombinators.ReadP, thực hiện toán tử lựa chọn đối xứng, trong đó nó được chứng minh là a +++ b = b +++ a, vì vậy nó thực sự không quan trọng thứ tự nào. Tôi là một phần để ReadP, vì nó là tối thiểu nhưng cung cấp những gì bạn cần để xây dựng một phân tích cú pháp thực sự mạnh mẽ.

+2

Lưu ý rằng sau một chút kinh nghiệm, tôi ít bị mê hoặc hơn với 'ReadP'. Nó có một số hành vi theo cấp số nhân khó tìm đôi khi, và không thất bại tốt. 'Parsec' là lớn hơn và clunkier, nhưng, bây giờ tôi tìm thấy, phần mềm tốt hơn. – luqui

Các vấn đề liên quan