How can I parse integers with unlimited length, no delimiters with attoparsec?

I am trying to parse two 3 character integers using attoparsec. An example input might look something like this:

341

      

... which I would like to analyze:

Constructor 34 1

      

I have two solutions that work, but which are somewhat clunky:

stdK :: P.Parser Packet
stdK = do
    P.char '1'
    qstr <- P.take 2
    let q = rExt $ P.parseOnly P.decimal qstr
    n <- P.decimal
    return $ Std q n

stdK2 :: P.Parser Packet
stdK2 = do
    P.char '1'
    qn <- P.decimal
    let q = div qn 10
    let n = rem qn 10
    return $ Std q n

      

There must be a better way to achieve something as simple as this. Did I miss something?

+3


source to share


1 answer


Your code snippet is not self-contained (in particular, imports and datatype are missing Packet

), but you seem to be too offensive.

First, define a parser for one-digit integers. Then use the latter as a building block for parsing for two-digit integers. After that, use applicative operators to combine the two parsers and define a parser for your custom data type Packet

. See below.

Note that you do not need the full power of the monads; there is enough additive parsing here.



-- test_attoparsec.hs

{-# LANGUAGE OverloadedStrings #-}

import Control.Applicative ((<$>))
import Data.Attoparsec.Text
import Data.Char

data Packet = Std {-# UNPACK #-} !Int
                  {-# UNPACK #-} !Int
  deriving (Show)

stdK :: Parser Packet
stdK = char '1' *> (Std <$> twoDigitInt <*> oneDigitInt)

twoDigitInt :: Parser Int
twoDigitInt = timesTenPlus <$> oneDigitInt <*> oneDigitInt
  where
    timesTenPlus x y = 10 * x + y

oneDigitInt :: Parser Int
oneDigitInt = digitToInt <$> digit

      

Tests at GHCi:

λ> :l test_attoparsec.hs
[1 of 1] Compiling Main             ( test_attoparsec.hs, interpreted )
Ok, modules loaded: Main.

λ> :set -XOverloadedStrings 

λ> parseOnly stdK "1341"
Right (Std 34 1)

λ> parseOnly stdK "212"
Left "1: Failed reading: satisfyWith"

      

+1


source







All Articles