所以我一直在尝试用 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 解析器。如果你知道另一种方法,请告诉我!