将多行解析为Haskell中的列表列表

Jes*_*spc 3 parsing haskell parsec

我试图解析一个看起来像这样的文件:

a b c 
f e d
Run Code Online (Sandbox Code Playgroud)

我想匹配行中的每个符号,并将所有内容解析为列表列表,例如:

[[A, B, C], [D, E, F]]
Run Code Online (Sandbox Code Playgroud)

为此,我尝试了以下方法:

import           Control.Monad
import           Text.ParserCombinators.Parsec
import           Text.ParserCombinators.Parsec.Language
import qualified Text.ParserCombinators.Parsec.Token    as P

parserP :: Parser [[MyType]]
parserP = do
  x  <- rowP
  xs <- many (newline >> rowP)
  return (x : xs)

rowP :: Parser [MyType]
rowP = manyTill cellP $ void newline <|> eof

cellP :: Parser (Cell Color)
cellP = aP <|> bP <|> ... -- rest of the parsers, they all look very similar

aP :: Parser MyType
aP = symbol "a" >> return A

bP :: Parser MyType
bP = symbol "b" >> return B

lexer = P.makeTokenParser emptyDef
symbol  = P.symbol lexer
Run Code Online (Sandbox Code Playgroud)

但它无法返回多个内部列表.相反,我得到的是:

[[A, B, C, D, E, F]]
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?我期待很多人解析cellP直到换行符,但事实并非如此.

Ben*_*son 5

对于这种简单的事情,解析器组合器是过度的.我将使用lines :: String -> [String]words :: String -> [String]分解输入,然后将各个标记映射到MyTypes.

toMyType :: String -> Maybe MyType
toMyType "a" = Just A
toMyType "b" = Just B
toMyType "c" = Just C
toMyType _ = Nothing

parseMyType :: String -> Maybe [[MyType]]
parseMyType = traverse (traverse toMyType) . fmap words . lines
Run Code Online (Sandbox Code Playgroud)