2013-09-23 36 views
5

Không chắc chắn nếu điều này là có thể (hoặc được khuyến nghị), nhưng về cơ bản tôi đang tìm kiếm chuỗi ký tự trong tệp bằng Parsec. Ví dụ file:Tìm kiếm mẫu bằng Parsec

START (name) 

junk 
morejunk=junk; 
dontcare 
    foo() 
    bar 

care_about this (stuff in here i dont care about); 

don't care about this 
or this 
foo = bar; 

also_care 
about_this 
(dont care whats in here); 
and_this too(only the names 
    at the front 
    do i care about 
); 

foobar 
may hit something = perhaps maybe (like this); 
foobar 

END 

Và đây là nỗ lực của tôi lúc nhận được nó làm việc:

careAbout :: Parser (String, String) 
careAbout = do 
    name1 <- many1 (noneOf " \n\r") 
    skipMany space 
    name2 <- many1 (noneOf " (\r\n") 
    skipMany space 
    skipMany1 parens 
    skipMany space 
    char ';' 
    return (name1, name2) 

parens :: Parser() 
parens = do 
    char '(' 
    many (parens <|> skipMany1 (noneOf "()")) 
    char ')' 
    return() 

parseFile = do 
    manyTill (do 
     try careAbout <|> 
     anyChar >> return ("", "")) (try $ string "END") 

Tôi đang cố gắng để brute force việc tìm kiếm bằng cách tìm kiếm careAbout, và nếu điều đó không làm việc, ăn một ký tự và thử lại. Tôi có thể phân tích tất cả các thư rác ở giữa (tôi biết nó có thể là gì), nhưng tôi không quan tâm nó là gì (vậy tại sao lại phân tích nó), và nó có khả năng phức tạp.

Vấn đề là giải pháp của tôi không hoạt động. anyChar kết thúc tiêu thụ mọi thứ và tìm kiếm END không bao giờ có cơ hội. Ngoài ra, ở đâu đó trong số careAbout, chúng tôi nhấn eof và một số Exception bị ném vì lý do đó.

Đây có lẽ là cách sai chính xác để thực hiện và tôi muốn biết cách cách hoặc thậm chí tốt hơn là Right Way ™.

Trả lời

1

Nếu không cho trình phân tích cú pháp parens, điều này sẽ phù hợp với trình phân tích ngôn ngữ thông thường, chẳng hạn như regex-applicative. Điều này là do các trình phân tích cú pháp ngôn ngữ thông thường có nhiều "thông minh" hơn về "backtracking" (trên thực tế không có backtracking nào cả, và mọi nhánh có thể được khám phá).

Tuy nhiên, như bạn có thể biết, dấu ngoặc đơn phù hợp không phải là ngôn ngữ thông thường. Nếu bạn có thể thư giãn ngữ pháp của mình để trở thành thường xuyên, hãy thử dùng regex.

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