我与Haskell的初学者,所以它可能是很明显的,我做错了什么......想不通负前瞻与秒差距
虽然试图解析"1:1,2, 2:18, 3:100"
到[(1,1), (1,2), (2,18), (3,100)]
我被困在一个超前。
要知道一个数字是否是一个经文编号,它应该向前看一个冒号,因为它是一个章节号码。
问题在于最后一个函数verseNr
,如果没有冒号后面的话,它应该解析+使用该数字,否则失败而不消耗任何东西(将数字作为章节号码解析为refGroupByChapter
)。
除了这个问题似乎很好地工作:)
import Text.ParserCombinators.Parsec
main = do
case (parse refString "(unknown)" "1:1,2, 2:18, 3:100") of
Left e -> do putStr "parse error at "; print e
Right x -> print x -- expecting: [(1,1), (1,2), (2,18), (3,100)]
refString :: GenParser Char st [(Int, Int)]
refString = do
refGroups <- many refGroupByChapter
eof
return $ concat $ map flatten refGroups
where flatten (_, []) = []
flatten (c, v:vs) = (c, v):(flatten (c, vs))
refGroupByChapter :: GenParser Char st (Int, [Int])
refGroupByChapter = do
chapterNum <- many digit
char ':'
verseNums <- verseNrs
return ((read chapterNum :: Int), verseNums)
verseNrs :: GenParser Char st [Int]
verseNrs = do
first <- verseNr
remaining <- remainingVerseNrs
return (first:remaining)
where
remainingVerseNrs = do -- allow for spaces around the commas
(spaces >> oneOf "," >> spaces >> verseNrs) <|> (return [])
verseNr = try $ do
n <- many1 digit
notFollowedBy $ char ':' -- if followed by a ':' it's a chapter number
return (read n :: Int)
非常感谢..它工作得很好,你的风格的评论也发现了我的代码。 – cies