
The tutorials I've found don't tell me what I want to know :-( I have lines that begin with an integer, then white-space, and then further structure to the end-of-line. So for a starter, could you show me how to write a parser for the integer (returning an Int), and how to combine it with a parser for the rest of the line (take that as written - it isn't, but I'll try to do that myself given such a kick-start). Thanks. -- Colin Adams Preston Lancashire

Colin Paul Adams wrote:
The tutorials I've found don't tell me what I want to know :-(
I have lines that begin with an integer, then white-space, and then further structure to the end-of-line.
So for a starter, could you show me how to write a parser for the integer (returning an Int), and how to combine it with a parser for the rest of the line (take that as written - it isn't, but I'll try to do that myself given such a kick-start).
Maybe one of my old blog posts can help? http://therning.org/magnus/archives/289 /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe Haskell is an even 'redder' pill than Lisp or Scheme. -- PaulPotts

Am Samstag, 21. Februar 2009 21:04 schrieb Colin Paul Adams:
The tutorials I've found don't tell me what I want to know :-(
I have lines that begin with an integer, then white-space, and then further structure to the end-of-line.
So for a starter, could you show me how to write a parser for the integer (returning an Int), and how to combine it with a parser for the rest of the line (take that as written - it isn't, but I'll try to do that myself given such a kick-start).
Thanks.
-- could also be Parser Int, if you don't need user-state parseInt :: GenParser Char st Int parseInt = do neg <- (char '-' >> return True) <|> (optional (char '+') >> return False) digs <- many1 digit let n | neg = negate $ read digs | otherwise = read digs return n parseLine :: GenParser Char st LineStructure parseLine = do -- spaces here, if there may be whitespace at the beginning of lines num <- parseInt spaces things <- parseRemainderOfLine return (combine num things) The strategy is always the same, you write parsers for small things and combine their results. Note that things are somewhat tricky if the structure you want to parse isn't very strict, if one of your possible parsers at some point in the parsing process can fail, but not immediately and you need to backtrack, you have to use the 'try' combinator as in combo = (try parser1) <|> parser2 , but try is bad for performance, so use it only where it's necessary. The latter part is notoriously difficult to identify for the inexperienced, so until you know parsec better, it's okay to insert a few 'try's more than necessary. HTH, otherwise ask again, Daniel

"Daniel" == Daniel Fischer
writes:
Thanks. In fact all I need is: parse_integer :: Parser Int parse_integer = do digits <- many1 digit let n = read digits return n as the format does not permit a sign. What I was missing was digits. Where does it come from? I can't find it with Hoggle. -- Colin Adams Preston Lancashire

On Sun, Feb 22, 2009 at 4:23 AM, Colin Paul Adams
parse_integer :: Parser Int parse_integer = do digits <- many1 digit let n = read digits return n
'digits' come from 'digits <- many1 digit', and 'digit' comes from Parsec itself[1] (and is the same as 'satisfy isDigit'[2,3]). I should note that it is more idiomatic to write 'parse_integer' as
import Control.Monad (liftM)
parse_integer :: Parse Int parse_integer = read `liftM` many1 digit
if you don't need signs. HTH, [1] http://hackage.haskell.org/packages/archive/parsec/3.0.0/doc/html/Text-Parse... [2] http://hackage.haskell.org/packages/archive/parsec/3.0.0/doc/html/src/Text-P... [3] http://hackage.haskell.org/packages/archive/base/4.0.0.0/doc/html/Data-Char.... -- Felipe.

"Felipe" == Felipe Lessa
writes:
Felipe> On Sun, Feb 22, 2009 at 4:23 AM, Colin Paul Adams
Felipe>

On Sun, Feb 22, 2009 at 4:50 AM, Colin Paul Adams
OK - I see it here, but I was looking in Text.ParserCombinators.Parsec.Char, where I can't see it (I can see satisfy). I can't see how I am supposed to make that apparently disconnected leap (other than by asking here, which works :-) )
It is there, too! =P http://hackage.haskell.org/packages/archive/parsec/3.0.0/doc/html/Text-Parse... -- Felipe.

"Felipe" == Felipe Lessa
writes:
Felipe> On Sun, Feb 22, 2009 at 4:50 AM, Colin Paul Adams
Felipe>

On Sun, Feb 22, 2009 at 5:02 AM, Colin Paul Adams
Hm.
It's not on my local copy of the GHC libraries documentation (ghc 6.10.1), although if I click the source button, I can see it.
My GHC 6.10.1 was compiled from source and Parsec comes from a different ebuild (Gentoo), and digit isn't documented as well. It must be some problem with parsec < 3, because Hackage has the same problem for old Parsec[1]. [1] http://hackage.haskell.org/packages/archive/parsec/2.1.0.1/doc/html/Text-Par... -- Felipe.

On Sun, Feb 22, 2009 at 2:14 AM, Felipe Lessa
My GHC 6.10.1 was compiled from source and Parsec comes from a different ebuild (Gentoo), and digit isn't documented as well. It must be some problem with parsec < 3, because Hackage has the same problem for old Parsec[1].
[1] http://hackage.haskell.org/packages/archive/parsec/2.1.0.1/doc/html/Text-Par...
From the sources:
upper, lower, alphaNum, letter, digit, hexDigit, octDigit :: CharParser st Char
I think I've seen Haddock have trouble documenting declarations which share a type signature in other places, as well. Antoine
participants (5)
-
Antoine Latter
-
Colin Paul Adams
-
Daniel Fischer
-
Felipe Lessa
-
Magnus Therning