【发布时间】:2015-06-26 21:15:49
【问题描述】:
其实我很确定我使用了错误的术语。这是我要解决的问题:markdown 格式的解析器,以及它的一个子集。
我的问题在于块引用功能。块引用中的每一行都以> 开头;否则一切都是markdown文件中的正常结构。
您不能单独查看单独的行,因为您需要将段落与正常行分开,例如
> a
> b
不一样
> a
>
> b
和类似的东西(如果列表被块引用,你不想要 x 列表而是一个带有 x 元素的列表)。一种自然而简单的方法是“取消”> 标志,自行解析块引用,忽略它周围的任何内容,用BlockQuote 类型构造函数包装它,将其放入外部 AST 并继续解析原始输入。如果我没记错的话,这就是pango 所做的:
blockQuote :: MarkdownParser (F Blocks)
blockQuote = do
raw <- emailBlockQuote
-- parse the extracted block, which may contain various block elements:
contents <- parseFromString parseBlocks $ (intercalate "\n" raw) ++ "\n\n"
return $ B.blockQuote <$> contents
然后:
http://hackage.haskell.org/package/pandoc-1.5.1/docs/src/Text-Pandoc-Shared.html#parseFromString
-- | Parse contents of 'str' using 'parser' and return result.
parseFromString :: GenParser tok st a -> [tok] -> GenParser tok st a
parseFromString parser str = do
oldPos <- getPosition
oldInput <- getInput
setInput str
result <- parser
setInput oldInput
setPosition oldPos
return result
现在 parseFromString 对我来说看起来很 hacky,此外它也是 Parsec 而不是 attoparsec 所以我不能在我的项目中使用它。我不确定如何从块引用中获取 Text 并对其进行解析并返回解析结果,以便它“适合”当前解析。似乎不可能?
我一直在谷歌上搜索这个问题,我认为 pipes-parse 和 conduit 可以在该领域提供帮助,尽管我很难找到示例并且我看到的看起来不太好看at 比“纯”解析器/attoparsec 解析器。
解析块引用的其他选项是重写通常的解析器,但使用> 捕获...复杂和重复很多。解析块引用分别计算每一行并编写一些凌乱的“合并”函数。或者解析到第一个 AST,它将在第一个 BlockquoteText 类型构造函数中包含块引用作为 Text 等待转换,在那里它们将被单独解析,不是很优雅,但它具有简单的好处,这确实很重要.
我可能会选择后者,但肯定有更好的方法吗?
【问题讨论】:
-
我不知道有一个解析器组合器库可以顺利支持这种组合(我过去一直在寻找它)。
-
前几天我遇到了类似的问题,试图解析一个“面向行”的文件。
Parsec的问题是:它给您的印象是您不需要词法分析器,而且理论上您可能不需要。在您的情况下,似乎首先“标记”您的文件将解决问题。您只需要为 BlockQuote 创建令牌。我可能错了。 -
@mb14 有趣...您知道这种方法的一些 OSS 示例吗,lexer 然后 parsec?它可能确实有效,但这次我可能会跳过它并采用一种不太优雅的方法。
-
我知道 parsec 也支持词法分析器,但我没有发现任何真正有用的东西。但是,我确定有。 Lexer + Parser 是标准方法,所以至少 GHC 应该做类似的事情。
-
有this,我真的没有时间好好看看。
标签: haskell attoparsec