【问题标题】:How to parse a formula from a string?如何从字符串中解析公式?
【发布时间】:2017-08-28 07:24:06
【问题描述】:

例如,我有字符串((data1 + data2) ^ data3) / data4,我希望我的小程序获取这个字符串并执行以下操作:

int main(int argc, char **argv) {

    double data1 = 1.0;
    double data2 = 2.0;
    double data3 = 3.0;
    double data4 = 4.0;

    double result = parse_formula("((data1 + data2) ^ data3) / data4");

    printf("Result is %d\n", result);
    return 0;
}

标准库中有这样的解析器吗?如果没有,我自己怎么做这样的解析器?

【问题讨论】:

  • 抱歉,parse_formula() 究竟做了什么无法以通常方式完成的事情?
  • @SouravGhosh 他正在寻找一个库来将函数解析为一个值。
  • @Chris 先生类似于double result = ((data1 + data2) ^ data3) / data4 还是我错过了什么?
  • @SouravGhosh 想象一下,如果在运行时输入了公式字符串。

标签: c parsing


【解决方案1】:

标准库中没有现成的用于解析表达式的东西,没有。但是,自己滚动解析器/评估器是一个很好的练习。我不想破坏乐趣,但这里有一些想法:

这个想法是首先将输入字符串解析为某种表示表达式的数据结构(通常是某种树结构),然后使用一些给定的变量绑定“评估”该数据结构。

数据结构可能是tagged union,类似于:

enum ValueType {
 ConstantValue, VariableValue, Addition, Division
};

struct Value {
  enum ValueType type;

  /* The 'representation' of the value. */
  union {
     int constantValue;
     const char *variableValue;
     struct {
       struct Value *summand1;
       struct Value *summand2;
     } additionValue;
     struct {
       struct Value *dividend;
       struct Value *divisor;
     } divisionValue;
  } repr;
};

对于解析部分,我建议阅读“递归下降”解析器,该区域很容易理解和手写。目标是定义一个函数

Value *parse( const char *s );

返回给定字符串的表示。

求值部分非常简单,适合递归。目标是定义一个函数

int eval( const Value *v, ??? bindings );

...其中??? 是适合保存变量绑定的某种类型(例如,到int 映射的字符串)。根据给定值的“类型”,它将执行算术运算,例如:

int eval( const Value *v, ??? bindings ) {
  switch ( v->type ) {
    case ConstantValue:
      return v->repr.constantValue;
    case Addition:
      return eval( v->repr.additionValue.summand1 ) + eval( v->repr.additionValue.summand2 );
    ...

【讨论】:

  • 我不认为这是正确的答案。该问题专门询问是否有可以解析和评估表达式的 C 库。提问者并没有问标准库里有没有东西,只是问有没有这样的库存在于任何地方。答案显然是肯定的。是的,通过实现自己的解析器和评估器可以学到很多东西,但这不是提问者所要求的。
  • @rhody 请注意,OP 还询问“或者自己编写代码的最佳方法是什么?”。但是,如果您想分享可能有用的库,请随时添加答案。
【解决方案2】:

标准库中没有这个功能,没有。

库有很多,这里不推荐一个。

请注意,没有库将允许通过名称“自动”访问程序变量;它们在运行时不可用。您必须找到一个支持变量的表达式求值器,并在尝试求值公式本身之前初始化求值器中的变量。

【讨论】:

    【解决方案3】:

    有很多可用的解析器,包括 C++ 和纯 C 语言。对于 C++,有 muParser:

    http://beltoforion.de/article.php?a=muparser&hl=en&s=idPageTop#idPageTop

    对于 C,我发现了这个看起来很有前途的小东西:

    https://github.com/codeplea/tinyexpr

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-03
      • 1970-01-01
      • 2018-09-07
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多