My Project
 All Classes Functions Variables Pages
fparser.hh
1 /***************************************************************************\
2 |* Function Parser for C++ v4.4.3 *|
3 |*-------------------------------------------------------------------------*|
4 |* Copyright: Juha Nieminen, Joel Yliluoma *|
5 |* *|
6 |* This library is distributed under the terms of the *|
7 |* GNU Lesser General Public License version 3. *|
8 |* (See lgpl.txt and gpl.txt for the license text.) *|
9 \***************************************************************************/
10 
11 #ifndef ONCE_FPARSER_H_
12 #define ONCE_FPARSER_H_
13 
14 #include <string>
15 #include <vector>
16 
17 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
18 #include <iostream>
19 #endif
20 
21 #ifdef _MSC_VER
22 // Visual Studio's warning about missing definitions for the explicit
23 // FunctionParserBase instantiations is irrelevant here.
24 #pragma warning(disable : 4661)
25 #endif
26 
27 namespace FPoptimizer_CodeTree { template<typename Value_t> class CodeTree; }
28 
29 template<typename Value_t>
31 {
32  public:
33  enum ParseErrorType
34  {
35  SYNTAX_ERROR=0, MISM_PARENTH, MISSING_PARENTH, EMPTY_PARENTH,
36  EXPECT_OPERATOR, OUT_OF_MEMORY, UNEXPECTED_ERROR, INVALID_VARS,
37  ILL_PARAMS_AMOUNT, PREMATURE_EOS, EXPECT_PARENTH_FUNC,
38  UNKNOWN_IDENTIFIER,
39  NO_FUNCTION_PARSED_YET,
40  FP_NO_ERROR
41  };
42 
43  typedef Value_t value_type;
44 
45 
46  int Parse(const char* Function, const std::string& Vars,
47  bool useDegrees = false);
48  int Parse(const std::string& Function, const std::string& Vars,
49  bool useDegrees = false);
50 
51  void setDelimiterChar(char);
52 
53  const char* ErrorMsg() const;
54  ParseErrorType GetParseErrorType() const;
55 
56  Value_t Eval(const Value_t* Vars);
57  int EvalError() const;
58 
59  bool AddConstant(const std::string& name, Value_t value);
60  bool AddUnit(const std::string& name, Value_t value);
61 
62  typedef Value_t (*FunctionPtr)(const Value_t*);
63 
64  bool AddFunction(const std::string& name,
65  FunctionPtr, unsigned paramsAmount);
66  bool AddFunction(const std::string& name, FunctionParserBase&);
67 
68  class FunctionWrapper;
69 
70  template<typename DerivedWrapper>
71  bool AddFunctionWrapper(const std::string& name, const DerivedWrapper&,
72  unsigned paramsAmount);
73 
74  FunctionWrapper* GetFunctionWrapper(const std::string& name);
75 
76  bool RemoveIdentifier(const std::string& name);
77 
78  void Optimize();
79 
80 
81  int ParseAndDeduceVariables(const std::string& function,
82  int* amountOfVariablesFound = 0,
83  bool useDegrees = false);
84  int ParseAndDeduceVariables(const std::string& function,
85  std::string& resultVarString,
86  int* amountOfVariablesFound = 0,
87  bool useDegrees = false);
88  int ParseAndDeduceVariables(const std::string& function,
89  std::vector<std::string>& resultVars,
90  bool useDegrees = false);
91 
92 
95 
96  // Copy constructor and assignment operator (implemented using the
97  // copy-on-write technique for efficiency):
99  FunctionParserBase& operator=(const FunctionParserBase&);
100 
101 
102  void ForceDeepCopy();
103 
104 
105 
106 #ifdef FUNCTIONPARSER_SUPPORT_DEBUGGING
107  // For debugging purposes only.
108  // Performs no sanity checks or anything. If the values are wrong, the
109  // library will crash. Do not use unless you know what you are doing.
110  void InjectRawByteCode(const unsigned* bytecode, unsigned bytecodeAmount,
111  const Value_t* immed, unsigned immedAmount,
112  unsigned stackSize);
113 
114  void PrintByteCode(std::ostream& dest, bool showExpression = true) const;
115 #endif
116 
117 
118 
119 //========================================================================
120  protected:
121 //========================================================================
122  // A derived class can implement its own evaluation logic by using
123  // the parser data (found in fptypes.hh).
124  struct Data;
125  Data* getParserData();
126 
127 
128 //========================================================================
129  private:
130 //========================================================================
131 
132  friend class FPoptimizer_CodeTree::CodeTree<Value_t>;
133 
134 // Private data:
135 // ------------
136  Data* mData;
137  unsigned mStackPtr;
138 
139 
140 // Private methods:
141 // ---------------
142  void CopyOnWrite();
143  bool CheckRecursiveLinking(const FunctionParserBase*) const;
144  bool NameExists(const char*, unsigned);
145  bool ParseVariables(const std::string&);
146  int ParseFunction(const char*, bool);
147  const char* SetErrorType(ParseErrorType, const char*);
148 
149  void AddFunctionOpcode(unsigned);
150  void AddImmedOpcode(Value_t v);
151  void incStackPtr();
152  void CompilePowi(long);
153  bool TryCompilePowi(Value_t);
154 
155  const char* CompileIf(const char*);
156  const char* CompileFunctionParams(const char*, unsigned);
157  const char* CompileElement(const char*);
158  const char* CompilePossibleUnit(const char*);
159  const char* CompilePow(const char*);
160  const char* CompileUnaryMinus(const char*);
161  const char* CompileMult(const char*);
162  const char* CompileAddition(const char*);
163  const char* CompileComparison(const char*);
164  const char* CompileAnd(const char*);
165  const char* CompileExpression(const char*);
166  inline const char* CompileFunction(const char*, unsigned);
167  inline const char* CompileParenthesis(const char*);
168  inline const char* CompileLiteral(const char*);
169  template<bool SetFlag>
170  inline void PushOpcodeParam(unsigned);
171  template<bool SetFlag>
172  inline void PutOpcodeParamAt(unsigned, unsigned offset);
173  const char* Compile(const char*);
174 
175  bool addFunctionWrapperPtr(const std::string&, FunctionWrapper*, unsigned);
176  static void incFuncWrapperRefCount(FunctionWrapper*);
177  static unsigned decFuncWrapperRefCount(FunctionWrapper*);
178 
179 protected:
180  // Parsing utility functions
181  static std::pair<const char*, Value_t> ParseLiteral(const char*);
182  static unsigned ParseIdentifier(const char*);
183 };
184 
185 class FunctionParser: public FunctionParserBase<double> {};
186 class FunctionParser_f: public FunctionParserBase<float> {};
187 class FunctionParser_ld: public FunctionParserBase<long double> {};
188 class FunctionParser_li: public FunctionParserBase<long> {};
189 
190 #include <complex>
191 class FunctionParser_cd: public FunctionParserBase<std::complex<double> > {};
192 class FunctionParser_cf: public FunctionParserBase<std::complex<float> > {};
193 class FunctionParser_cld: public FunctionParserBase<std::complex<long double> > {};
194 
195 
196 
197 template<typename Value_t>
199 {
200  unsigned mReferenceCount;
201  friend class FunctionParserBase<Value_t>;
202 
203  public:
204  FunctionWrapper(): mReferenceCount(1) {}
205  FunctionWrapper(const FunctionWrapper&): mReferenceCount(1) {}
206  virtual ~FunctionWrapper() {}
207  FunctionWrapper& operator=(const FunctionWrapper&) { return *this; }
208 
209  virtual Value_t callFunction(const Value_t*) = 0;
210 };
211 
212 template<typename Value_t>
213 template<typename DerivedWrapper>
215 (const std::string& name, const DerivedWrapper& wrapper, unsigned paramsAmount)
216 {
217  return addFunctionWrapperPtr
218  (name, new DerivedWrapper(wrapper), paramsAmount);
219 }
220 #endif
Definition: fparser.hh:192
Definition: fparser.hh:193
Definition: fparser.hh:30
Definition: fparser.hh:186
Definition: fparser.hh:188
Definition: fparser.hh:27
Definition: fparser.hh:191
Definition: fparser.hh:187
Definition: fparser.hh:185
Definition: fparser.hh:198