1 #ifndef MUP_PARSERBASE_H
2 #define MUP_PARSERBASE_H
3 
4 /** \file
5     \brief Definition of the muParserX engine.
6 
7 <pre>
8                __________                                 ____  ___
9     _____  __ _\______   \_____ _______  ______ __________\   \/  /
10    /     \|  |  \     ___/\__  \\_  __ \/  ___// __ \_  __ \     /
11   |  Y Y  \  |  /    |     / __ \|  | \/\___ \\  ___/|  | \/     \
12   |__|_|  /____/|____|    (____  /__|  /____  >\___  >__| /___/\  \
13         \/                     \/           \/     \/           \_/
14                                        Copyright (C) 2016, Ingo Berg
15                                        All rights reserved.
16 
17   Redistribution and use in source and binary forms, with or without
18   modification, are permitted provided that the following conditions are met:
19 
20    * Redistributions of source code must retain the above copyright notice,
21      this list of conditions and the following disclaimer.
22    * Redistributions in binary form must reproduce the above copyright notice,
23      this list of conditions and the following disclaimer in the documentation
24      and/or other materials provided with the distribution.
25 
26   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29   IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33   WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35   POSSIBILITY OF SUCH DAMAGE.
36 </pre>
37 */
38 
39 #include <cmath>
40 #include <string>
41 #include <iostream>
42 #include <map>
43 #include <memory>
44 
45 #include "mpIOprt.h"
46 #include "mpIOprtBinShortcut.h"
47 #include "mpIValReader.h"
48 #include "mpIPackage.h"
49 #include "mpStack.h"
50 #include "mpTokenReader.h"
51 #include "mpError.h"
52 #include "mpValue.h"
53 #include "mpVariable.h"
54 #include "mpTypes.h"
55 #include "mpRPN.h"
56 #include "mpValueCache.h"
57 
58 MUP_NAMESPACE_START
59 
60   /** \brief Implementation of the parser engine.
61       \author Ingo Berg
62 
63     This is the muParser core. It provides the parsing logic and manages
64     the callback functions, operators, variables and constants. Do not
65     instantiate this class directly. Create an instance of mup::ParserX instead.
66   */
67   class ParserXBase
68   {
69   friend class TokenReader;
70 
71   private:
72 
73     typedef const IValue& (ParserXBase::*parse_function_type)() const;
74     static const char_type *c_DefaultOprt[];
75     static bool s_bDumpStack;
76     static bool s_bDumpRPN;
77 
78   public:
79 
80     static string_type GetVersion();
81     static void EnableDebugDump(bool bDumpCmd, bool bDumpRPN);
82 
83     ParserXBase();
84     ParserXBase( const ParserXBase &a_Parser );
85     ParserXBase& operator=(const ParserXBase &a_Parser);
86     virtual ~ParserXBase();
87 
88     const IValue& Eval() const;
89 
90     void SetExpr(const string_type &a_sExpr);
91     void AddValueReader(IValueReader *a_pReader);
92 
93     void AddPackage(IPackage *p);
94 
95     void DefineConst(const string_type &ident, const Value &val);
96     void DefineVar(const string_type &ident, const Variable &var);
97     void DefineFun(const ptr_cal_type &fun);
98     void DefineOprt(const TokenPtr<IOprtBin> &oprt);
99     void DefineOprt(const TokenPtr<IOprtBinShortcut> &oprt);
100     void DefinePostfixOprt(const TokenPtr<IOprtPostfix> &oprt);
101     void DefineInfixOprt(const TokenPtr<IOprtInfix> &oprt);
102 
103     bool IsVarDefined(const string_type &ident) const;
104     bool IsConstDefined(const string_type &ident) const;
105     bool IsFunDefined(const string_type &ident) const;
106     bool IsOprtDefined(const string_type &ident) const;
107     bool IsPostfixOprtDefined(const string_type &ident) const;
108     bool IsInfixOprtDefined(const string_type &ident) const;
109 
110     void RemoveVar(const string_type &ident) ;
111     void RemoveConst(const string_type &ident);
112     void RemoveFun(const string_type &ident);
113     void RemoveOprt(const string_type &ident);
114     void RemovePostfixOprt(const string_type &ident);
115     void RemoveInfixOprt(const string_type &ident);
116 
117     // Clear user defined variables, constants or functions
118     void ClearVar();
119     void ClearFun();
120     void ClearConst();
121     void ClearInfixOprt();
122     void ClearPostfixOprt();
123     void ClearOprt();
124     void DumpRPN() const;
125 
126     const var_maptype& GetExprVar() const;
127     const var_maptype& GetVar() const;
128     const val_maptype& GetConst() const;
129     const fun_maptype& GetFunDef() const;
130     const string_type& GetExpr() const;
131 
132     const char_type ** GetOprtDef() const;
133     void DefineNameChars(const char_type *a_szCharset);
134     void DefineOprtChars(const char_type *a_szCharset);
135     void DefineInfixOprtChars(const char_type *a_szCharset);
136 
137     void EnableAutoCreateVar(bool bStat);
138     void EnableOptimizer(bool bStat);
139     bool IsAutoCreateVarEnabled() const;
140 
141     const char_type* ValidNameChars() const;
142     const char_type* ValidOprtChars() const;
143     const char_type* ValidInfixOprtChars() const;
144 
145     void  Error(EErrorCodes a_iErrc,
146                 int a_iPos = -1,
147                 const IToken *a_pTok = 0) const;
148 
149     // Allow clients to check syntacticaly correctnes of name against character set.
150     void  CheckName(const string_type &a_sName, const string_type &a_CharSet) const;
151 
152   protected:
153 
154     fun_maptype  m_FunDef;           ///< Function definitions
155     oprt_pfx_maptype m_PostOprtDef;  ///< Postfix operator callbacks
156     oprt_ifx_maptype m_InfixOprtDef; ///< Infix operator callbacks.
157     oprt_bin_maptype m_OprtDef;      ///< Binary operator callbacks
158     oprt_bin_shortcut_maptype   m_OprtShortcutDef;        ///< short circuit operator definitions
159     val_maptype  m_valDef;           ///< Definition of parser constants
160     var_maptype  m_varDef;           ///< user defind variables.
161 
162   private:
163 
164     void  ReInit() const;
165     void  ClearExpr();
166     void  CreateRPN() const;
167     void  StackDump(const Stack<ptr_tok_type> &a_stOprt) const;
168 
169     // Used by by DefineVar and DefineConst methods
170     // for better checking of var/const/oprt/fun existence.
171     void CheckForEntityExistence(const string_type & ident, EErrorCodes error_code);
172 
173     void Assign(const ParserXBase &a_Parser);
174     void InitTokenReader();
175 
176     void ApplyFunc(Stack<ptr_tok_type> &a_stOpt, int a_iArgCount) const;
177     void ApplyOprtShortcut(Stack<ptr_tok_type> &a_stOpt) const;
178     void ApplyIfElse(Stack<ptr_tok_type> &a_stOpt) const;
179     void ApplyRemainingOprt(Stack<ptr_tok_type> &a_stOpt) const;
180     const IValue& ParseFromString() const;
181     const IValue& ParseFromRPN() const;
182 
183     /** \brief Pointer to the parser function.
184 
185 
186       Eval() calls the function whose address is stored there.
187     */
188     mutable parse_function_type m_pParserEngine;
189 
190     /** \brief Managed pointer to the token reader object. */
191     std::unique_ptr<TokenReader> m_pTokenReader;
192 
193     val_vec_type m_valDynVarShadow;  ///< Value objects referenced by variables created at parser runtime
194     string_type m_sNameChars;        ///< Charset for names
195     string_type m_sOprtChars;        ///< Charset for postfix/ binary operator tokens
196     string_type m_sInfixOprtChars;   ///< Charset for infix operator tokens
197     mutable int m_nPos;
198 
199     /** \brief Index of the final result in the stack array.
200 
201       The parser supports expressions using with commas for seperating
202       multiple expression. Each comma will increase this number.
203       (i.e. "a=10,b=15,c=a*b")
204 
205     */
206     mutable int m_nFinalResultIdx;
207 
208     /** \brief A flag indicating querying of expression variables is underway.
209 
210 
211       If this flag is set the parser is momentarily querying the expression
212       variables. In these cases undefined variable errors must be ignored cause
213       the whole point of querying the expression variables is for finding out
214       which variables mut be defined.
215 
216     */
217     mutable bool m_bIsQueryingExprVar;
218 
219     mutable bool m_bAutoCreateVar;      ///< If this flag is set unknown variables will be defined automatically
220 
221     mutable RPN m_rpn;                  ///< reverse polish notation
222     mutable val_vec_type m_vStackBuffer;
223     mutable ValueCache m_cache;         ///< A cache for recycling value items instead of deleting them
224 
225   };
226 } // namespace mu
227 
228 #endif
229 
230