如何解决以秒为单位的输入意外结束
| 我想解析这样的文件: 66:3 3:4 329:2 101:3 495:4 55:5 268:5 267:2 242:4 262:1 861:1 我的代码如下:getTestData :: String -> IO [[(Int,Int)]]
getTestData name = do
--res <- parseFromFile testData (name ++ \".test\")
fc <- readFile (name ++ \".test\")
let res = parse testData \"test data\" fc
case res of
Left e -> error $ show e-- \"test data parse eror.\"
Right ts -> return ts
eol = char \'\\n\'
testData = endBy line eol
--testData = many line
testTuple = do
i <- natural
colon
r <- natural
return (fromIntegral i:: Int,fromIntegral r:: Int)
line = sepBy testTuple whiteSpace
但是在运行时,它将引发异常:
ts <- getTestData \"data\"
*** Exception: \"test data\" (line 11,column 1):
unexpected end of input
expecting natural or \"\\n\"
我不明白,为什么说11行,而我的data.test文件只有10行。因此,经过多次尝试,我未能解决此问题。
解决方法
我最好的猜测是,ѭ3中的ѭ2正在消耗换行符。因此,您的整个文件都由单个
line
解析器进行解析,而ѭ5never解析器将永远不会有机会获得\"\\n\"
。尝试将whiteSpace
替换为many (char \' \')
,看看是否有帮助。
, 这是使用原始字符解析器而不是令牌解析器的有效实现。注意-不使用空格作为分隔符,而是将其删除(如果存在则更为健壮)。如果您使用Applicative中的(<*)
,则我使用过一行注解符号的位会更加整洁。
{-# OPTIONS -Wall #-}
module ParsecWhite where
import Text.ParserCombinators.Parsec
import Data.Char
main = getTestData \"sample\"
getTestData :: String -> IO [[(Int,Int)]]
getTestData name = do
--res <- parseFromFile testData (name ++ \".test\")
fc <- readFile (name ++ \".test\")
let res = parse testData \"test data\" fc
case res of
Left e -> error $ show e -- \"test data parse eror.\"
Right ts -> return ts
testData :: Parser [[(Int,Int)]]
testData = input
input :: Parser [[(Int,Int)]]
input = many (do { a <- line; newline; return a })
<?> \"input\"
line :: Parser [(Int,Int)]
line = many (do { a <- testTuple; softWhite; return a}) <?> \"line\"
testTuple :: Parser (Int,Int)
testTuple = do
i <- natural
colon
r <- natural
return (i,r)
<?> \"testTuple\"
softWhite :: Parser ()
softWhite = many (oneOf \" \\t\") >> return ()
colon :: Parser ()
colon = char \':\' >> return ()
natural :: Parser Int
natural = fmap (post 0) $ many1 digit
where
post ac [] = (ac * 10)
post ac [x] = (ac * 10) + digitToInt x
post ac (x:xs) = post ((ac * 10) + digitToInt x) xs
, 我敢打赌,您在最后一行的末尾缺少换行符。
为了解析完整的行,它应该是\“ 861:1 \\ n \”,但可能是\“ 861:1EOF \”。
因此,我认为您的解析器正确地将您的输入标识为不正确。
, 实际上,我发现您可以使用whiteSpace(例如,轻松地忽略多行块注释),同时仍然是面向行的。只需在需要换行符时包括此解析器。
col (== 1) \"only matches beginning of line\"
col pred errStr = do
c <- sourceColumn <$> getPosition
if pred c then return ()
else unexpected errStr
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。