Мы хотели бы, чтобы в нашей программе на C ++ были пользовательские формулы. например Значение v = x + (y - (z - 2)) / 2. Позже в программе пользователь определит x, y и z -> программа должна вернуть результат вычисления.
Когда-нибудь позже формула может измениться, поэтому в следующий раз программа должна проанализировать формулу и добавить новые значения.
Есть идеи / подсказки, как сделать что-то подобное?
Пока я просто пришел к решению написать парсер для вычисления этих формул - может быть, есть идеи по этому поводу?
вычисление пользовательских формул (с C ++)
Ответы (8)
Если он будет часто использоваться и будет расширяться в будущем, я почти рекомендую добавить в ваш код Python или Lua. Lua - это очень легкий язык сценариев, к которому вы можете подключиться и предоставить новые функции, операторы и т. д. вместо этого используйте Python, чтобы делать более надежные и сложные вещи.
Вы можете представить свою формулу в виде дерева операций и подвыражений. Вы можете определить типы или константы для типов операций и переменных.
Затем вы можете достаточно легко написать метод, который рекурсивно проходит по дереву, применяя соответствующие операции к любым значениям, которые вы передаете.
Создание собственного парсера для этого должно быть простой операцией:
) преобразовать уравнение из инфиксной в постфиксную нотацию (типичное присваивание compsci) (я бы использовал стек)) ждать, чтобы получить нужные значения) вставлять стек элементов инфикса, удаляя значение переменной там, где это необходимо) отображение Результаты
Использование Spirit (например) для синтаксического анализа (и «семантических действий», которые он предоставляет для построения дерева выражений, которое вы можете затем манипулировать, например оценивать) кажется довольно простым решением. Вы можете найти грамматику для арифметических выражений там, например, если нужен ... (его довольно просто придумать).
Примечание: Spirit очень прост в освоении и вполне приспособлен для таких задач.
Обычно есть два способа сделать это с тремя возможными реализациями:
- как вы уже упоминали, библиотека для оценки формул
- компиляция формулы в код
Второй вариант здесь обычно выполняется либо путем компиляции чего-то, что может быть загружено как своего рода плагин, либо его можно скомпилировать в отдельную программу, которая затем вызывается и производит необходимый вывод.
Что касается C ++, я бы предположил, что библиотека для оценки, вероятно, где-то существует, так что я бы начал с этого.
Если вы хотите написать свой собственный, ищите «формальные автоматы» и / или «грамматику конечных автоматов».
Как правило, вы будете анализировать строку, помещая символы в стек по мере продвижения. Затем начните выталкивать персонажей и выполнять задания на основе того, что появляется. Кодировать будет проще, если заставить уравнения отшлифовать нотацию в обратном порядке.
Чтобы облегчить вам жизнь, я думаю, что получение такого рода ввода лучше всего делать через графический интерфейс, где пользователи ограничены в том, что они могут вводить.
Если вы планируете делать это из командной строки (такое впечатление, которое я получил от вашего сообщения), вам, вероятно, следует определить строгий набор допустимых входных данных (например, только однобуквенные переменные, без пробелов и только определенные математические символы: ( ) + - * / и т. д.).
Затем вам нужно будет:
Прочитать входной массив символов;
проанализировать его, чтобы создать список переменных и действий; • Выполнить эти действия - в заказ BOMDAS
С помощью ANTLR вы можете создать синтаксический анализатор / компилятор, который будет интерпретировать ввод пользователя, а затем выполнять вычисления с использованием шаблона посетителя. . Хороший пример здесь, но он написан на C #. Вы сможете быстро адаптировать его к своим потребностям и по-прежнему использовать C ++ в качестве платформы разработки.