问题标签 [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 回答
661 浏览

haskell - parsec 如何递归解析简单表达式?

我有这样的字符串:***, **(*)*,****(**(**)*)**

我想像这样在数据结构中解析它:

data Tree = Node [S] Tree Tree | Empty在哪里 (S并不意味着任何字符,它只是星号)**

我尝试构建解析器(我使用megaparsec但它与 habitual 非常相似parsec):

但它不起作用。我尝试了很多方法,但无法与之抗争。

0 投票
0 回答
163 浏览

haskell - Megaparsec:没有由 do 语句引起的 (ErrorComponent Void) 实例

我正在尝试使用 megaparsec 编写一个简单的解析器并遇到以下问题:

我在线收到错误消息:满足 .... 那说:

没有由 do 语句产生的 (ErrorComponent Void) 实例在“do”块的 stmt 中:满足(notElem“!>”)

0 投票
2 回答
281 浏览

haskell - Haskell 中的类型解析:MegaParsec/ 解析单个空格

如果我查看它的文档space建议使用void spaceChar.

但是,如果我真的尝试:

我明白了

我认为表达式是正确的,但我需要做一些事情来说服类型检查器。我怎样才能让它工作?

0 投票
1 回答
884 浏览

parsing - 使用 Megaparsec 缩进

我想使用 Megaparsec 解析一种基本的缩进语言。最初我使用的是 Parsec,我设法通过缩进正常工作,但现在我遇到了一些麻烦。

我一直在这里学习教程这是我必须解析语言忽略缩进的代码。

运行此解析正确。

这是从这里的第二个教程解析缩进的代码。

我想作为一个正确解析的例子。

我怎样才能正确解析缩进?还有其他地方有关于使用 Megaparsec 的教程/文档吗?

0 投票
0 回答
104 浏览

haskell - 在Haskell中定义了一个类型类的名字后,函数后面的竖线是什么意思?

我正在查看megaparsec库并注意到一个类被定义为

我知道我正在创建一个名为 MonadParsec 的类型类,但究竟是什么| m -> e s意思?

0 投票
0 回答
329 浏览

parsing - Megaparsec:使用 try 时出现意外的输入消耗

我目前正在使用 megaparsec 库在 Haskell 中编写我的简单编程语言解析器。

我找到了这个megaparsec 教程,并编写了以下解析器代码:

具有保留名称错误处理的简单标识符解析器。它成功解析有效标识符,例如foo, bar123

但是当无效输入(又名保留名称)进入解析器时,它会输出错误:

其中,错误消息还可以,但是错误位置(1:3:)与我的预期有点不同。我预计错误位置是1:1:.

在定义的以下部分中identifier

如果失败并返回源位置,我预计try会表现得像没有消耗输入。(p >>= check)1:1:

我的期望错了吗?我怎样才能让这段代码按我的预期工作?

0 投票
0 回答
121 浏览

parsing - megaparsec 在解析错误时报告不正确的位置

对于这个项目,我分两个阶段进行解析。第一阶段处理 include/ifdef/define 指令并将输入分成[Span]项目,这些项目在原始输入中定义它们的起点/终点以及正文。然后第二阶段将此流解析为我的 AST 以进行后续处理。

AST 的每个元素都带有它的源位置,并且在解析后捕获的任何语义错误都会打印正确的错误位置,而不管包含深度如何。这部分至关重要,因为它出现在出现问题的阶段之后。

该问题在第二阶段从包含的文件中给出了一个解析错误,它报告了一个虚假错误,其位置位于输入的顶级规则中。初始文件中的解析错误可以正常工作。任何指令的存在甚至会将初始文件分成多个块,因此这不是“单个块”与“多个块”的问题。

鉴于 AST 正在获取正确的位置这一事实,我很难理解 Megaparsec 在遇到解析错误时如何报告错误信息。

我包含了我的流实例和 (set|get)(Position|Input) 代码,因为这些看起来像是相关的位。我觉得一定有一些我没有做的兆秒内务处理,或者我的 Stream 实例由于某种原因无效。

找到包含并交换它:

如果我们到达输入弹出堆栈的末尾并继续:

0 投票
0 回答
117 浏览

haskell - 通过延续传播(Mega)Parsec 错误

我对(Mega)Parsec 的内部运作有一个有点技术性的问题,其非正式的上下文是:

通过 continuation 控制错误消息的累积/传播的想法是什么Parsec

具体来说:考虑mplus制作ParsecT. MonadPlus( source ) mplus m n将要解析的字符串作为输入,并根据解析的结果s继续cok, cerr, eok, 和eerr跟随。

s首先解析m

  • 如果解析成功并消耗(分别不消耗)的一部分s,则遵循cok(分别eok)继续。
  • s如果在使用 的部分时with的解析m失败s,请cerr继续。
  • s假设with的解析m失败而没有消耗任何东西;让err成为与此失败相关的解析错误。s然后我们尝试用解析n,并相应地选择一个延续:
    • 如果在使用输入时解析swithn成功,请cok继续。
    • s如果使用输入时with的解析n失败,请cerr继续。
    • s如果with的解析成功而没有消耗输入,请遵循从 派生n的延续:neokeokneok y s' err' = eok y s' (mergeError err err')
    • s如果with的解析失败而没有消耗输入,请遵循从 派生n的延续:neerreerrneerr y s' err' = eerr (mergeError err err')

我的问题是:

为什么我们在跟随“空”延续而不是跟随“消耗”延续时合并错误,从而忘记所有先前的错误?

这一定是一个设计决定,但我无法弄清楚它背后的原因。也许有一个简单的例子可以澄清这一点?

0 投票
1 回答
901 浏览

parsing - 在算术表达式中解析表达式

我想解析算术表达式。

这是我当前的解析器:

使用它我可以正确解析:

像这样生成 AST。

我可以解析的另一件事是通用表达式。这些可以是变量、方法调用、三元组等。

例如

身份标识:

这会产生:

方法调用:

这会产生:

这是解析通用表达式的示例。

这很好用,但我也想在其中解析算术表达式。

这意味着使用expressionParserI 现在可以解析所有不同的表达式,包括算术表达式。如果它恰好是一个算术表达式,它会被包裹在AExprAsExpr.

问题

我想解析包含其他表达式的算术表达式。

例如

为此,我最初的想法是更改算术解析器,以便它也解析表达式。

问题在于aTerm调用表达式解析器时存在递归循环,表达式解析器调用aExpr. 这会导致无限循环。还有一个问题是所有identifiers现在都将被包裹在一个AExprAsExpr.

在算术表达式中解析表达式的正确方法是什么?

0 投票
1 回答
788 浏览

parsing - Haskell Parsec、MegaParsec 或 Happy 的简单 C 语法

我开发了一个预处理器,将 C 语句的子集转换为 gcc _asm 语句。对于这个项目,我很乐意重用使用任何流行的 Haskell 技术编写的现有 C 语句解析器,或者只是从一些简单的 C 子集解析器开始以避免重做现有工作。

不幸的是,到目前为止,我发现除了 C 之外的所有语法。虽然我可以从 Java/Go 的 Parsec 语法开始,但似乎 MegaParsec 是更好的选择?

我可以快速开发小的 C 子集的语法,但是对于较大的 C 子集的即用型语法将允许我完全跳过 C 语句解析器的开发,而专注于项目的核心 - asm 代码生成。

最终,它可能会变成 C++ 代码的 LLVM pass 转译部分,但为了快速原型,我更喜欢 Haskell,特别是如果我能找到现成的解析器。