haskell一个文本的两个解析器

时间:2014-05-23 17:07:43

标签: parsing haskell

我有一个带有两个单独形式的文本的文本,例如:     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

1 个答案:

答案 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:[])