Created
June 26, 2015 00:26
-
-
Save deech/28734a84cb4b3fdc0714 to your computer and use it in GitHub Desktop.
Non Greedy Parsing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Control.Monad | |
import Text.Parsec | |
testString = unlines [ | |
"foo {", | |
" contents of foo", | |
" a stray }", | |
"}", | |
"bar {", | |
"}" | |
] | |
naiveP = many $ do | |
name <- many alphaNum | |
space | |
char '{' | |
body <- many anyChar | |
char '}' | |
return (name,body) | |
naiveTest = parseTest naiveP testString | |
untilP keepGoing stop = go [] | |
where | |
go accum = | |
(try $ do | |
e <- stop | |
return (accum, e) | |
) | |
<|> | |
(do | |
u <- keepGoing | |
go (accum ++ [u])) | |
backtrackingP = do | |
name <- many alphaNum | |
space | |
char '{' | |
(body, rest) <- untilP anyChar $ do | |
char '}' | |
endOfLine | |
(<|>) (try backtrackingP) | |
(try $ do | |
eof | |
return []) | |
return $ [(name, body)] ++ rest | |
backtrackingTest = parseTest backtrackingP testString | |
{- | |
*Main> naiveTest | |
parse error at (line 7, column 1): | |
unexpected end of input | |
expecting "}" | |
*Main> backtrackingTest | |
[("foo","\n contents of foo\n a stray }\n"),("bar","\n")] | |
-} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The tricky part is to permit ending character inside the block. We could use the info from
lookAhead
to mimic greedy parsing. Hope I get it right.