Haskell Parsec的indents包提供了一种解析缩进式语言(如 Haskell 和 Python)的方法。它重新定义了Parser
类型,那么如何使用 ParsecText.Parsec.Token
模块导出的普通Parser
类型的令牌解析器函数呢?
背景
- Parsec是一个解析器组合库,不管这意味着什么。
- IndentParser 0.2.1是一个旧包,提供两个模块
Text.ParserCombinators.Parsec.IndentParser
和Text.ParserCombinators.Parsec.IndentParser.Token
- indents 0.3.3是一个提供单个模块的新包
Text.Parsec.Indent
Parsec 带有大量的模块。它们中的大多数导出了一堆有用的解析器(例如newline
from Text.Parsec.Char
,它解析一个换行符)或解析器组合器(例如 count n p
from Text.Parsec.Combinator
,它运行解析器p,n次)
但是,该模块Text.Parsec.Token
希望导出由用户参数化的具有被解析语言特征的函数,例如,该函数将在解析“{”之后和解析“}”之前braces p
运行解析器p ,忽略诸如注释之类的东西,其语法取决于您的语言。
实现这一点的方法Text.Parsec.Token
是它导出一个makeTokenParser
你调用的函数,给它你特定语言的参数(比如评论的样子),它返回一个包含所有函数的记录Text.Parsec.Token
,适应你的语言指定的。
当然,在缩进风格的语言中,这些需要进一步调整(也许?这是我不确定的地方——我稍后会解释)所以我注意到(可能已经过时的)IndentParser 包提供了一个模块Text.ParserCombinators.Parsec.IndentParser.Token
它看起来是Text.Parsec.Token
.
我应该在某些时候提到所有 Parsec 解析器都是一元函数,所以它们对状态做了神奇的事情,以便错误消息可以说明错误出现在源文件的哪一行和哪一列
我的问题
由于几个小原因,在我看来indents包或多或少是 IndentParser 的当前版本,但是它不提供看起来像的模块,Text.ParserCombinators.Parsec.IndentParser.Token
它只提供Text.Parsec.Indent
,所以我想知道如何获得所有令牌解析器Text.Parsec.Token
(比如reserved "something"
解析保留关键字“某物”,或者像braces
我之前提到的那样)。
在我看来,(新的)Text.Parsec.Indent
通过某种单子状态魔法来计算源代码的列位是什么,因此它不需要像whiteSpace
from那样修改令牌解析器Text.Parsec.Token
,这可能就是它的原因不提供替换模块。但是我遇到了类型问题。
你看,没有Text.Parsec.Indent
,我所有的解析器都是类型Parser Something
,其中 Something 是返回类型,并且Parser
是 Text.Parsec.String 中定义的类型别名
type Parser = Parsec String ()
但是我使用自己的定义Text.Parsec.Indent
而不是导入Text.Parsec.String
type Parser a = IndentParser String () a
这使我的所有类型的解析器,其中 IndentParser 在 Text.Parsec.Indent 中定义。但是我从中获得的令牌解析器类型错误。IndentParser String () Something
makeTokenParser
Text.Parsec.Token
如果现在这没有多大意义,那是因为我有点迷路了。类型问题在这里讨论了一下。
我得到的错误是我尝试用另一个定义替换Parser
上面的一个定义,但是当我尝试使用其中一个令牌解析器时Text.Parsec.Token
,我得到了编译错误
Couldn't match expected type `Control.Monad.Trans.State.Lazy.State
Text.Parsec.Pos.SourcePos'
with actual type `Data.Functor.Identity.Identity'
Expected type: P.GenTokenParser
String
()
(Control.Monad.Trans.State.Lazy.State Text.Parsec.Pos.SourcePos)
Actual type: P.TokenParser ()
链接
- 秒差距
- IndentParser(旧包)
- indents,提供 Text.Parsec.Indent (新包)
- 使用示例代码讨论解析器类型
- 另一个使用 Text.Parsec.Indent 的例子
遗憾的是,上述示例都没有使用像 Text.Parsec.Token 中那样的令牌解析器。