1 #pragma once
2 
3 #ifndef TGRAMMAR_INCLUDED
4 #define TGRAMMAR_INCLUDED
5 
6 #include <memory>
7 
8 // TnzCore includes
9 #include "tcommon.h"
10 
11 // TnzBase includes
12 #include "ttokenizer.h"
13 
14 #undef DVAPI
15 #undef DVVAR
16 #ifdef TNZBASE_EXPORTS
17 #define DVAPI DV_EXPORT_API
18 #define DVVAR DV_EXPORT_VAR
19 #else
20 #define DVAPI DV_IMPORT_API
21 #define DVVAR DV_IMPORT_VAR
22 #endif
23 
24 //==============================================
25 
26 //    Forward declarations
27 
28 class TDoubleParam;
29 class TUnit;
30 
31 namespace TSyntax {
32 class Token;
33 class Calculator;
34 }  // namespace TSyntax
35 
36 //==============================================
37 
38 //-------------------------------------------------------------------
39 // Calculator & calculator nodes
40 //-------------------------------------------------------------------
41 
42 namespace TSyntax {
43 
44 class DVAPI CalculatorNodeVisitor {
45 public:
CalculatorNodeVisitor()46   CalculatorNodeVisitor() {}
~CalculatorNodeVisitor()47   virtual ~CalculatorNodeVisitor() {}
48 };
49 
50 //-------------------------------------------------------------------
51 
52 class DVAPI CalculatorNode {
53   Calculator *m_calculator;
54 
55 public:
CalculatorNode(Calculator * calculator)56   CalculatorNode(Calculator *calculator) : m_calculator(calculator) {}
~CalculatorNode()57   virtual ~CalculatorNode() {}
58 
getCalculator()59   Calculator *getCalculator() const { return m_calculator; }
60 
61   enum { T, FRAME, RFRAME };
62   virtual double compute(double vars[3]) const = 0;
63 
64   virtual void accept(CalculatorNodeVisitor &visitor) = 0;
65 
hasReference()66   virtual bool hasReference() const { return false; }
67 
68 private:
69   // Non-copyable
70   CalculatorNode(const CalculatorNode &);
71   CalculatorNode &operator=(const CalculatorNode &);
72 };
73 
74 //-------------------------------------------------------------------
75 
76 class DVAPI Calculator {
77   CalculatorNode *m_rootNode;  //!< (owned) Root calculator node
78 
79   TDoubleParam *m_param;  //!< (not owned) Owner of the calculator object
80   const TUnit *m_unit;    //!< (not owned)
81 
82 public:
83   Calculator();
84   virtual ~Calculator();
85 
86   void setRootNode(CalculatorNode *node);
87 
compute(double t,double frame,double rframe)88   double compute(double t, double frame, double rframe) {
89     double vars[3];
90     vars[0] = t, vars[1] = frame, vars[2] = rframe;
91     return m_rootNode->compute(vars);
92   }
93 
accept(CalculatorNodeVisitor & visitor)94   void accept(CalculatorNodeVisitor &visitor) { m_rootNode->accept(visitor); }
95 
96   typedef double Calculator::*Variable;
97 
setOwnerParameter(TDoubleParam * param)98   void setOwnerParameter(TDoubleParam *param) { m_param = param; }
getOwnerParameter()99   TDoubleParam *getOwnerParameter() const { return m_param; }
100 
getUnit()101   const TUnit *getUnit() const { return m_unit; }
setUnit(const TUnit * unit)102   void setUnit(const TUnit *unit) { m_unit = unit; }
103 
104 private:
105   // not copyable
106   Calculator(const Calculator &);
107   Calculator &operator=(const Calculator &);
108 };
109 
110 //-------------------------------------------------------------------
111 
112 class DVAPI NumberNode final : public CalculatorNode {
113   double m_value;
114 
115 public:
NumberNode(Calculator * calc,double value)116   NumberNode(Calculator *calc, double value)
117       : CalculatorNode(calc), m_value(value) {}
118 
compute(double vars[3])119   double compute(double vars[3]) const override { return m_value; }
120 
accept(CalculatorNodeVisitor & visitor)121   void accept(CalculatorNodeVisitor &visitor) override {}
122 };
123 
124 //-------------------------------------------------------------------
125 
126 class DVAPI VariableNode final : public CalculatorNode {
127   int m_varIdx;
128 
129 public:
VariableNode(Calculator * calc,int varIdx)130   VariableNode(Calculator *calc, int varIdx)
131       : CalculatorNode(calc), m_varIdx(varIdx) {}
132 
compute(double vars[3])133   double compute(double vars[3]) const override { return vars[m_varIdx]; }
134 
accept(CalculatorNodeVisitor & visitor)135   void accept(CalculatorNodeVisitor &visitor) override {}
136 };
137 
138 //-------------------------------------------------------------------
139 // Pattern
140 //-------------------------------------------------------------------
141 
142 enum TokenType {
143   Unknown = 0,
144 
145   Number,
146   Constant,
147   Variable,
148   Operator,
149   Parenthesis,
150   Function,
151   Comma,
152 
153   UnexpectedToken = -100,
154   Eos,
155   Mismatch,
156 
157   InternalError = -200
158 };
159 
160 //-------------------------------------------------------------------
161 
162 class DVAPI Pattern {
163   std::string m_description;
164 
165 public:
Pattern()166   Pattern() {}
~Pattern()167   virtual ~Pattern() {}
168 
getFirstKeyword()169   virtual std::string getFirstKeyword() const { return ""; }
getAcceptableKeywords(std::vector<std::string> & keywords)170   virtual void getAcceptableKeywords(std::vector<std::string> &keywords) const {
171   }
getPriority()172   virtual int getPriority() const { return 0; }
expressionExpected(const std::vector<Token> & previousTokens)173   virtual bool expressionExpected(
174       const std::vector<Token> &previousTokens) const {
175     return false;
176   }
177   virtual bool matchToken(const std::vector<Token> &previousTokens,
178                           const Token &token) const = 0;
179   virtual bool isFinished(const std::vector<Token> &previousTokens,
180                           const Token &token) const = 0;
isComplete(const std::vector<Token> & previousTokens,const Token & token)181   virtual bool isComplete(const std::vector<Token> &previousTokens,
182                           const Token &token) const {
183     return isFinished(previousTokens, token);
184   }
185   virtual TokenType getTokenType(
186       const std::vector<Token> &previousTokens,
187       const Token &token) const = 0;  // see also SyntaxToken in tparser.h
188 
189   virtual void createNode(Calculator *calc,
190                           std::vector<CalculatorNode *> &stack,
191                           const std::vector<Token> &tokens) const = 0;
192 
getDescription()193   std::string getDescription() const { return m_description; }
setDescription(std::string description)194   void setDescription(std::string description) { m_description = description; }
195 
196   // helper methods
197   CalculatorNode *popNode(std::vector<CalculatorNode *> &stack) const;
198 };
199 
200 //-------------------------------------------------------------------
201 
202 class DVAPI Grammar {
203   class Imp;
204   std::unique_ptr<Imp> m_imp;
205 
206 public:
207   Grammar();
208   ~Grammar();
209 
210   void addPattern(Pattern *pattern);  // take ownership
211 
212   enum Position { ExpressionStart, ExpressionEnd };
213 
214   // note: returns a matching pattern (or 0 if no pattern matches)
215   const Pattern *getPattern(Position position, const Token &token) const;
216 
217   // returns matching <keywords, comment>
218   typedef std::vector<std::pair<std::string, std::string>> Suggestions;
219   void getSuggestions(Suggestions &suggetsions, Position position) const;
220 
221 private:
222   // not implemented
223   Grammar(const Grammar &);
224   Grammar &operator=(const Grammar &);
225 };
226 
227 }  // namespace TSyntax
228 
229 #endif  // TGRAMMAR_INCLUDED
230