[Haskell-beginners] Parsec Many Mishap

David McBride toad3k at gmail.com
Tue May 6 20:40:07 UTC 2014


First, when you post something like this, please put enough code to at
least compile.  I had to spend five minutes adding some code to make this
compile.

The reason it doesn't work is your manyTill anyChar nextCommand.  In this
case nextCommand actually slurps up the next hashtag, leaving you
positioned at " It was ...", then you try to match another command, and it
fails, and terminates.

The fix is simple, you just have to prevent it from eating the next tag you
intended to stop at, which you can do by changing it to manyTill anyChar
(lookAhead nextCommand)


On Tue, May 6, 2014 at 2:54 PM, Walter Askew <waltaskew at gmail.com> wrote:

> I am trying to use parsec to turn strings like this:
>
> “#newch The Period #txt It was the best of times #newpar #txt it was the
> worst of times”
>
> into data structures like this:
>
> [NewChapter “The Period”, Text "It was the best of times”, NewParagraph,
> Text "it was the worst of times”]
>
> My current attempt returns this, however:
>
> [NewChapter "The Period "]
>
> That is, my current implementation only parses out the first item in the
> string and does not find the remaining items.
> I’m not sure why that is.  I’d suspect I am misusing parsec’s “many” or
> “manyTill” somehow, but it isn’t clear to me why my use of “many" results
> in only single item lists.
>
> My code is pasted below — any suggestions?  This is my first exploration
> of parsec, so any general suggestion on using the library are welcome (for
> instance, I do note that I end up double-parsing the strings “#newch, #txt
> and #newpar because both nextCommand and the newChapter newText and newPar
> parsers all parse those same strings, but I’m not sure how to avoid that
> elegantly.)
>
> Thanks for your help!
>
>
> parser = many command
>
> command = newChapter <|> newTxt <|> newPar
>
> newChapter = do
>   try (string "#newch")
>   spaces
>   chapterName <- text
>   return (NewChapter chapterName)
>
> newTxt = do
>   try (string "#txt")
>   spaces
>   content <- text
>   return (Text content)
>
> newPar = do
>   try (string "#newpar")
>   spaces
>   return NewParagraph
>
> text = manyTill anyChar nextCommand
>
> nextCommand = try (string "#newch")
>               <|> try (string "#txt")
>               <|> try (string "#newpar")
>               <|> eof *> return ""
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20140506/4bc8f223/attachment.html>


More information about the Beginners mailing list