Parsing 三元组的Haskell解析器
我目前正在做一项关于Haskell解析的作业,但我正在努力学习一些基础知识 作业: 我应该创建一个函数,将字符串解析为三元组列表。 以便: A、 B,C ,E,D 会导致Parsing 三元组的Haskell解析器,parsing,haskell,functional-programming,Parsing,Haskell,Functional Programming,我目前正在做一项关于Haskell解析的作业,但我正在努力学习一些基础知识 作业: 我应该创建一个函数,将字符串解析为三元组列表。 以便: A、 B,C ,E,D 会导致 Triples [("A","B","C"), ("A","E","D")] 输入字符串将包括:\作为一个新三元组开始的标志。字符串将以一个点结束。 三元组的元素可以是字母、数字或组合, e、 g.abc,a,1,abc121 所以, "a,b,c;\n d,e;\n f,g;\n h,i." 将导致: Triples
Triples [("A","B","C"), ("A","E","D")]
输入字符串将包括:\作为一个新三元组开始的标志。字符串将以一个点结束。
三元组的元素可以是字母、数字或组合,
e、 g.abc,a,1,abc121
所以,
"a,b,c;\n d,e;\n f,g;\n h,i."
将导致:
Triples [("a","b","c"),("a","d","e"),("a","f","g"),("a","h","i")]
我当前的解决方案:
这个函数非常简单和正确。获取字符串并返回一个newtype Triples对象,其中包含由parseTriples创建的Triples列表
parseTriples :: Parser [Triple]
parseTriples = parseTriple
>>= \r -> ((string ";\n" >> parseTriples >>= \rs -> return (r:rs))
P.<|>(return[r]))
导入:
newtype Triples = Triples [Triple] deriving (Show,Eq)
type Triple = (String, String, String)
import Test.HUnit (runTestTT,Test(TestLabel,TestList),(~?=))
import qualified Text.Parsec as P (char,runP,noneOf,many,(<|>),eof)
import Text.ParserCombinators.Parsec
import Text.Parsec.String
import Text.Parsec.Char
import Data.Maybe
导入Test.HUnit(runTestTT,Test(TestLabel,TestList),(~?=)
将限定的Text.Parsec作为P导入(char、runP、noneOf、many、()、eof)
导入Text.ParserCombinators.Parsec
导入Text.Parsec.String
导入Text.Parsec.Char
导入数据,也许吧
测试用例
runParsec :: Parser a -> String -> Maybe a
runParsec parser input = case P.runP parser () "" input of
Left _ -> Nothing
Right a -> Just a
-- | Tests the implementations of 'parseScore'.
main :: IO ()
main = do
testresults <- runTestTT tests
print testresults
-- | List of tests for 'parseScore'.
tests :: Test
tests = TestLabel "parseScoreTest" (TestList [
runParsec parseTriplesD "0,1,2;\n2,3." ~?= Just (Triples [("0","1","2"),("0","2","3")]),
runParsec parseTriplesD "a,bcde ,23." ~?= Just (Triples [("a","bcde ","23")]),
runParsec parseTriplesD "a,b,c;\n d,e;\n f,g;\n h,i." ~?= Just (Triples [("a","b","c"),("a","d","e"),("a","f","g"),("a","h","i")]),
runParsec parseTriplesD "a,bcde23." ~?= Nothing,
runParsec parseTriplesD "a,b,c;d,e;f,g;h,i." ~?= Nothing,
runParsec parseTriplesD "a,b,c;\nd;\nf,g;\nh,i." ~?= Nothing
])
runParsec::Parser a->String->Maybe a
runParsec parser input=case P.runP parser()“”的输入
左->无
对->只是一个
--|测试“parseScore”的实现。
main::IO()
main=do
testresults您可以做的是:
解析第一个字符
解析成对的列表
将第一个字符添加到每个对以创建三元组
使用do
符号将使代码更具可读性。
您可以使用alphaNum
作为字母数字的缩写
parseTriplesD :: Parser Triples
parseTriplesD = Triples <$> parseTriples
parseTriples :: Parser [Triple]
parseTriples = do
a <- parseString
char ','
pairs <- parsePair `sepBy1` string ";\n"
char '.'
eof
return (map (\(b, c) -> (a, b, c)) pairs)
parsePair :: Parser (String, String)
parsePair = do
first <- parseString
char ','
second <- parseString
return (first, second)
parseString :: Parser String
parseString = many (char ' ') >> many (alphaNum <|> char ' ')
parsetriples::解析器三元组
parseTriples=Triples parseTriples
parseTriples::解析器[Triple]
parseTriples=do
a您的第二个测试显示在“bcde”
上的预期输出中捕获的空间。我以为输出中只需要字母数字字符。那是打字错误吗?啊。错过了那个。我们没有得到直接的任务指示,只有测试用例。所以我假设它只是字母数字字符,但我完全忽略了那个空格字符。我将在我的问题中编辑它。好主意。我没想到。你能再解释一下pairs>可选(字符“”)吗?“sepBy 1”和可选选项有什么作用?以下是和的文档sepBy1
将解析由第二个参数分隔的第一个参数的列表optional
将尝试解析某些内容,但如果匹配失败,则会忽略它。
runParsec :: Parser a -> String -> Maybe a
runParsec parser input = case P.runP parser () "" input of
Left _ -> Nothing
Right a -> Just a
-- | Tests the implementations of 'parseScore'.
main :: IO ()
main = do
testresults <- runTestTT tests
print testresults
-- | List of tests for 'parseScore'.
tests :: Test
tests = TestLabel "parseScoreTest" (TestList [
runParsec parseTriplesD "0,1,2;\n2,3." ~?= Just (Triples [("0","1","2"),("0","2","3")]),
runParsec parseTriplesD "a,bcde ,23." ~?= Just (Triples [("a","bcde ","23")]),
runParsec parseTriplesD "a,b,c;\n d,e;\n f,g;\n h,i." ~?= Just (Triples [("a","b","c"),("a","d","e"),("a","f","g"),("a","h","i")]),
runParsec parseTriplesD "a,bcde23." ~?= Nothing,
runParsec parseTriplesD "a,b,c;d,e;f,g;h,i." ~?= Nothing,
runParsec parseTriplesD "a,b,c;\nd;\nf,g;\nh,i." ~?= Nothing
])
parseTriplesD :: Parser Triples
parseTriplesD = Triples <$> parseTriples
parseTriples :: Parser [Triple]
parseTriples = do
a <- parseString
char ','
pairs <- parsePair `sepBy1` string ";\n"
char '.'
eof
return (map (\(b, c) -> (a, b, c)) pairs)
parsePair :: Parser (String, String)
parsePair = do
first <- parseString
char ','
second <- parseString
return (first, second)
parseString :: Parser String
parseString = many (char ' ') >> many (alphaNum <|> char ' ')