2016-05-17 03:04:11 +12:00
|
|
|
#pragma once
|
|
|
|
|
2016-03-19 06:57:51 +13:00
|
|
|
#ifndef TGRAMMAR_INCLUDED
|
|
|
|
#define TGRAMMAR_INCLUDED
|
|
|
|
|
2016-04-14 22:15:09 +12:00
|
|
|
#include <memory>
|
|
|
|
|
2016-03-19 06:57:51 +13:00
|
|
|
// TnzCore includes
|
|
|
|
#include "tcommon.h"
|
|
|
|
|
|
|
|
// TnzBase includes
|
|
|
|
#include "ttokenizer.h"
|
|
|
|
|
|
|
|
#undef DVAPI
|
|
|
|
#undef DVVAR
|
|
|
|
#ifdef TNZBASE_EXPORTS
|
|
|
|
#define DVAPI DV_EXPORT_API
|
|
|
|
#define DVVAR DV_EXPORT_VAR
|
|
|
|
#else
|
|
|
|
#define DVAPI DV_IMPORT_API
|
|
|
|
#define DVVAR DV_IMPORT_VAR
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//==============================================
|
|
|
|
|
|
|
|
// Forward declarations
|
|
|
|
|
|
|
|
class TDoubleParam;
|
|
|
|
class TUnit;
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
namespace TSyntax {
|
2016-03-19 06:57:51 +13:00
|
|
|
class Token;
|
|
|
|
class Calculator;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
// Calculator & calculator nodes
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
namespace TSyntax {
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
class DVAPI CalculatorNodeVisitor {
|
2016-03-19 06:57:51 +13:00
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
CalculatorNodeVisitor() {}
|
|
|
|
virtual ~CalculatorNodeVisitor() {}
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
class DVAPI CalculatorNode {
|
|
|
|
Calculator *m_calculator;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
CalculatorNode(Calculator *calculator) : m_calculator(calculator) {}
|
|
|
|
virtual ~CalculatorNode() {}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
Calculator *getCalculator() const { return m_calculator; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
enum { T, FRAME, RFRAME };
|
|
|
|
virtual double compute(double vars[3]) const = 0;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
virtual void accept(CalculatorNodeVisitor &visitor) = 0;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
// Non-copyable
|
|
|
|
CalculatorNode(const CalculatorNode &);
|
|
|
|
CalculatorNode &operator=(const CalculatorNode &);
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
class DVAPI Calculator {
|
|
|
|
CalculatorNode *m_rootNode; //!< (owned) Root calculator node
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
TDoubleParam *m_param; //!< (not owned) Owner of the calculator object
|
|
|
|
const TUnit *m_unit; //!< (not owned)
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
Calculator();
|
|
|
|
virtual ~Calculator();
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void setRootNode(CalculatorNode *node);
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
double compute(double t, double frame, double rframe) {
|
|
|
|
double vars[3];
|
|
|
|
vars[0] = t, vars[1] = frame, vars[2] = rframe;
|
|
|
|
return m_rootNode->compute(vars);
|
|
|
|
}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void accept(CalculatorNodeVisitor &visitor) { m_rootNode->accept(visitor); }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
typedef double Calculator::*Variable;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void setOwnerParameter(TDoubleParam *param) { m_param = param; }
|
|
|
|
TDoubleParam *getOwnerParameter() const { return m_param; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
const TUnit *getUnit() const { return m_unit; }
|
|
|
|
void setUnit(const TUnit *unit) { m_unit = unit; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
// not copyable
|
|
|
|
Calculator(const Calculator &);
|
|
|
|
Calculator &operator=(const Calculator &);
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
|
2016-06-29 18:17:12 +12:00
|
|
|
class DVAPI NumberNode final : public CalculatorNode {
|
2016-06-15 18:43:10 +12:00
|
|
|
double m_value;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
NumberNode(Calculator *calc, double value)
|
|
|
|
: CalculatorNode(calc), m_value(value) {}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-19 20:06:29 +12:00
|
|
|
double compute(double vars[3]) const override { return m_value; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-19 20:06:29 +12:00
|
|
|
void accept(CalculatorNodeVisitor &visitor) override {}
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
|
2016-06-29 18:17:12 +12:00
|
|
|
class DVAPI VariableNode final : public CalculatorNode {
|
2016-06-15 18:43:10 +12:00
|
|
|
int m_varIdx;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
VariableNode(Calculator *calc, int varIdx)
|
|
|
|
: CalculatorNode(calc), m_varIdx(varIdx) {}
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-19 20:06:29 +12:00
|
|
|
double compute(double vars[3]) const override { return vars[m_varIdx]; }
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-19 20:06:29 +12:00
|
|
|
void accept(CalculatorNodeVisitor &visitor) override {}
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
// Pattern
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
|
|
|
|
enum TokenType {
|
2016-06-15 18:43:10 +12:00
|
|
|
Unknown = 0,
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
Number,
|
|
|
|
Constant,
|
|
|
|
Variable,
|
|
|
|
Operator,
|
|
|
|
Parenthesis,
|
|
|
|
Function,
|
|
|
|
Comma,
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
UnexpectedToken = -100,
|
|
|
|
Eos,
|
|
|
|
Mismatch,
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
InternalError = -200
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
class DVAPI Pattern {
|
|
|
|
std::string m_description;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
Pattern() {}
|
|
|
|
virtual ~Pattern() {}
|
|
|
|
|
|
|
|
virtual std::string getFirstKeyword() const { return ""; }
|
|
|
|
virtual void getAcceptableKeywords(std::vector<std::string> &keywords) const {
|
|
|
|
}
|
|
|
|
virtual int getPriority() const { return 0; }
|
|
|
|
virtual bool expressionExpected(
|
|
|
|
const std::vector<Token> &previousTokens) const {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
virtual bool matchToken(const std::vector<Token> &previousTokens,
|
|
|
|
const Token &token) const = 0;
|
|
|
|
virtual bool isFinished(const std::vector<Token> &previousTokens,
|
|
|
|
const Token &token) const = 0;
|
|
|
|
virtual bool isComplete(const std::vector<Token> &previousTokens,
|
|
|
|
const Token &token) const {
|
|
|
|
return isFinished(previousTokens, token);
|
|
|
|
}
|
|
|
|
virtual TokenType getTokenType(
|
|
|
|
const std::vector<Token> &previousTokens,
|
|
|
|
const Token &token) const = 0; // see also SyntaxToken in tparser.h
|
|
|
|
|
|
|
|
virtual void createNode(Calculator *calc,
|
|
|
|
std::vector<CalculatorNode *> &stack,
|
|
|
|
const std::vector<Token> &tokens) const = 0;
|
|
|
|
|
|
|
|
std::string getDescription() const { return m_description; }
|
|
|
|
void setDescription(std::string description) { m_description = description; }
|
|
|
|
|
|
|
|
// helper methods
|
|
|
|
CalculatorNode *popNode(std::vector<CalculatorNode *> &stack) const;
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
class DVAPI Grammar {
|
|
|
|
class Imp;
|
|
|
|
std::unique_ptr<Imp> m_imp;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
public:
|
2016-06-15 18:43:10 +12:00
|
|
|
Grammar();
|
|
|
|
~Grammar();
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
void addPattern(Pattern *pattern); // take ownership
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
enum Position { ExpressionStart, ExpressionEnd };
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// note: returns a matching pattern (or 0 if no pattern matches)
|
|
|
|
const Pattern *getPattern(Position position, const Token &token) const;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
// returns matching <keywords, comment>
|
|
|
|
typedef std::vector<std::pair<std::string, std::string>> Suggestions;
|
|
|
|
void getSuggestions(Suggestions &suggetsions, Position position) const;
|
2016-03-19 06:57:51 +13:00
|
|
|
|
|
|
|
private:
|
2016-06-15 18:43:10 +12:00
|
|
|
// not implemented
|
|
|
|
Grammar(const Grammar &);
|
|
|
|
Grammar &operator=(const Grammar &);
|
2016-03-19 06:57:51 +13:00
|
|
|
};
|
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
} // namespace TSyntax
|
2016-03-19 06:57:51 +13:00
|
|
|
|
2016-06-15 18:43:10 +12:00
|
|
|
#endif // TGRAMMAR_INCLUDED
|