对于这个简化的问题,我试图解析如下所示的输入
foo bar
baz quux
woo
hoo xyzzy
glulx转到
[["foo", "bar", "baz", "quux", "woo"], ["hoo", "xyzzy", "glulx"]]我尝试过的代码如下:
import qualified Text.Megaparsec.Lexer as L
import Text.Megaparsec hiding (space)
import Text.Megaparsec.Char hiding (space)
import Text.Megaparsec.String
import Control.Monad (void)
import Control.Applicative
space :: Parser ()
space = L.space (void spaceChar) empty empty
item :: Parser () -> Parser String
item sp = L.lexeme sp $ some letterChar
items :: Parser () -> Parser [String]
items sp = L.lineFold sp $ \sp' -> some (item sp')
items_ :: Parser [String]
items_ = items space这适用于一个块items
λ» parseTest items_ "foo bar\n baz quux\n woo"
["foo","bar","baz","quux","woo"]但是,一旦我试图解析many items,它就会在第一个未缩进的行上失败:
λ» parseTest (many items_) "foo bar\n baz quux\n woo\nhoo xyzzy\n glulx"
4:1:
incorrect indentation (got 1, should be greater than 1)或者,用一个更简单的输入:
λ» parseTest (many items_) "a\nb"
2:1:
incorrect indentation (got 1, should be greater than 1)发布于 2016-05-16 18:19:26
Megaparsec的作者是这样的:-)当你使用Megaparsec时,要记住的一件事是,它的lexer模块实际上是“低级”的。它不会做任何你无法构建自己的事情,也不会将你锁在任何特定的“框架”中。因此,在您的情况下,您有为您提供的空间使用者sp',但是您应该谨慎使用它,因为当您的缩进级别小于或等于整个折叠开始时的缩进级别时,它肯定会失败,顺便说一句,这就是折叠结束的方式。
引用医生们
创建一个支持行折叠的解析器。第一个参数用于使用行折叠组件之间的空白,因此它必须使用新行才能正常工作。第二个参数是一个回调,它接收自定义的空间消耗解析器作为参数。此解析器应在可以放置在不同行上的行折叠的单独组件之后使用。
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 spaceitem `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"]]https://stackoverflow.com/questions/37256316
复制相似问题