我目前正在解决AOC第四项任务,输入格式如下,用逗号分隔的数字行,然后是5x5矩阵:
27,14,70,7,85,66,65
31 23 52 26 8
27 89 37 80 46
97 19 63 34 79
13 59 45 12 73
42 25 22 6 39
27 71 24 3 0
79 42 32 72 62
99 52 11 92 33
38 22 16 44 39
35 26 76 49 58
27 71 24 ...我有以下解析器:
{-# LANGUAGE TupleSections #-}
module Lib4Parse (parseAll) where
import Control.Applicative
import Control.Monad
import Data.Attoparsec.ByteString.Char8 (Parser, Result, char, count, decimal, eitherResult, endOfInput, endOfLine, isDigit, isEndOfLine, isSpace, many', many1, option, parse, parseOnly, parseTest, scientific, sepBy, signed, skipMany, skipMany1, skipSpace, skipWhile, space, takeTill)
import qualified Data.ByteString as B
newtype BoardEntry = MkBoardEntry (Bool, Int) deriving (Show, Eq)
newtype Board = MkBoard [[BoardEntry]] deriving (Show, Eq)
parseAll :: B.ByteString -> Maybe ([Int], [Board])
parseAll input =
either (const Nothing) Just $
parseOnly ((,) <$> inputNumbers <*> boards) input
inputNumbers :: Parser [Int]
inputNumbers = decimal `sepBy` char ','
boardEntry :: Parser [BoardEntry]
boardEntry = map (\x -> MkBoardEntry (False, x)) <$> (decimal `sepBy` many1 (char ' '))
board :: Parser Board
board =
MkBoard <$> count 5 (boardEntry <* (skipWhile isSpace <|> endOfInput))
boards :: Parser [Board]
boards = takeTill isDigit >> many board问题是,当我在板函数中使用many时,它会挂起(当调用parseAll函数时)。但是,如果董事会的功能看起来像这样,它可以工作:
boards :: Parser [Board]
boards = takeTill isDigit >> count 5 board然而,我想解析所有的董事会,而不仅仅是指定的数目。
问题
这个挂起的问题是什么,怎么解决呢?
如何调试这样的解析器?-我无法调试它,因为我不知道解析器在做什么。有什么技巧和技巧来调试这样的解析器吗?
发布于 2022-02-14 23:39:47
根据@Carl的评论,问题是board可以匹配空输入,所以当它到达输入末尾时,many board试图解析无限多个空板。具体来说,一个board匹配五个boardEntry,但是boardEntry可以匹配零数字(即一个空字符串)。如果所有行都应该那么长,则可以要求它匹配五个数字,或者可以将sepBy升级到sepBy1,以确保至少匹配一个数字:
boardEntry :: Parser [BoardEntry]
boardEntry = map (\x -> MkBoardEntry (False, x)) <$> (decimal `sepBy1` many1 (char ' '))我常用的调试解析器的方法是孤立地运行小块:
> :set -XOverloadedStrings
> parseOnly boardEntry "1 2 3 4 5\n"
Right [MkBoardEntry (False,1),...]在这种情况下,这没有多大帮助。在我走得太远之前,我碰巧在boardEntry中发现了这个问题。
https://stackoverflow.com/questions/71117525
复制相似问题