How to parse arbitrary lists using Haskell parsers?

Is it possible to use one of the parsing libraries (for example Parsec) to parse something other than String? And how would I do that?

For simplicity, suppose the input is a list of ints [Int]. Task may be

  • falling leading zeros
  • analyze the rest in the template (S+L+)*, where Sis a number less than 10, and Lis a number greater than or equal to ten.
  • returns a list of tuples (Int,Int)where fstis the product Sand sndis the product of integersL

It would be great if someone could show how to write such a parser (or something like that).

+4
source share
2 answers

Yes, as user5402 points out, it Parseccan parse any instance Stream, including arbitrary lists. Since there are no predefined parsers-parsers (as for text), you need to collapse your own ( myTokenbelow), using, for example, tokenPrim

The only thing that seems a little inconvenient to me is the processing of the "initial positions". SourcePosis an abstract type (and not a type class) and forces me to use its "filename / line / column" format, which is a bit unnatural here.

Anyway, here is the code (without missing leading zeros, for brevity)

import Text.Parsec

myToken ::  (Show a) => (a -> Bool) -> Parsec [a] () a
myToken test = tokenPrim show incPos $ justIf test where
  incPos pos _ _ = incSourceColumn pos 1
  justIf test x = if (test x) then Just x else Nothing

small = myToken  (< 10)
large = myToken  (>= 10)

smallLargePattern = do
  smallints <- many1 small
  largeints <- many1 large
  let prod = foldl1 (*)
  return (prod smallints, prod largeints)

myIntListParser :: Parsec [Int] () [(Int,Int)]
myIntListParser = many smallLargePattern

testMe :: [Int] -> [(Int, Int)]
testMe xs = case parse myIntListParser "your list" xs of
  Left err -> error $ show err
  Right result -> result

I tried everything:

*Main> testMe [1,2,55,33,3,5,99]
[(2,1815),(15,99)]
*Main> testMe [1,2,55,33,3,5,99,1]
*** Exception: "your list" (line 1, column 9):
unexpected end of input

Note the inconvenient row / column format in the error message

, sanitiseSourcePos :: SourcePos -> MyListPosition

+6

, Parsec [a] , - , .

, , - Haskell .

, Haskell/ edx.org (), 7 - . :

"... . , . ..."

+3

All Articles