2012-04-02 80 views
14

你能给我一些关于如何在C中创建一个简单的数学表达式解析器的想法吗?从字符串评估数学函数

用户在一个字符串和我想在C 比如建立一个功能串入一个数学函数。 x + sin(2*x)

- >return x + sin(2x);

在此先感谢。

+0

看一看野牛文件以外,还有[实例](http://www.gnu.org/software/bison/manual/html_node/Infix-Calc.html#Infix-Calc),它会引导你。 – 2012-04-02 13:11:00

+0

http://stackoverflow.com/questions/1151127/evaluating-mathematical-expressions,[什么是快速C或Objective-C数学解析器?]可能的重复(http://stackoverflow.com/questions/4892152/what -is-a-fast-c-or-objective-c-math-parser),http://stackoverflow.com/questions/5115872/what-is-the-best-way-to-evaluate-mathematical-expression- in-c/5117028#5117028,http://stackoverflow.com/questions/4071456/opensouce-cc-math-expression-parser-library/4071701#4071701,和其他几个。 – lhf 2012-04-02 13:35:23

+0

尝试[TinyExpr](https://github.com/codeplea/tinyexpr)。它在一个C源代码文件和头文件中。 – 131 2016-01-22 21:32:04

回答

6

您可以分析基于“调度场算法” http://en.wikipedia.org/wiki/Shunting-yard_algorithm表达。您将需要扩充以处理为正弦,余弦等函数调用等...

+0

+1的调车场。这是解决它可以处理的任务的正确方法(算法简单,没有堆栈溢出的风险)。 – 2012-04-02 14:19:21

1

一种方式做到这一点是要使用的表达逆波兰表示法以及用于操作数堆栈。 一些快速的伪代码:

if element is operand 
    push in stack 
else if element is operation 
    pop last 2 elements 
    perform operation 
    push result in stack 

重复,直到表达式结束。最终结果是堆栈中唯一的元素。

3

这不是一件简单的事情,面对面,这是一件很难的事情。您需要一个完整的语法分析器,并结合预定义的常量/函数(sin,log,pi等)。

如果你有CI没有广泛以往的经验将disrecommend这样做,但如果你真的想在recursive descent parsing做到这一点看看这无疑是做到这一点(不把负担对用户最简单的方法,如逆波兰符号)。

最后但并非最不重要的是,你说你想从用户生成的输入创建一个C函数。这几乎总是一件错误的事情 - 从用户输入生成代码,而最简单的方法是预处理创建可以高效执行的中间表示。

+0

我会在你应该研究[BNF(Backus-Naur Form)](http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form)裁决 – Eregrith 2012-04-02 13:11:25

+0

我会第二,这不是一个简单的事情要做。这并不可怕,实际上它非常优雅,但绝非简单。递归下降是最简单的方法,运营商的优先级更高,但相当复杂 – 2012-04-02 13:13:40

0

写一个表达式解析器和评估器使用时讨论解析器的写作手法通常的例子之一。 例如,您可以查看flex/bison或lex/yacc的文档。这将有构造解析器/表达式评估器的例子。