具有相同分隔符的嵌套 sepBy1
Nested sepBy1 with same delimiter
#!/usr/bin/env runhaskell
import Control.Applicative ((<|>))
import Text.Parsec.Char
import Text.ParserCombinators.Parsec hiding (spaces, (<|>))
main :: IO ()
main = do
print $ parse p "" "a\nb\n\nc\nd" where
p = sepBy1 (try pp) newline
pp = sepBy1 l newline
l = many1 letter
我正在尝试解析这个:
a
b
c
d
对此:[["a", "b"], ["c", "d"]]
。我尝试摆弄 try
但它似乎不起作用。
这可能是一些非常基础的东西,请尝试解释你的答案中发生了什么(我是 Haskell 和 Parsec 的初学者)。
编辑:忘记添加错误消息。
Left (line 3, column 1):
unexpected "\n"
expecting letter
问题似乎出在sepBy1的实现上,因为parse pp "" "a\nb\n"
也出现了错误。虽然我们期望这是 return Right ["a","b"]
,但它会抛出相同的 expected \n
错误。
因此,sepBy1
看起来像预期的那样工作,除了要解析的字符串以分隔符结尾的情况。这似乎是无害的,因为对于这种情况还有另一个解析器组合器。但是现在我们想要两个嵌套的 sepBy1
具有相同的分隔符,这是一个问题。
我找到的唯一解决方案是编写自己的回溯sepBy1
,并在内部案例中使用它。
main :: IO ()
main = print $ parse p "" "a\nb\n\nc\nd"
where pp = mySepBy1 l newline
l = many1 letter
p = sepBy1 pp (newline >> newline)
mySepBy1 parser separator = do
x <- parser
xs <- many (try $ separator >> parser)
return (x:xs)
#!/usr/bin/env runhaskell
import Control.Applicative ((<|>))
import Text.Parsec.Char
import Text.ParserCombinators.Parsec hiding (spaces, (<|>))
main :: IO ()
main = do
print $ parse p "" "a\nb\n\nc\nd" where
p = sepBy1 (try pp) newline
pp = sepBy1 l newline
l = many1 letter
我正在尝试解析这个:
a
b
c
d
对此:[["a", "b"], ["c", "d"]]
。我尝试摆弄 try
但它似乎不起作用。
这可能是一些非常基础的东西,请尝试解释你的答案中发生了什么(我是 Haskell 和 Parsec 的初学者)。
编辑:忘记添加错误消息。
Left (line 3, column 1):
unexpected "\n"
expecting letter
问题似乎出在sepBy1的实现上,因为parse pp "" "a\nb\n"
也出现了错误。虽然我们期望这是 return Right ["a","b"]
,但它会抛出相同的 expected \n
错误。
因此,sepBy1
看起来像预期的那样工作,除了要解析的字符串以分隔符结尾的情况。这似乎是无害的,因为对于这种情况还有另一个解析器组合器。但是现在我们想要两个嵌套的 sepBy1
具有相同的分隔符,这是一个问题。
我找到的唯一解决方案是编写自己的回溯sepBy1
,并在内部案例中使用它。
main :: IO ()
main = print $ parse p "" "a\nb\n\nc\nd"
where pp = mySepBy1 l newline
l = many1 letter
p = sepBy1 pp (newline >> newline)
mySepBy1 parser separator = do
x <- parser
xs <- many (try $ separator >> parser)
return (x:xs)