问题标签 [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.
parsing - 使用 Haskell/Megaparsec 进行解析:StateT 用于建立本地的词法范围?
因此,我正在尝试执行标准的“为自己编写类似方案的语言的解析器”练习来找出 MegaParsec 和 monad 转换器。遵循许多教程和博客文章的建议,我正在使用ReaderT
并local
实现词法范围。
我在尝试实施时遇到了麻烦let*
。两者共享相同的语法,绑定变量以在后续表达式中使用let
。let*
两者之间的区别在于let*
允许您在后续绑定中使用绑定,而let
不能:
我的问题是,在解析let*
表达式时,我需要将绑定一个接一个地添加到当前范围,以便每个绑定都可用于后续绑定。这似乎是一个很好的用例StateT
;允许我一次建立本地范围一个绑定。然后,在解析完所有新绑定后,我可以将这些以及从父作用域继承的那些一起传递给let*
表达式的第三个参数 via local
。
我按如下方式构建我的 monad 转换器堆栈:
这是解析器,我尽可能地简化了我的观点。特别是,Float
是唯一的数据类型+
,*
, 和let*
是唯一的命令。
上面的第一个测试成功,但第二个失败。它失败了,因为在第一个表达式中持有的可变状态x
绑定let*
被传递到第二个let*
表达式。我需要一种方法来使这个可变状态成为相关计算的本地化,这是我不知道该怎么做的。是否有来自for的local
命令的类似物?我使用了错误的单子变压器堆栈吗?我的方法有根本缺陷吗?Reader
State
我尝试过的天真的(回想起来)解决方案是通过向以下位置添加语句来重置每个let*
表达式的可变状态:put Map.empty
letStarExpr
但这与嵌套let*
表达式不兼容:
给出 1.0 而不是 666.0。
有任何想法吗?
haskell - 使用 megaparsec 解析后的错误包
我目前在 megaparsec 中有一个可以工作的解析器,在那里我为我的程序构建了一个 AST。我现在想对我的 AST 进行一些除草操作,同时能够使用与解析器相同类型的漂亮错误。虽然这个阶段是在解析之后,但我想知道 megaparsec 是否有这样做的一般做法。有没有办法让我提取每一行和评论(在包中使用)并将其添加到我的 AST 中的每个项目中?人们还有其他方法可以解决这个问题吗?
如果这听起来是开放式的,请提前道歉,但我主要想知道是否有比获取行号和自己创建捆绑包更好的想法。我对haskell还是新手,所以我无法正确浏览所有源代码。
parsing - 如何使用 Parsec 制作子解析器?
我想解析几个缩进或格式化为数组的命令列表Parsec
。例如,我的列表格式如下:
这些命令应该通过解析器中的状态更改逐列解析。
我的想法是将命令收集到单独的字符串列表中,并将这些字符串解析为子解析器(在主解析器内执行)。
我检查了 Parsec 库的 API,但没有找到执行此操作的函数。
我考虑过使用runParser
,但这个函数只提取解析器的结果,而不是它的状态。
我还考虑制作一个受启发的函数runParsecT
并mkPT
制作我自己的解析器,但构造函数ParsecT
或initialPos
不可用(不由库导出)
是否可以在解析器中运行子解析器Parsec
?
如果没有,像megaparsec这样的库可以解决我的问题吗?
parsing - 我的 Megaparsec 解析器卡住了,ghci 调试也无济于事
我已经完成了这个 Megaparsec 教程,现在正在尝试基于它编写我自己的解析器。我想为一种编造的汇编语言编写一个简单的解析器:
这是我正在使用的简单数据类型:
这是解析器的代码:
我已经提出了给我带来麻烦的功能。我已经为这些功能编写了一些测试,这里是测试:
与汇编文件一样,我想逐行解析源代码。上面所有的测试都通过了,除了被注释掉的那个。运行with产生相同prog
的结果,它不返回任何结果并最终崩溃:ghci
parseTest
我假设我lexeme
在我的代码中以某种方式滥用/过度使用以从解析的字符串中删除尾随空格。我错过了什么?
haskell - Megaparsec ParsecT 的状态不回溯
我有一个解析器定义为以下稍微复杂的版本:
这个想法是我可以建立一堆我想对我的状态(the [Int]
)执行的操作,然后根据情况以任何顺序或我想要的任何时候执行它们:
例如,执行的操作可能会重新排序操作堆栈或修改[Int]
.
除了设计决策(我确信有更好的方法可以做到这一点),回溯似乎try
不适用于状态。具体来说, ParsecT 的状态将回溯,但内部状态([Int]
and [X]
)不会。为什么是这样?我是在滥用 ParsecT 还是奇怪的递归X
业务把一切都搞砸了?我需要Control.Monad.State.Strict
改用吗?
编辑:要回答评论者关于示例的问题X
,这里有一个:
useless
[Int]
如果它的元素少于十个,则加倍我们,并返回False
. 如果它确实有十个或更多元素,它会删除自己并返回True
。递归的强大X
之处在于它可以选择在完成后是否删除自己。
haskell - 如何在 Parsec/Megaparsec 中重载运算符?
我正在使用Parsec/Megaparsec 作为解析器来实现编译器。我找不到重载 operator 的方法+
,我想将它用于整数加法和字符串连接。可能吗?
haskell - 如何使用 Parsec 解析三元表达式?
buildExpressionParser只处理一元和二元运算符。它可以处理三元运算符?:
吗?这里和这里有一些讨论,但没有一个是决定性的。
haskell - 具有专业化规则的功能依赖
我想
为 Megaparsec 组合器编写一个专门化重写规则ByteString
,以便该规则仅在输入类型为.
当我尝试构建它时,它失败了:
的输入流类型参数s
对参数MonadParsec
有功能依赖。Monad
m
这是specialize.cabal
用于尝试构建的文件。
如果成功,输出应如下所示:
建议?
haskell - 如何使用 megaparsec 获取 AST 节点的源范围?
我正在尝试为正在解析的某些源文件生成源映射,并且我想获取每个节点的范围。getSourcePos仅给出节点的起始位置(src:line:column)。如何获得它的结束位置?
parsing - 如何使用 megaparsec 报告多个错误?
根据 megaparsec 文档,“从版本 8 开始,一次报告多个解析错误变得更加容易。” 我还没有找到一个这样做的例子。我唯一找到的是这个。然而,它只展示了如何解析一个换行符分隔的玩具语言,也没有展示如何将多个错误组合到 ParseErrorBundle 中。这个SO 讨论不是结论性的。