避免使用 `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 以避免急切解析