问题标签 [megaparsec]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
353 浏览

parsing - 使用 Haskell/Megaparsec 进行解析:StateT 用于建立本地的词法范围?

因此,我正在尝试执行标准的“为自己编写类似方案的语言的解析器”练习来找出 MegaParsec 和 monad 转换器。遵循许多教程和博客文章的建议,我正在使用ReaderTlocal实现词法范围。

我在尝试实施时遇到了麻烦let*。两者共享相同的语法,绑定变量以在后续表达式中使用letlet*两者之间的区别在于let*允许您在后续绑定中使用绑定,而let不能:

我的问题是,在解析let*表达式时,我需要将绑定一个接一个地添加到当前范围,以便每个绑定都可用于后续绑定。这似乎是一个很好的用例StateT;允许我一次建立本地范围一个绑定。然后,在解析完所有新绑定后,我可以将这些以及从父作用域继承的那些一起传递给let*表达式的第三个参数 via local

我按如下方式构建我的 monad 转换器堆栈:

这是解析器,我尽可能地简化了我的观点。特别是,Float是唯一的数据类型+*, 和let*是唯一的命令。

上面的第一个测试成功,但第二个失败。它失败了,因为在第一个表达式中持有的可变状态x绑定let*被传递到第二个let*表达式。我需要一种方法来使这个可变状态成为相关计算的本地化,这是我不知道该怎么做的。是否有来自for的local命令的类似物?我使用了错误的单子变压器堆栈吗?我的方法有根本缺陷吗?ReaderState

我尝试过的天真的(回想起来)解决方案是通过向以下位置添加语句来重置每个let*表达式的可变状态:put Map.emptyletStarExpr

但这与嵌套let*表达式不兼容:

给出 1.0 而不是 666.0。

有任何想法吗?

0 投票
1 回答
331 浏览

haskell - 使用 megaparsec 解析后的错误包

我目前在 megaparsec 中有一个可以工作的解析器,在那里我为我的程序构建了一个 AST。我现在想对我的 AST 进行一些除草操作,同时能够使用与解析器相同类型的漂亮错误。虽然这个阶段是在解析之后,但我想知道 megaparsec 是否有这样做的一般做法。有没有办法让我提取每一行和评论(在包中使用)并将其添加到我的 AST 中的每个项目中?人们还有其他方法可以解决这个问题吗?

如果这听起来是开放式的,请提前道歉,但我主要想知道是否有比获取行号和自己创建捆绑包更好的想法。我对haskell还是新手,所以我无法正确浏览所有源代码。

0 投票
2 回答
187 浏览

parsing - 如何使用 Parsec 制作子解析器?

我想解析几个缩进或格式化为数组的命令列表Parsec。例如,我的列表格式如下:

这些命令应该通过解析器中的状态更改逐列解析。

我的想法是将命令收集到单独的字符串列表中,并将这些字符串解析为子解析器(在主解析器内执行)。

我检查了 Parsec 库的 API,但没有找到执行此操作的函数。

我考虑过使用runParser,但这个函数只提取解析器的结果,而不是它的状态。

我还考虑制作一个受启发的函数runParsecTmkPT制作我自己的解析器,但构造函数ParsecTinitialPos不可用(不由库导出)

是否可以在解析器中运行子解析器Parsec

如果没有,像megaparsec这样的库可以解决我的问题吗?

0 投票
1 回答
204 浏览

parsing - 我的 Megaparsec 解析器卡住了,ghci 调试也无济于事

我已经完成了这个 Megaparsec 教程,现在正在尝试基于它编写我自己的解析器。我想为一种编造的汇编语言编写一个简单的解析器:

这是我正在使用的简单数据类型:

这是解析器的代码:

我已经提出了给我带来麻烦的功能。我已经为这些功能编写了一些测试,这里是测试:

与汇编文件一样,我想逐行解析源代码。上面所有的测试都通过了,除了被注释掉的那个。运行with产生相同prog的结果,它不返回任何结果并最终崩溃:ghciparseTest

我假设我lexeme在我的代码中以某种方式滥用/过度使用以从解析的字符串中删除尾随空格。我错过了什么?

0 投票
1 回答
169 浏览

haskell - Megaparsec ParsecT 的状态不回溯

我有一个解析器定义为以下稍微复杂的版本:

这个想法是我可以建立一堆我想对我的状态(the [Int])执行的操作,然后根据情况以任何顺序或我想要的任何时候执行它们:

例如,执行的操作可能会重新排序操作堆栈或修改[Int].

除了设计决策(我确信有更好的方法可以做到这一点),回溯似乎try不适用于状态。具体来说, ParsecT 的状态将回溯,但内部状态([Int]and [X])不会。为什么是这样?我是在滥用 ParsecT 还是奇怪的递归X业务把一切都搞砸了?我需要Control.Monad.State.Strict改用吗?

编辑:要回答评论者关于示例的问题X,这里有一个:

useless[Int]如果它的元素少于十个,则加倍我们,并返回False. 如果它确实有十个或更多元素,它会删除自己并返回True。递归的强大X之处在于它可以选择在完成后是否删除自己。

0 投票
1 回答
88 浏览

haskell - 如何在 Parsec/Megaparsec 中重载运算符?

我正在使用Parsec/Megaparsec 作为解析器来实现编译器。我找不到重载 operator 的方法+,我想将它用于整数加法和字符串连接。可能吗?

0 投票
1 回答
228 浏览

haskell - 如何使用 Parsec 解析三元表达式?

buildExpressionParser只处理一元和二元运算符。它可以处理三元运算符?:吗?这里这里有一些讨论,但没有一个是决定性的。

0 投票
1 回答
98 浏览

haskell - 具有专业化规则的功能依赖

我想 为 Megaparsec 组合器编写一个专门化重写规则ByteString,以便该规则仅在输入类型为.

当我尝试构建它时,它失败了:

的输入流类型参数s对参数MonadParsec有功能依赖Monadm

这是specialize.cabal用于尝试构建的文件。

如果成功,输出应如下所示:

建议?

0 投票
1 回答
270 浏览

haskell - 如何使用 megaparsec 获取 AST 节点的源范围?

我正在尝试为正在解析的某些源文件生成源映射,并且我想获取每个节点的范围。getSourcePos仅给出节点的起始位置(src:line:column)。如何获得它的结束位置?

0 投票
1 回答
294 浏览

parsing - 如何使用 megaparsec 报告多个错误?

根据 megaparsec 文档,“从版本 8 开始,一次报告多个解析错误变得更加容易。” 我还没有找到一个这样做的例子。我唯一找到的是这个。然而,它只展示了如何解析一个换行符分隔的玩具语言,也没有展示如何将多个错误组合到 ParseErrorBundle 中。这个SO 讨论不是结论性的。