Search code examples
haskellparsec

Haskell: parsec key value pairs (key: value)


how would I parse a file containing keys and values using parsec into [[(String, String)]]?

key1: value 1 key2: value 2
key1: value 1 key2: value 2
key1: value 1 key2: value 2

the key is one word, the value can be more words.

I have tried

tag :: GenParser Char st Tag
tag = do
  name <- key
  value <- manyTill anyChar (try key)
  return (name, value)

key :: GenParser Char st String
key = do
  name <- many (noneOf ": ")
  char ':'
  return name

> parse (many tag) "" "key1: value 1 key2: value 2"
Right [("key1"," value 1 ")]

Solution

  • I have changed the tag function to test both newline and next key, and that works for me.

    tag :: GenParser Char st Tag
    tag = do
      name <- key
      value <- manyTill anyChar ((test newline) <|> (test key))
      return (name, strip value)
    
    test :: GenParser Char st a -> GenParser Char st ()
    test p = lookAhead $ try p >> return ()
    
    key :: GenParser Char st String
    key = do
      name <- many1 (noneOf ": \n\r")
      char ':'
      return name