在 Haskell 的 Parsec 中解析基于缩进的语法
我正在尝试使用 Parsec 在 Haskell 中解析基于缩进的语言(例如 Python、Haskell 本身、Boo、YAML)。我已经看过 IndentParser 库,它看起来是完美的匹配,但我不知道如何使我的 TokenParser 成为缩进解析器。这是我到目前为止的代码:
import qualified Text.ParserCombinators.Parsec.Token as T
import qualified Text.ParserCombinators.Parsec.IndentParser.Token as IT
lexer = T.makeTokenParser mylangDef
ident = IT.identifier lexer
这会引发错误:
parser2.hs:29:28:
Couldn't match expected type `IT.TokenParser st'
against inferred type `T.GenTokenParser s u m'
In the first argument of `IT.identifier', namely `lexer'
In the expression: IT.identifier lexer
In the definition of `ident': ident = IT.identifier lexer
我做错了什么?我应该如何创建 IT.TokenParser
?或者 IndentParser 是否已损坏并需要避免?
I'm trying to parse an indentation-based language (think Python, Haskell itself, Boo, YAML) in Haskell using Parsec. I've seen the IndentParser library, and it looks like it's the perfect match, but what I can't figure out is how to make my TokenParser
into an indentation parser. Here's the code I have so far:
import qualified Text.ParserCombinators.Parsec.Token as T
import qualified Text.ParserCombinators.Parsec.IndentParser.Token as IT
lexer = T.makeTokenParser mylangDef
ident = IT.identifier lexer
This throws the error:
parser2.hs:29:28:
Couldn't match expected type `IT.TokenParser st'
against inferred type `T.GenTokenParser s u m'
In the first argument of `IT.identifier', namely `lexer'
In the expression: IT.identifier lexer
In the definition of `ident': ident = IT.identifier lexer
What am I doing wrong? How should I create an IT.TokenParser
? Or is IndentParser broken and to be avoided?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看起来您在这里使用的是 Parsec 3,而 IndentParser 需要 Parsec 2。您的示例使用
-package parsec-2.1.0.1
为我进行编译。因此,IndentParser 不一定被破坏,但作者应该更具体地了解依赖项列表中的版本。可以安装两个版本的 Parsec,因此您没有理由不使用 IndentParser,除非您出于其他原因致力于使用 Parsec 3。
更新:实际上,无需对源代码进行任何更改即可使 IdentParser 使用 Parsec 3。我们俩遇到的问题似乎是由
cabal-install
对秒差距 2 有一个“软偏好”。您可以简单地重新安装 IndentParser,并对 Parsec 版本进行显式约束:或者您可以下载 源 和 以正常方式构建和安装。
It looks like you're using Parsec 3 here, while IndentParser expects Parsec 2. Your example compiles for me with
-package parsec-2.1.0.1
.So IndentParser isn't necessarily broken, but the author(s) should have been more specific about versions in the list of dependencies. It's possible to have both versions of Parsec installed, so there's no reason you shouldn't use IndentParser unless you're committed to using Parsec 3 for other reasons.
UPDATE: Actually no changes to the source are necessary to get IdentParser working with Parsec 3. The problem that both of us were having seems to be caused by the fact that
cabal-install
has a "soft preference" for Parsec 2. You can simply reinstall IndentParser with an explicit constraint on the Parsec version:Alternatively you can download the source and build and install in the normal way.
这是我为 Parsec 3 整理的一组解析器组合器,可用于 Haskell 样式布局,可能对您有用。关键的考虑因素是
layout
启动并运行布局规则,并且您应该使用提供的space
和spaced
组合器,而不是常用的 < code>Parsec 组合器用于相同目的。由于布局和注释的交互,我必须将注释解析合并到标记器中。Here is a set of parser combinators I put together for Parsec 3 that can be used for Haskell style layout, that might be of use to you. The key considerations are that
laidout
starts and runs a layout rule, and that you should use thespace
andspaced
combinators provided rather than the stockParsec
combinators for the same purpose. Due to the interaction of layout and comments I had to merge the comment parsing into the tokenizer.