// FormulaCalculator.h
#ifndef FORMULACALCULATOR_H
#define FORMULACALCULATOR_H
#include <QString>
#include <QMap>
#include <QVector>
#include <functional>
#include <memory>
// Класс лексемы
class Token {
public:
enum class Type {
NUMBER,
VARIABLE,
OPERATOR,
FUNCTION,
PARENTHESIS,
COMMAND,
SPECIAL
};
Token(Type type, const QString& value);
Type getType() const;
QString getValue() const;
private:
Type m_type;
QString m_value;
};
// Класс для хранения результата
class CalculationResult {
public:
CalculationResult(double value = 0.0, const QString& table = QString());
double getValue() const;
QString getTable() const;
bool hasTable() const;
private:
double m_value;
QString m_table;
};
// Основной класс калькулятора (реализует Dependency)
class FormulaCalculator {
public:
FormulaCalculator();
~FormulaCalculator();
// Основные методы
CalculationResult parseAndCalculate(const QString& formula);
// Работа с переменными
void setVariable(const QString& name, double value);
double getVariable(const QString& name) const;
bool hasVariable(const QString& name) const;
QMap<QString, double> getAllVariables() const;
void clearVariables();
// Определение типов символов
bool isNumber(const QString& token) const;
bool isVariable(const QString& token) const;
bool isOperator(const QString& token) const;
bool isFunction(const QString& token) const;
bool isCommand(const QString& token) const;
bool isSpecialSymbol(const QChar& ch) const;
private:
// Зависимости (вариант 4 - Dependency)
std::unique_ptr<QMap<QString, double>> m_variables;
std::unique_ptr<QMap<QString, std::function<double(double)>>> m_functions;
std::unique_ptr<QMap<QString, std::function<double(double, double)>>> m_binaryOperators;
// Лексический анализ
QVector<Token> tokenize(const QString& formula);
// Парсинг и вычисление
double evaluate(const QVector<Token>& tokens, CalculationResult& result);
double parseExpression(const QVector<Token>& tokens, int& pos);
double parseTerm(const QVector<Token>& tokens, int& pos);
double parseFactor(const QVector<Token>& tokens, int& pos);
// Вспомогательные методы
double applyFunction(const QString& funcName, double arg);
double applyOperator(const QString& op, double left, double right);
int getPrecedence(const QString& op) const;
bool isRightAssociative(const QString& op) const;
// Генерация таблицы значений
QString generateTable(const QString& formula, const QString& variable,
double start, double end, int steps);
};
#endif // FORMULACALCULATOR_H