2013-09-23 10 views
5

これが可能かどうかはわかりませんが、Parsecを使用してファイルの文字列を検索しようとしています。サンプルファイル: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 

そして、ここではそれが働いて得ることで私の試みです:

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") 

私はcareAboutを探して検索を強制し、それが動作しない場合は、食べブルートしようとしています1文字を入力してもう一度お試しください。私は真ん中のすべての迷惑メールを解析することができますが、私はそれが何であるか気にしません(なぜそれを解析するのがなぜか)、それは潜在的に複雑です。

問題は、私の解決策がうまくいかないことです。 anyCharはすべてを消費してしまい、ENDの検索では決してチャンスがありません。また、careAboutのどこかで、eofに達し、そのためにExceptionが投げられます。

これはおそらく間違ったやり方であり、の方法、またはそれより優れた方法であることを知りたいと思います。

答えて

1

parensパーサーではない場合は、regex-applicativeのような通常の言語パーサーに適しています。これは、通常の言語パーサは「バックトラック」についてよりスマートになっているからです(実際にはバックトラックがまったく起こっていませんが、可能なすべてのブランチが探究されています)。

しかし、おわかりのように、一致するかっこは通常の言語ではありません。正規表現になるために文法を緩めることができれば、regex-applicativeを試してみてください。

関連する問題