如何从字符串中解析公式?
How to parse a formula from a string?
例如,我有字符串 ((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;
}
标准库中有这样的解析器吗?如果没有,我如何自己制作这样的解析器?
标准库中没有这个函数,没有。
有很多库,我不打算在这里推荐一个。
请注意,任何库都不允许 "automatic" 通过名称访问您程序的变量;它们在运行时不可用。您将不得不找到一个支持变量的表达式计算器,并在尝试计算公式本身之前在计算器中初始化变量。
标准库中没有现成的解析表达式的东西,没有。但是,自己滚动 parser/evaluator 是一个很好的练习。我不想破坏乐趣,但这里有一些想法:
想法是首先将输入字符串解析为某种表示表达式的数据结构(通常是某种树结构),然后 'evaluate' 该数据结构具有一些给定的变量绑定。
数据结构可能是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;
};
对于解析部分,我建议阅读 'recursive descent' 解析器,这部分很容易理解和手写。目标是定义一个函数
Value *parse( const char *s );
其中 returns 给定字符串的表示形式。
评估部分非常简单,适合递归。目标是定义一个函数
int eval( const Value *v, ??? bindings );
...其中 ???
是适合保存变量绑定的某种类型(例如,到 int
映射的字符串)。根据给定值的'type'进行算术运算,例如:
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++ 和普通 C。对于 C++,有 muParser:
http://beltoforion.de/article.php?a=muparser&hl=en&s=idPageTop#idPageTop
对于 C,我发现了这个看起来很有前途的小东西:
例如,我有字符串 ((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;
}
标准库中有这样的解析器吗?如果没有,我如何自己制作这样的解析器?
标准库中没有这个函数,没有。
有很多库,我不打算在这里推荐一个。
请注意,任何库都不允许 "automatic" 通过名称访问您程序的变量;它们在运行时不可用。您将不得不找到一个支持变量的表达式计算器,并在尝试计算公式本身之前在计算器中初始化变量。
标准库中没有现成的解析表达式的东西,没有。但是,自己滚动 parser/evaluator 是一个很好的练习。我不想破坏乐趣,但这里有一些想法:
想法是首先将输入字符串解析为某种表示表达式的数据结构(通常是某种树结构),然后 'evaluate' 该数据结构具有一些给定的变量绑定。
数据结构可能是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;
};
对于解析部分,我建议阅读 'recursive descent' 解析器,这部分很容易理解和手写。目标是定义一个函数
Value *parse( const char *s );
其中 returns 给定字符串的表示形式。
评估部分非常简单,适合递归。目标是定义一个函数
int eval( const Value *v, ??? bindings );
...其中 ???
是适合保存变量绑定的某种类型(例如,到 int
映射的字符串)。根据给定值的'type'进行算术运算,例如:
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++ 和普通 C。对于 C++,有 muParser:
http://beltoforion.de/article.php?a=muparser&hl=en&s=idPageTop#idPageTop
对于 C,我发现了这个看起来很有前途的小东西: