问题标签 [happy]
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 解析器生成器不匹配 - 快乐
我已经处理这个问题几天了,我没有想法,希望你能帮助我:
我的令牌列表如下:
我的语法规则如下:
它只是定义了一个变量列表,就像您在命令式编程语言中可能找到的任何变量一样(在这种给定的语言中,变量只能被分配整数):
我的词法分析器(文件的 Haskell 部分)具有以下数据类型:
这样,在解析之后,我可以获得所有声明的变量的列表,并使用数据“ArithmeticInt 0”进行初始化:
当我在提示符下运行“快乐”命令时,一切都很好:
但是当我在我的 GHCI 上加载生成的 .hs 文件时:
我收到一个广泛的错误,说 typeVariablesList
无法与 type 匹配[(String,ArithmeticExpression)]
。我知道,由于我进行了不同的测试,问题出在我的VariablesList
语法规则的第二种模式上:
确切地说是($2,ArithmeticInt 0):$4
部分。我对 Haskell 很陌生,我能理解的是第四个参数 ($4) 是类型VariablesList
,并且类型(String,ArithmeticExpression)
不能连接 (:) 到它。
非常欢迎任何形式的帮助或指导:)。
编辑:通过请愿,这是一个最小的工作快乐文件:
运行:
然后,在 GHCI 中,加载:
最后,测试一下:
或任何少于 3 个变量的列表。
parsing - 如何在没有令牌的情况下定义规则关联?
我有以下最小化语法
该Exp Exp
规则用于在值中应用函数。但是,如果我有类似的东西myFunc 1 2
默认为 precendence myFunc (1 2)
,这不是我想要的。我想要(myFunc 1) 2
,用于咖喱。
但是,如果我没有非终结符,我该如何定义关联呢?尝试做%left Exp
似乎没有帮助。
parsing - 使用 Parsec 解析复杂文件
我想用 Haskell 解析具有多个数据序列(相同的列数,相同的内容,...)的文件。我的数据序列将由前后的关键字分隔。
我的问题是,在使用 Parsec 进行了几次测试后,我的印象是 Parsec 宁可逐行解析文件,而不是整个文件。
Parsec是制作我想要的东西的正确方法,还是我应该考虑使用其他工具,如Happy或Alex?
是否有网站(或其他资源)提供使用Parsec解析复杂文本文件的示例?
注意:我给出的例子是一个非常简单的例子。在我的文件中有更多关键字和组合时,事情会更加棘手。
parsing - 在 Happy 项目中,“templates/wrappers.hs”在哪里?
我正在尝试使用 Alex 和 Happy 制作解析器。我正在按照这篇文章的说明进行操作,但遇到了麻烦。我正在尝试追查以下类型错误的来源:
我的词法分析器位于 src/AnsiParser/FrontEnd/Lex.x 中。所以我查看了 dist/build/AnsiParser/FrontEnd/Lex.hs,我能找到的只有:
但是我在我的系统上找不到任何名为“wrapper.hs”的文件。如何追踪此错误的原因?
如果它有用,这是我的 Parse.y 的简化版本:
和 Lex.x:
parsing - 是什么导致 Happy 抛出解析错误?
我已经用 Alex 编写了一个词法分析器,并且正在尝试将它连接到一个用 Happy 编写的解析器。我会尽力总结我的问题而不粘贴大量代码。
我从我的词法分析器的单元测试中知道该字符串"\x7"
被用于:
我的令牌类型(由词法分析器吐出)是Token
. 我已经定义lexWrap
并如此处alexEOF
所述,它为我提供了以下标头和令牌声明:
我使用以下命令调用 parser+lexer 组合:
这是我的前几部作品:
我将省略 和 的数据类型声明,Expr
因为NonPrint
它们很长,而且这里只有构造函数Cmd
和NonPrint
问题。该函数parseNonPrint
在 Parse.y 的底部定义为:
此外,我的错误处理函数如下所示:
像这样写,我希望通过以下 hspec 测试:
但相反,我看到"exprs 30"
print一次(即使我正在运行 5 个不同的单元测试)和我所有的parseExpr
return测试Right []
。我不明白为什么会这样,但我改变了exprs
生产以防止它:
现在我所有的测试在他们命中的第一个令牌上都失败了——parseExpr "\x7"
失败了:
而且我非常困惑,因为我希望解析器能够走上这条路exprs -> expr -> nonprint -> NONPRINT
并成功。我不明白为什么这个输入会使解析器处于错误状态。没有任何trace
语句被命中(优化掉了?)。
我究竟做错了什么?
haskell - 如何让 Stack 调用 Happy、Alex 和其他构建工具?
作为编译器的一部分,我需要alex
并happy
作为构建过程的一部分运行。Stack 如何支持这种情况?
奖励:我如何注册alex
并happy
作为编译时依赖项?
parsing - Happy 解析:左递归与右递归
Happy 用户手册第 2.2 节建议您使用左递归而不是右递归,因为右递归“效率低下”。基本上他们是说,如果您尝试解析一长串项目,右递归将溢出解析堆栈,而左递归使用常量堆栈。给出的典型例子是
不幸的是,这意味着项目列表是倒退的。
现在它很容易reverse
在最后应用(尽管您必须在调用解析器的任何地方都这样做,而不是在定义它的地方一次)。但是,如果项目列表很大,肯定reverse
也会溢出 Haskell 堆栈吗?不?
基本上,我该如何做才能解析任意大的文件并仍然以正确的顺序得到结果?
parsing - 快乐:这不是关键字
当你写一个快乐的描述时,你必须定义所有可能出现的令牌类型。但是您只能匹配令牌类型,而不是单个令牌值......
这有点问题。例如,考虑data
关键字。根据 Haskell 报告,这个令牌是一个“reservedid”。所以我的标记器识别它并标记它。但是,请考虑as
关键字。现在事实证明这不是一个reservedid;这是一个普通的变量。它仅在一种情况下是特殊的。您完全可以声明一个名为 的普通变量as
,这很好。
所以这里有一个问题:我如何as
具体解析?
起初我并没有真正考虑过。我刚刚定义了一个新的令牌类型,它代表文本恰好是的任何可变令牌as
。
...然后我花了大约 2 个小时试图弄清楚为什么我的语法实际上不起作用。是的,事实证明,由于此令牌类型与现有令牌类型重叠,因此声明顺序很重要。(!!!) 从字面上看,更改声明的顺序使语法解析完美。
但现在我很担心。我担心它as
永远不会被匹配为一个变量,只会匹配它自己。所以所有说 varid 的语法规则都会拒绝这个as
标记——这是完全错误的!
解决此问题的正确方法是什么?
parsing - 在 Happy 中定义规则别名
我正在阅读语言规范,并尝试为其编写解析器。在某些地方,规范对同一事物使用多个名称。我试图将其复制到快乐语法中,如下所示:
不幸的是,这导致 Happy 情绪失控,开始抱怨“减少/减少冲突”。基本上,问题似乎是当它看到 a 时foo
,它不知道是将其减少为 abar
还是 a baz
。事实当然是我不在乎,因为它们都是相同的。但这仍然让快乐感到不安——如果没有别的,这在语言上是具有讽刺意味的。
(我也有点害怕如果我有一个提到的规则bar
和另一个提到baz
的规则,如果选择了“错误”的归约,正确的规则可能无法触发。换句话说,解析器会出现 100% 的问题永远无法调试。)
有什么方法可以告诉Happy“无论我在哪里说bar
,就假装我说foo
,继续你的生活”?
显然我可以使用一些外部工具来进行文本查找和替换,但我真的更希望不必添加另一个构建步骤......
haskell - 在语义分析阶段获取行号信息(使用 Alex,Happy)
我正在为一种实验语言进行语义分析。我正在使用 Alex 和 Happy 来生成词法分析器和解析器(实际上我正在使用 BNFC 工具来生成 Alex 和 Happy 文件)。每当出现语义错误(例如类型错误)时,我都想收到带有行号和列号的错误消息。
似乎我必须在构建符号表或 AST 时存储行号信息。如果我能以某种方式访问 Happy 文件的规则部分中的位置信息,我的问题就会得到解决。
在这方面的任何建议将不胜感激。
我尝试实施下面建议的答案,但不幸的是没有取得任何成功。让我们考虑一个非常简单的语法:-
我的词法分析器如下所示。
我的 Yacc 文件如下,这就是我苦苦挣扎的地方。如何在我的语法树中嵌入位置信息。
尝试编译生成的 Haskell 文件时出现以下类型错误。
你们能建议我如何让这个东西工作吗?