避免使用 `sepBy` 解析最后一个分隔符
avoid parsing last separator with `sepBy`
我正在尝试使用 megaparsec
解析字符串。
其中一部分是由分隔符分隔的字符串重复,为此我使用 sepBy
。
考虑例如
sepBy (char 'a') (char 's')
这可以正确解析 ""
、"a"
、"asa"
、...
如果我需要继续使用另一个以我的分隔符开头的解析器进行解析,就会出现问题,如
(,) <$> sepBy (char 'a') (char 's') <*> string "something"
如果我尝试使用此解析器解析字符串 "asasomething"
,我希望得到 ("aa", "something")
。相反,我得到一个错误,因为我在第二个 s
.
之后没有 a
我也试过 sepEndBy
但结果是一样的
我是这样解决的
megapersec
使用的sepBy
实现是
sepBy :: MonadPlus m => m a -> m sep -> m [a]
sepBy p sep = do
r <- C.optional p
case r of
Nothing -> return []
Just x -> (x:) <$> many (sep >> p)
我修改为
sepBy :: Parser a -> Parser sep -> Parser [a]
sepBy p sep = do
r <- optional p
case r of
Nothing -> return []
Just x -> (x:) <$> many (try $ sep >> p)
将其专门化为 Parsec
添加一个 try
以避免急切解析
我正在尝试使用 megaparsec
解析字符串。
其中一部分是由分隔符分隔的字符串重复,为此我使用 sepBy
。
考虑例如
sepBy (char 'a') (char 's')
这可以正确解析 ""
、"a"
、"asa"
、...
如果我需要继续使用另一个以我的分隔符开头的解析器进行解析,就会出现问题,如
(,) <$> sepBy (char 'a') (char 's') <*> string "something"
如果我尝试使用此解析器解析字符串 "asasomething"
,我希望得到 ("aa", "something")
。相反,我得到一个错误,因为我在第二个 s
.
a
我也试过 sepEndBy
但结果是一样的
我是这样解决的
megapersec
使用的sepBy
实现是
sepBy :: MonadPlus m => m a -> m sep -> m [a]
sepBy p sep = do
r <- C.optional p
case r of
Nothing -> return []
Just x -> (x:) <$> many (sep >> p)
我修改为
sepBy :: Parser a -> Parser sep -> Parser [a]
sepBy p sep = do
r <- optional p
case r of
Nothing -> return []
Just x -> (x:) <$> many (try $ sep >> p)
将其专门化为 Parsec
添加一个 try
以避免急切解析