Megaparsec 的作者在这里 :-) 当你使用时要记住一件事
Megaparsec 的特点是它的词法分析器模块确实是故意的“低级”。它
不会做任何你自己无法构建的事情,它不会将你锁定在任何
特定的“框架”。所以基本上在你的情况下你有空间消费者sp'
为您提供,但您应该谨慎使用它,因为它肯定会
当您的缩进级别小于或等于的缩进级别时失败
顺便说一句,整个折叠的开始,这就是折叠的结束方式。
去引用the docs https://hackage.haskell.org/package/megaparsec-5.0.0/docs/Text-Megaparsec-Lexer.html#v:lineFold:
创建一个支持行折叠的解析器。第一个参数用于
消耗线折叠组件之间的空白,因此它必须消耗
换行符才能正常工作。第二个参数是一个回调
接收自定义的占用空间的解析器作为参数。这个解析器应该是
在线折叠的单独组件之后使用,可以将其放在不同的位置上
线。
sc = L.space (void spaceChar) empty empty
myFold = L.lineFold sc $ \sc' -> do
L.symbol sc' "foo"
L.symbol sc' "bar"
L.symbol sc "baz" -- for the last symbol we use normal space consumer
折线不能无限期地运行,因此您应该预料到它会失败并出现错误
消息类似于您现在的消息。要想成功,你应该思考
关于完成它的方法。这通常是通过使用“正常”来完成的
行折叠末尾的空间消费者:
space :: Parser ()
space = L.space (void spaceChar) empty empty
item :: Parser String
item = some letterChar
items :: Parser () -> Parser [String]
items sp = L.lineFold sp $ \sp' ->
item `sepBy1` try sp' <* sp
items_ :: Parser [String]
items_ = items space
item `sepBy1` try sp'
运行直到失败然后sp
抓住剩下的,所以
可以解析下一个折叠。
λ> parseTest items_ "foo bar\n baz quux\n woo"
["foo","bar","baz","quux","woo"]
λ> parseTest (many items_) "foo bar\n baz quux\n woo\nhoo xyzzy\n glulx"
[["foo","bar","baz","quux","woo"],["hoo","xyzzy","glulx"]]
λ> parseTest (many items_) "foo bar\n baz quux\n woo\nhoo\nxyzzy\n glulx"
[["foo","bar","baz","quux","woo"],["hoo"],["xyzzy","glulx"]]