muParser API -  1.35
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
muParserError.cpp
1 /*
2  __________
3  _____ __ __\______ \_____ _______ ______ ____ _______
4  / \ | | \| ___/\__ \ \_ __ \/ ___/_/ __ \\_ __ \
5  | Y Y \| | /| | / __ \_| | \/\___ \ \ ___/ | | \/
6  |__|_| /|____/ |____| (____ /|__| /____ > \___ >|__|
7  \/ \/ \/ \/
8  Copyright (C) 2011 Ingo Berg
9 
10  Permission is hereby granted, free of charge, to any person obtaining a copy of this
11  software and associated documentation files (the "Software"), to deal in the Software
12  without restriction, including without limitation the rights to use, copy, modify,
13  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
14  permit persons to whom the Software is furnished to do so, subject to the following conditions:
15 
16  The above copyright notice and this permission notice shall be included in all copies or
17  substantial portions of the Software.
18 
19  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
20  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
22  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25 #include "muParserError.h"
26 
27 
28 namespace mu
29 {
30  const ParserErrorMsg ParserErrorMsg::m_Instance;
31 
32  //------------------------------------------------------------------------------
33  const ParserErrorMsg& ParserErrorMsg::Instance()
34  {
35  return m_Instance;
36  }
37 
38  //------------------------------------------------------------------------------
39  string_type ParserErrorMsg::operator[](unsigned a_iIdx) const
40  {
41  return (a_iIdx<m_vErrMsg.size()) ? m_vErrMsg[a_iIdx] : string_type();
42  }
43 
44  //---------------------------------------------------------------------------
45  ParserErrorMsg::~ParserErrorMsg()
46  {}
47 
48  //---------------------------------------------------------------------------
49  /** \brief Assignement operator is deactivated.
50  */
52  {
53  assert(false);
54  return *this;
55  }
56 
57  //---------------------------------------------------------------------------
58  ParserErrorMsg::ParserErrorMsg(const ParserErrorMsg&)
59  {}
60 
61  //---------------------------------------------------------------------------
62  ParserErrorMsg::ParserErrorMsg()
63  :m_vErrMsg(0)
64  {
65  m_vErrMsg.resize(ecCOUNT);
66 
67  m_vErrMsg[ecUNASSIGNABLE_TOKEN] = _T("Unexpected token \"$TOK$\" found at position $POS$.");
68  m_vErrMsg[ecINTERNAL_ERROR] = _T("Internal error");
69  m_vErrMsg[ecINVALID_NAME] = _T("Invalid function-, variable- or constant name: \"$TOK$\".");
70  m_vErrMsg[ecINVALID_BINOP_IDENT] = _T("Invalid binary operator identifier: \"$TOK$\".");
71  m_vErrMsg[ecINVALID_INFIX_IDENT] = _T("Invalid infix operator identifier: \"$TOK$\".");
72  m_vErrMsg[ecINVALID_POSTFIX_IDENT] = _T("Invalid postfix operator identifier: \"$TOK$\".");
73  m_vErrMsg[ecINVALID_FUN_PTR] = _T("Invalid pointer to callback function.");
74  m_vErrMsg[ecEMPTY_EXPRESSION] = _T("Expression is empty.");
75  m_vErrMsg[ecINVALID_VAR_PTR] = _T("Invalid pointer to variable.");
76  m_vErrMsg[ecUNEXPECTED_OPERATOR] = _T("Unexpected operator \"$TOK$\" found at position $POS$");
77  m_vErrMsg[ecUNEXPECTED_EOF] = _T("Unexpected end of expression at position $POS$");
78  m_vErrMsg[ecUNEXPECTED_ARG_SEP] = _T("Unexpected argument separator at position $POS$");
79  m_vErrMsg[ecUNEXPECTED_PARENS] = _T("Unexpected parenthesis \"$TOK$\" at position $POS$");
80  m_vErrMsg[ecUNEXPECTED_FUN] = _T("Unexpected function \"$TOK$\" at position $POS$");
81  m_vErrMsg[ecUNEXPECTED_VAL] = _T("Unexpected value \"$TOK$\" found at position $POS$");
82  m_vErrMsg[ecUNEXPECTED_VAR] = _T("Unexpected variable \"$TOK$\" found at position $POS$");
83  m_vErrMsg[ecUNEXPECTED_ARG] = _T("Function arguments used without a function (position: $POS$)");
84  m_vErrMsg[ecMISSING_PARENS] = _T("Missing parenthesis");
85  m_vErrMsg[ecTOO_MANY_PARAMS] = _T("Too many parameters for function \"$TOK$\" at expression position $POS$");
86  m_vErrMsg[ecTOO_FEW_PARAMS] = _T("Too few parameters for function \"$TOK$\" at expression position $POS$");
87  m_vErrMsg[ecDIV_BY_ZERO] = _T("Divide by zero");
88  m_vErrMsg[ecDOMAIN_ERROR] = _T("Domain error");
89  m_vErrMsg[ecNAME_CONFLICT] = _T("Name conflict");
90  m_vErrMsg[ecOPT_PRI] = _T("Invalid value for operator priority (must be greater or equal to zero).");
91  m_vErrMsg[ecBUILTIN_OVERLOAD] = _T("user defined binary operator \"$TOK$\" conflicts with a built in operator.");
92  m_vErrMsg[ecUNEXPECTED_STR] = _T("Unexpected string token found at position $POS$.");
93  m_vErrMsg[ecUNTERMINATED_STRING] = _T("Unterminated string starting at position $POS$.");
94  m_vErrMsg[ecSTRING_EXPECTED] = _T("String function called with a non string type of argument.");
95  m_vErrMsg[ecVAL_EXPECTED] = _T("String value used where a numerical argument is expected.");
96  m_vErrMsg[ecOPRT_TYPE_CONFLICT] = _T("No suitable overload for operator \"$TOK$\" at position $POS$.");
97  m_vErrMsg[ecSTR_RESULT] = _T("Function result is a string.");
98  m_vErrMsg[ecGENERIC] = _T("Parser error.");
99  m_vErrMsg[ecLOCALE] = _T("Decimal separator is identic to function argument separator.");
100  m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = _T("The \"$TOK$\" operator must be preceeded by a closing bracket.");
101  m_vErrMsg[ecMISSING_ELSE_CLAUSE] = _T("If-then-else operator is missing an else clause");
102  m_vErrMsg[ecMISPLACED_COLON] = _T("Misplaced colon at position $POS$");
103  m_vErrMsg[ecUNREASONABLE_NUMBER_OF_COMPUTATIONS] = _T("Number of computations to small for bulk mode. (Vectorisation overhead too costly)");
104 
105  #if defined(_DEBUG)
106  for (int i=0; i<ecCOUNT; ++i)
107  if (!m_vErrMsg[i].length())
108  assert(false);
109  #endif
110  }
111 
112  //---------------------------------------------------------------------------
113  //
114  // ParserError class
115  //
116  //---------------------------------------------------------------------------
117 
118  /** \brief Default constructor. */
120  :m_strMsg()
121  ,m_strFormula()
122  ,m_strTok()
123  ,m_iPos(-1)
124  ,m_iErrc(ecUNDEFINED)
125  ,m_ErrMsg(ParserErrorMsg::Instance())
126  {
127  }
128 
129  //------------------------------------------------------------------------------
130  /** \brief This Constructor is used for internal exceptions only.
131 
132  It does not contain any information but the error code.
133  */
135  :m_strMsg()
136  ,m_strFormula()
137  ,m_strTok()
138  ,m_iPos(-1)
139  ,m_iErrc(a_iErrc)
140  ,m_ErrMsg(ParserErrorMsg::Instance())
141  {
142  m_strMsg = m_ErrMsg[m_iErrc];
143  stringstream_type stream;
144  stream << (int)m_iPos;
145  ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
146  ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
147  }
148 
149  //------------------------------------------------------------------------------
150  /** \brief Construct an error from a message text. */
152  :m_ErrMsg(ParserErrorMsg::Instance())
153  {
154  Reset();
155  m_strMsg = sMsg;
156  }
157 
158  //------------------------------------------------------------------------------
159  /** \brief Construct an error object.
160  \param [in] a_iErrc the error code.
161  \param [in] sTok The token string related to this error.
162  \param [in] sExpr The expression related to the error.
163  \param [in] a_iPos the position in the expression where the error occurred.
164  */
166  const string_type &sTok,
167  const string_type &sExpr,
168  int iPos )
169  :m_strMsg()
170  ,m_strFormula(sExpr)
171  ,m_strTok(sTok)
172  ,m_iPos(iPos)
173  ,m_iErrc(iErrc)
174  ,m_ErrMsg(ParserErrorMsg::Instance())
175  {
176  m_strMsg = m_ErrMsg[m_iErrc];
177  stringstream_type stream;
178  stream << (int)m_iPos;
179  ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
180  ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
181  }
182 
183  //------------------------------------------------------------------------------
184  /** \brief Construct an error object.
185  \param [in] iErrc the error code.
186  \param [in] iPos the position in the expression where the error occurred.
187  \param [in] sTok The token string related to this error.
188  */
189  ParserError::ParserError(EErrorCodes iErrc, int iPos, const string_type &sTok)
190  :m_strMsg()
191  ,m_strFormula()
192  ,m_strTok(sTok)
193  ,m_iPos(iPos)
194  ,m_iErrc(iErrc)
195  ,m_ErrMsg(ParserErrorMsg::Instance())
196  {
197  m_strMsg = m_ErrMsg[m_iErrc];
198  stringstream_type stream;
199  stream << (int)m_iPos;
200  ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
201  ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
202  }
203 
204  //------------------------------------------------------------------------------
205  /** \brief Construct an error object.
206  \param [in] szMsg The error message text.
207  \param [in] iPos the position related to the error.
208  \param [in] sTok The token string related to this error.
209  */
210  ParserError::ParserError(const char_type *szMsg, int iPos, const string_type &sTok)
211  :m_strMsg(szMsg)
212  ,m_strFormula()
213  ,m_strTok(sTok)
214  ,m_iPos(iPos)
215  ,m_iErrc(ecGENERIC)
216  ,m_ErrMsg(ParserErrorMsg::Instance())
217  {
218  stringstream_type stream;
219  stream << (int)m_iPos;
220  ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());
221  ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);
222  }
223 
224  //------------------------------------------------------------------------------
225  /** \brief Copy constructor. */
227  :m_strMsg(a_Obj.m_strMsg)
228  ,m_strFormula(a_Obj.m_strFormula)
229  ,m_strTok(a_Obj.m_strTok)
230  ,m_iPos(a_Obj.m_iPos)
231  ,m_iErrc(a_Obj.m_iErrc)
232  ,m_ErrMsg(ParserErrorMsg::Instance())
233  {
234  }
235 
236  //------------------------------------------------------------------------------
237  /** \brief Assignment operator. */
239  {
240  if (this==&a_Obj)
241  return *this;
242 
243  m_strMsg = a_Obj.m_strMsg;
244  m_strFormula = a_Obj.m_strFormula;
245  m_strTok = a_Obj.m_strTok;
246  m_iPos = a_Obj.m_iPos;
247  m_iErrc = a_Obj.m_iErrc;
248  return *this;
249  }
250 
251  //------------------------------------------------------------------------------
252  ParserError::~ParserError()
253  {}
254 
255  //------------------------------------------------------------------------------
256  /** \brief Replace all occurrences of a substring with another string.
257  \param strFind The string that shall be replaced.
258  \param strReplaceWith The string that should be inserted instead of strFind
259  */
260  void ParserError::ReplaceSubString( string_type &strSource,
261  const string_type &strFind,
262  const string_type &strReplaceWith)
263  {
264  string_type strResult;
265  string_type::size_type iPos(0), iNext(0);
266 
267  for(;;)
268  {
269  iNext = strSource.find(strFind, iPos);
270  strResult.append(strSource, iPos, iNext-iPos);
271 
272  if( iNext==string_type::npos )
273  break;
274 
275  strResult.append(strReplaceWith);
276  iPos = iNext + strFind.length();
277  }
278 
279  strSource.swap(strResult);
280  }
281 
282  //------------------------------------------------------------------------------
283  /** \brief Reset the erro object. */
284  void ParserError::Reset()
285  {
286  m_strMsg = _T("");
287  m_strFormula = _T("");
288  m_strTok = _T("");
289  m_iPos = -1;
290  m_iErrc = ecUNDEFINED;
291  }
292 
293  //------------------------------------------------------------------------------
294  /** \brief Set the expression related to this error. */
295  void ParserError::SetFormula(const string_type &a_strFormula)
296  {
297  m_strFormula = a_strFormula;
298  }
299 
300  //------------------------------------------------------------------------------
301  /** \brief gets the expression related tp this error.*/
303  {
304  return m_strFormula;
305  }
306 
307  //------------------------------------------------------------------------------
308  /** \brief Returns the message string for this error. */
310  {
311  return m_strMsg;
312  }
313 
314  //------------------------------------------------------------------------------
315  /** \brief Return the formula position related to the error.
316 
317  If the error is not related to a distinct position this will return -1
318  */
320  {
321  return m_iPos;
322  }
323 
324  //------------------------------------------------------------------------------
325  /** \brief Return string related with this token (if available). */
327  {
328  return m_strTok;
329  }
330 
331  //------------------------------------------------------------------------------
332  /** \brief Return the error code. */
334  {
335  return m_iErrc;
336  }
337 } // namespace mu
A class that handles the error messages.
#define _T(x)
Activate this option in order to compile with OpenMP support.
Definition: muParserDef.h:69
const string_type & GetExpr() const
gets the expression related tp this error.
binary operators may only be applied to value items of the same type
Definition: muParserError.h:65
An unexpected comma has been found. (Example: "1,23")
Definition: muParserError.h:52
Token cant be identified.
Definition: muParserError.h:50
result is a string
Definition: muParserError.h:66
An unexpected argument has been found.
Definition: muParserError.h:53
Division by zero (currently unused)
Definition: muParserError.h:82
Name conflict.
Definition: muParserError.h:78
Internal error of any kind.
Definition: muParserError.h:93
unterminated string constant. (Example: "3*valueof("hello)")
Definition: muParserError.h:62
Trying to overload builtin operator.
Definition: muParserError.h:74
Undefined message, placeholder to detect unassigned error messages.
Definition: muParserError.h:97
ParserErrorMsg & operator=(const ParserErrorMsg &)
Assignement operator is deactivated.
Unexpected function found. (Example: "sin(8)cos(9)")
Definition: muParserError.h:61
std::basic_stringstream< char_type, std::char_traits< char_type >, std::allocator< char_type > > stringstream_type
Typedef for easily using stringstream that respect the parser stringtype.
Definition: muParserDef.h:264
This is no error code, It just stores just the total number of error codes.
Definition: muParserError.h:96
An unexpected value token has been found.
Definition: muParserError.h:54
Conflict with current locale.
Definition: muParserError.h:84
catch division by zero, sqrt(-1), log(0) (currently unused)
Definition: muParserError.h:81
An unexpected variable token has been found.
Definition: muParserError.h:55
Invalid variable pointer.
Definition: muParserError.h:76
Invalid function, variable or constant name.
Definition: muParserError.h:69
void SetFormula(const string_type &a_strFormula)
Set the expression related to this error.
Error class of the parser.
The Expression is empty.
Definition: muParserError.h:77
Too many function parameters.
Definition: muParserError.h:63
A numerical function has been called with a non value type of argument.
Definition: muParserError.h:59
Namespace for mathematical applications.
Definition: muParser.cpp:49
Unexpected end of formula. (Example: "2+sin(")
Definition: muParserError.h:51
Too few function parameters. (Example: "ite(1<2,2)")
Definition: muParserError.h:64
A string function has been called with a different type of argument.
Definition: muParserError.h:58
EErrorCodes GetCode() const
Return the error code.
ParserError()
Default constructor.
string_type::value_type char_type
The character type used by the parser.
Definition: muParserDef.h:259
int GetPos() const
Return the formula position related to the error.
Unexpected binary operator found.
Definition: muParserError.h:49
MUP_STRING_TYPE string_type
The stringtype used by the parser.
Definition: muParserDef.h:253
Invalid operator priority.
Definition: muParserError.h:79
Unexpected Parenthesis, opening or closing.
Definition: muParserError.h:56
Invalid function, variable or constant name.
Definition: muParserError.h:72
Invalid callback function pointer.
Definition: muParserError.h:75
EErrorCodes
Error codes.
Definition: muParserError.h:46
Generic error.
Definition: muParserError.h:83
const string_type & GetToken() const
Return string related with this token (if available).
Missing parens. (Example: "3*sin(3")
Definition: muParserError.h:60
const string_type & GetMsg() const
Returns the message string for this error.
A string has been found at an inapropriate position.
Definition: muParserError.h:57
Invalid function, variable or constant name.
Definition: muParserError.h:71
ParserError & operator=(const ParserError &a_Obj)
Assignment operator.
Invalid binary operator identifier.
Definition: muParserError.h:70
This file defines the error class used by the parser.