2015-02-11 2 views
2

Например, у меня есть строка ((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; 
} 

Есть такой анализатор в стандартной библиотеке? Если нет, как бы я сам сделал такой парсер?

+0

Извините, но что точно выполняются 'parse_formula()', которые не могут быть выполнены _usual_ способом? –

+0

@SouravGhosh он ищет библиотеку для синтаксического анализа функции до значения. – Hristo

+0

Mr @Chris что-то вроде 'double result = ((data1 + data2)^data3)/data4' или я что-то упускаю? –

ответ

3

Нет ничего готового в стандартной библиотеке для разбора выражений, нет. Тем не менее, это отличное упражнение для того, чтобы самостоятельно развернуть анализатор/оценщик. Я не хочу испортить веселье, но вот несколько мыслей:

Идея состоит в том, чтобы сначала разобрать входную строку в какую-то структуру данных, которая представляет выражение (обычно какую-то древовидную структуру), а затем " оценить "эту структуру данных с некоторыми заданными привязками переменных.

Структура данных может быть 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); 
    ... 
+0

Я не считаю это правильным ответом. Вопрос был задан вопросом, есть ли библиотека C, которая могла бы анализировать и оценивать выражение. Вопроситель не спросил, есть ли что-то в стандартной библиотеке, просто ли такая библиотека существует где угодно. Ответ, очевидно, да. Да, вы можете многому научиться, внедряя свой собственный синтаксический анализатор и оценщик, но это не то, о чем спрашивал вопрошающий. – rhody

+0

@rhody Обратите внимание, что OP также спросил: «Или что это лучший способ закодировать его сам?». Однако, если вы хотите поделиться библиотеками, которые могут быть полезны, не стесняйтесь добавлять ответ. –

+0

Я стою исправленный, ты прав. – rhody

2

В стандартной библиотеке такой функции нет, нет.

Существует множество библиотек, и я не буду рекомендовать их здесь.

Обратите внимание: никакая библиотека не позволит «автоматическому» доступу по имени к вашим переменным вашей программы; они недоступны во время выполнения. Вам нужно будет найти оценщика выражений с поддержкой переменных и инициализировать переменные в оценочном устройстве, прежде чем пытаться оценить формулу.

Смежные вопросы