我想要完成的事情是:
a)我想学习它 - 这次是关于我的自我,这是一个有趣的项目,我想向自己展示我是非常擅长这些东西
b)我对EBNF知之甚少(虽然我还不知道,运营商优先级如何在EBNF中运行 - Irony.NET做得对,我查看了这些例子,但这对我来说有点不祥)
c)我的解析器应该可以这样:5 *(3 +(2 - 9 *(5/7))+ 9)例如,给我正确的结果
d)坦率地说,这似乎是为我编写编译器甚至是解释器的最大问题。我甚至可以生成64位汇编代码(我可以手动编写汇编程序),但公式解析器...
e)另一个想法:即使是简单的计算机(就像我的旧款Sharp 1246S只有大约2kB的RAM)也可以做到这一点......它不会那么难,对吧?甚至非常非常古老的编程语言都有公式评估...... BASIC是从1964年开始的,它们已经可以计算出我所提出的公式类型 f)一些想法,一些灵感就足够了 - 我根本不知道如何做运算符优先级和括号 - 但是,我知道它涉及AST并且很多人使用堆栈< / p>那么,您怎么看?
答案 0 :(得分:5)
您应该了解Recursive Descent parsers。
通过以下10种不同的方式查看Code Golf练习:
Code Golf: Mathematical expression evaluator (that respects PEMDAS)
这些“高尔夫”解决方案中的一些是以不同方式编码的递归下降解析器。
你会发现只做表达式解析是编译器中最简单的事情。解析语言的其余部分比较困难,但理解代码元素如何交互以及如何生成良好的代码要困难得多。
您可能还对如何使用BNF表达解析器感兴趣,以及如何使用该BNF执行某些操作。这里的 具有显式BNF和隐式AST作为基础的example of how to parse and manipulate algebra symbolically。这不是编译器传统上所做的,但其所做的机制深深植根于编译器技术。
答案 1 :(得分:1)
传统上,计算机上的公式处理器使用POSTFIX表示法。他们使用堆栈,弹出2个项目作为操作数,弹出第三个项目作为操作符,然后推送结果。
你想要的是一个INFIX到POSTFIX表示法转换器,这真的很简单。一旦你进行后缀处理是你做过的最简单的事情。
答案 2 :(得分:1)
对于在PHP中实现的基于堆栈的解析器,它使用Djikstra的分流码算法将中缀转换为后缀表示法,并且支持具有不同数量参数的函数,您可以查看PHPExcel计算的源代码发动机
答案 3 :(得分:0)
如果你想寻找一个现有的解决方案,我可以推荐一个工作,PSR-0兼容的分流码算法实现:https://github.com/andig/php-shunting-yard/tree/dev。