【发布时间】:2016-05-30 15:54:08
【问题描述】:
假设我想解析语言 X 的文件。真的,我只对其中的一小部分信息感兴趣。为此目的,在 Haskell 的众多 eDSL 之一中编写解析器很容易(例如 Megaparsec)。
data Foo = Foo Int -- the information I'm after.
parseFoo :: Parsec Text Foo
parseFoo = ...
这很容易产生一个函数getFoo :: Text -> Maybe Foo。
但是现在我也想修改Foo信息的来源,即基本上我要实现
changeFoo :: (Foo -> Foo) -> Text -> Text
属性
changeFoo id ≡ id
getFoo . changeFoo f ≡ fmap f . getFoo
可以通过将解析器的结果更改为类似镜头的东西来做到这一点
parseFoo :: Parsec Text (Foo, Foo -> Text)
parseFoo = ...
但这使得定义变得更加麻烦——我不能再仅仅掩盖不相关的信息,而是需要存储每个 string 子解析的匹配项并手动重新组合它。
这可以通过将字符串重新组合保持在解析器 monad 周围的 StateT 层中来实现某种程度的自动化,但我不能只使用现有的原始解析器。
这个问题有现成的解决方案吗?
【问题讨论】:
-
解析库通常会构建一个“抽象语法树”,它会忽略所有格式。您正在寻找的是“具体语法树”。我不知道有什么库可以构建它。
-
我通常在Prolog中使用definite clause grammars进行双向解析,但是在Haskell中我没见过这样的东西。
标签: parsing haskell parsec bijection