【发布时间】:2012-06-07 23:57:19
【问题描述】:
所以我一直在尝试用 Scala 的解析器编写一个计算器,这很有趣,除了我发现运算符关联性是倒退的,而且当我尝试让我的语法左递归时,即使它是完全明确的,我得到一个堆栈溢出。
澄清一下,如果我有这样的规则: def 减法:Parser[Int] = num ~ "-" ~ add { x => x._1._1 - x._2 } 然后评估 7 - 4 - 3 的结果是 6 而不是 0。
我实际实现的方式是我正在组成一个二叉树,其中运算符是非叶节点,叶节点是数字。我评估树的方式是左孩子(运算符)右孩子。在为 7 - 4 - 5 构建树时,我希望它看起来像:
-
- 5
7 4 NULL NULL
其中 - 是根,它的子节点是 - 和 5,第二个 - 的子节点是 7 和 4。
但是,我唯一可以轻松构建的树是
-
7 -
NULL NULL 4 5
这是不同的,不是我想要的。
基本上,简单的括号是 7 - (4 - 5) 而我想要 (7 - 4) - 5。
我怎样才能破解这个?我觉得无论如何我都应该能够编写一个具有正确运算符优先级的计算器。我应该先对所有内容进行标记,然后再反转我的标记吗?我可以通过取右孩子的所有左孩子并使他们成为右孩子父母的右孩子并使父母成为前右孩子的左孩子来翻转我的树吗?它似乎很适合第一个近似值,但我并没有真正考虑过它。我觉得一定有一些我失踪的案例。
我的印象是我只能用 scala 解析器制作 LL 解析器。如果你知道另一种方法,请告诉我!
【问题讨论】:
-
请更具体地说明您所说的“运算符关联性是向后的”。
-
顺便说一句,结帐scala-dist 以获取更多示例——我只是使用该链接编辑我的答案。
标签: parsing scala operators context-free-grammar ll