我将尝试在Haskell中解析表示树的字符串。每个节点都位于一行上,其中缩进确定了嵌套层次(例如,类似于Python或Haskell的语法)。
成功的解析结果应该是类型为
例如,字符串
应该导致
使用 Haskell indents package 和一篇关于如何解析缩进树的 文章 的帮助,我可以解析出以下示例。
问题在于我的当前实现成功解析了该字符串。
节点
我的实现如下(简化:树标签非空且仅包含字母数字字符;不支持每种Unicode换行符)。
这个解析器如何修改才能仅接受与某个外部缩进级别匹配的未缩进内容?提前感谢。
成功的解析结果应该是类型为
[Tree]
(玫瑰树森林),其中:data Tree = Tree String [Tree]
deriving Show
例如,字符串
A
B
C
D
E
F
应该导致
[Tree "A" [Tree "B" [], Tree "C" []], Tree "D" [Tree "E" [Tree "F" []]]]
使用 Haskell indents package 和一篇关于如何解析缩进树的 文章 的帮助,我可以解析出以下示例。
问题在于我的当前实现成功解析了该字符串。
A
B
C
D
as
[Tree "A" [Tree "B" [Tree "C" []]], Tree "D" []]
节点
D
被解析为另一个根。然而,我希望在解析D
失败,因为它与C
相比没有缩进,但它的缩进级别与A
或B
不匹配。我的实现如下(简化:树标签非空且仅包含字母数字字符;不支持每种Unicode换行符)。
import qualified Control.Applicative as A
import qualified Control.Monad as M
import qualified Text.Parsec as P
import qualified Text.Parsec.Indent as I
parse :: String -> Either P.ParseError [Tree]
parse = I.runIndent "" . P.runParserT forest () ""
forest = P.many tree A.<* P.eof
tree = spacing A.*> I.withBlock Tree node tree
spacing = P.many P.newline A.*> indentation
indentation = P.many $ P.char ' '
node = label A.<* spacing
label = P.many1 P.alphaNum A.<* lineEnd
lineEnd = M.void P.newline P.<|> P.eof
这个解析器如何修改才能仅接受与某个外部缩进级别匹配的未缩进内容?提前感谢。
same
已经提供了这个功能,不是吗? - Zetaforest = I.block tree A.<* P.eof
可以帮助解决问题!(我需要等一会儿才能回答自己。) - evolutics