我有一个带有两个单独形式的文本的文本,例如: 123:ABC 456:DEF ABC:123 386:HDG DEF:456
现在我写了两个解析器,第一个用于123:ABC,这个形式,另一个用于ABC:456。我想知道的是如何在一个主函数中创建两个解析器
123:ABC
456:DEF
ABC:123
386:HDG
DEF:456
aa=B.readFile logFile >>= print . parseOnly aaParser
bb=B.readFile logFile >>= print . parseOnly bbParser
main :: IO ()
main =B.readFile logFile >>= print . parseOnly aaParser --there is missing the aaparser and I need both of them for the text above
答案 0 :(得分:1)
很难从实现中判断出解析器的输出形式是什么,因此很难知道它们如何组合。一种可能的方法是使两种不同格式中的每一种对应于代数数据类型的不同数据构造器。一个简单的解决方案可能如下所示:
module TinyParse(parseABC123Format) where
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Char
data TwoTypes
= ABCNums String String
| NumsABC String String
deriving (Eq, Show)
parseABC123Format :: String -> [TwoTypes]
parseABC123Format str = case parse parseABC123File "ABC123" str of
Left err -> error $ show err
Right p -> p
parseABC123File :: Parser [TwoTypes]
parseABC123File = endBy parseEither spaces
parseEither :: Parser TwoTypes
parseEither = parseABC123 <|> parse123ABC
parseABC123 :: Parser TwoTypes
parseABC123 = do
threeLetters <- parseABC
semi <- char ':'
threeNumbers <- parseNums
return $ ABCNums threeLetters threeNumbers
parse123ABC :: Parser TwoTypes
parse123ABC = do
threeNumbers <- parseNums
semi <- char ':'
threeLetters <- parseABC
return $ NumsABC threeNumbers threeLetters
parseNums :: Parser String
parseNums = do
d1 <- digit
d2 <- digit
d3 <- digit
return (d1:d2:d3:[])
parseABC :: Parser String
parseABC = do
l1 <- upper
l2 <- upper
l3 <- upper
return (l1:l2:l3:[])