Parsec: No newline after last line and 'many'
Iavor Diatchki
diatchki@cse.ogi.edu
Sun, 7 Apr 2002 12:13:34 -0700
hello,
does this work?
> pLine = many (noneOf "\n")
> pLines = pLine `sepEndBy` char '\n'
bye
iavor
On Sun, Apr 07, 2002 at 07:44:42PM +0200, Till Doerges wrote:
> Hi folks,
>
> when trying to write a parser for unix-style textfiles, I stumbled
> across the problem having to distinguish between lines w/ a newline
> character at the end and lines w/o a newline at the end (i.e. the last
> line in a file doesn't have to have it).
>
> Eventually I want to be able to use my parser 'linep' with 'many' on
> no matter which text-files.
>
> The first version I tried, was
>
> --- snip ---
> skip1 :: Parser()
> skip1 = do
> anyChar
> return()
>
> linep :: Parser(String)
> linep = do { cs <- many (noneOf "\n")
> ; skip1
> ; return cs
> }
> --- snap ---
>
> Well, this only works, if the last line in the file is also terminated
> by '\n'. So, I tried to be smarter using:
>
> --- snip ---
> lineWith :: Parser(String)
> lineWith = try (do { cs <- many (noneOf "\n")
> ; skip1
> ; return cs
> })
>
> lineWithOut :: Parser(String)
> lineWithOut = many anyChar
>
> linep :: Parser(String)
> linep = lineWith
> <|> lineWithOut
> <?> "line"
> --- snap ---
>
> But this doesn't do the trick either, instead it'll overflow my stack
> if used in conjunction w/ 'many':
>
> --- snip ---
> parse (do {many linep}) "stdin" (unlines ["hallo","ballo"])
> ^CInterrupted.
> ReadOrig> parse (do {many linep}) "stdin" ("hallo\nballo")
> ^CInterrupted.
> --- snap ---
>
> Avoiding many OTOH works fine:
> --- snip ---
> parse (do {linep;linep}) "stdin" (unlines ["hallo","ballo"])
> Right "ballo"
> ReadOrig> parse (do {linep;linep}) "stdin" ("hallo\nballo")
> Right "ballo"
> --- snap ---
>
> Besides these two attempts explicitly spelled out I've made quite a
> few others, but none of them did the trick.
>
> The documentation for 'try' says that it'll only consume input upon
> success, but why doesn't it work w/ 'many'?
>
> I know about the Prelude-functions unlines, lines etc., but they don't
> really help, since linep should be used within another parser of mine.
>
> I am using Parsec as of Jan 25, 2001 (the version included w/ ghc 5.02).
>
> Any hints/solutions/... would be greatly appreciated!
>
> Bye -- Till
> _______________________________________________
> Haskell mailing list
> Haskell@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell
--
---------------------------------------+----------------------------------------
Iavor S. Diatchki | email: diatchki@cse.ogi.edu
Dept. of Computer Science | web: http://www.cse.ogi.edu/~diatchki
OGI School of Science and Engineering | work phone: 5037481631
OHSU | home phone: 5036434085
---------------------------------------+----------------------------------------