Seamly2D
Code documentation
qmuparsertokenreader.h
Go to the documentation of this file.
1 /***************************************************************************************************
2  **
3  ** Copyright (C) 2013 Ingo Berg
4  **
5  ** Permission is hereby granted, free of charge, to any person obtaining a copy of this
6  ** software and associated documentation files (the "Software"), to deal in the Software
7  ** without restriction, including without limitation the rights to use, copy, modify,
8  ** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
9  ** permit persons to whom the Software is furnished to do so, subject to the following conditions:
10  **
11  ** The above copyright notice and this permission notice shall be included in all copies or
12  ** substantial portions of the Software.
13  **
14  ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15  ** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16  ** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17  ** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  **
20  ******************************************************************************************************/
21 
22 #ifndef QMUPARSERTOKENREADER_H
23 #define QMUPARSERTOKENREADER_H
24 
25 #include <qcompilerdetection.h>
26 #include <QChar>
27 #include <QString>
28 #include <QtGlobal>
29 #include <list>
30 #include <locale>
31 
32 #include "qmuparsercallback.h"
33 #include "qmuparserdef.h"
34 #include "qmuparsererror.h"
35 #include "qmuparsertoken.h"
36 
37 /**
38  * @file
39  * @brief This file contains the parser token reader definition.
40  */
41 
42 namespace qmu
43 {
44 // Forward declaration
45 class QmuParserBase;
46 
47 /**
48  * @brief Token reader for the ParserBase class.
49  *
50  */
52 {
53 private:
55 public:
56  explicit QmuParserTokenReader(QmuParserBase *a_pParent);
57  QmuParserTokenReader* Clone(QmuParserBase *a_pParent) const;
58 
59  void AddValIdent(identfun_type a_pCallback);
60  void SetVarCreator(facfun_type a_pFactory, void *pUserData);
61  void SetFormula(const QString &a_strFormula);
62  void SetArgSep(char_type cArgSep);
63  int GetPos() const;
64  const QString& GetExpr() const;
66  QChar GetArgSep() const;
67  void IgnoreUndefVar(bool bIgnore);
68  void ReInit();
69  token_type ReadNextToken(const QLocale &locale, const QChar &decimal, const QChar &thousand);
70 private:
71 
72  /**
73  * @brief Syntax codes.
74  *
75  * The syntax codes control the syntax check done during the first time parsing of
76  * the expression string. They are flags that indicate which tokens are allowed next
77  * if certain tokens are identified.
78  */
79  enum ESynCodes
80  {
81  noBO = 1 << 0, ///< to avoid i.e. "cos(7)("
82  noBC = 1 << 1, ///< to avoid i.e. "sin)" or "()"
83  noVAL = 1 << 2, ///< to avoid i.e. "tan 2" or "sin(8)3.14"
84  noVAR = 1 << 3, ///< to avoid i.e. "sin a" or "sin(8)a"
85  noARG_SEP = 1 << 4, ///< to avoid i.e. ",," or "+," ...
86  noFUN = 1 << 5, ///< to avoid i.e. "sqrt cos" or "(1)sin"
87  noOPT = 1 << 6, ///< to avoid i.e. "(+)"
88  noPOSTOP = 1 << 7, ///< to avoid i.e. "(5!!)" "sin!"
89  noINFIXOP = 1 << 8, ///< to avoid i.e. "++4" "!!4"
90  noEND = 1 << 9, ///< to avoid unexpected end of formula
91  noSTR = 1 << 10, ///< to block numeric arguments on string functions
92  noASSIGN = 1 << 11, ///< to block assignement to constant i.e. "4=7"
93  noIF = 1 << 12,
94  noELSE = 1 << 13,
96  noANY = ~0 ///< All of he above flags set
97  };
98 
101  void Assign(const QmuParserTokenReader &a_Reader);
102 
103  void SetParent(QmuParserBase *a_pParent);
104  int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const;
105  int ExtractOperatorToken(QString &a_sTok, int a_iPos) const;
106 
107  bool IsBuiltIn(token_type &a_Tok);
108  bool IsArgSep(token_type &a_Tok);
109  bool IsEOF(token_type &a_Tok);
110  bool IsInfixOpTok(token_type &a_Tok);
111  bool IsFunTok(token_type &a_Tok);
112  bool IsPostOpTok(token_type &a_Tok);
113  bool IsOprt(token_type &a_Tok);
114  bool IsValTok(token_type &a_Tok, const QLocale &locale, const QChar &decimal, const QChar &thousand);
115  bool IsVarTok(token_type &a_Tok);
116  bool IsStrVarTok(token_type &a_Tok);
117  bool IsUndefVarTok(token_type &a_Tok);
118  bool IsString(token_type &a_Tok);
119  void Q_NORETURN Error(EErrorCodes a_iErrc, int a_iPos = -1, const QString &a_sTok = QString() ) const;
120 
122 
124  QString m_strFormula;
125  int m_iPos;
128 
135  varmap_type *m_pVarDef; ///< The only non const pointer to parser internals
138  std::list<identfun_type> m_vIdentFun; ///< Value token identification function
140  qreal m_fZero; ///< Dummy value of zero, referenced by undefined variables
141  int m_iBrackets; ///< Keep count open brackets
143  QChar m_cArgSep; ///< The character used for separating function arguments
144 };
145 
146 //---------------------------------------------------------------------------------------------------------------------
147 /**
148  * @brief Return the current position of the token reader in the formula string.
149  *
150  * @return #m_iPos
151  * @throw nothrow
152  */
154 {
155  return m_iPos;
156 }
157 
158 //---------------------------------------------------------------------------------------------------------------------
159 /**
160  * @brief Return a reference to the formula.
161  *
162  * @return #m_strFormula
163  * @throw nothrow
164  */
165 inline const QString& QmuParserTokenReader::GetExpr() const
166 {
167  return m_strFormula;
168 }
169 
170 //---------------------------------------------------------------------------------------------------------------------
171 /**
172  * @brief Return a map containing the used variables only.
173  */
175 {
176  return m_UsedVar;
177 }
178 
179 //---------------------------------------------------------------------------------------------------------------------
180 /**
181  * @brief Set Flag that contronls behaviour in case of undefined variables beeing found.
182  *
183  * If true, the parser does not throw an exception if an undefined variable is found. Otherwise it does. This variable
184  * is used internally only! It supresses a "undefined variable" exception in GetUsedVar().
185  * Those function should return a complete list of variables including
186  * those the are not defined by the time of it's call.
187  */
188 inline void QmuParserTokenReader::IgnoreUndefVar ( bool bIgnore )
189 {
190  m_bIgnoreUndefVar = bIgnore;
191 }
192 
193 //---------------------------------------------------------------------------------------------------------------------
195 {
196  m_cArgSep = cArgSep;
197 }
198 
199 //---------------------------------------------------------------------------------------------------------------------
201 {
202  return m_cArgSep;
203 }
204 } // namespace qmu
205 
206 #endif
Mathematical expressions parser (base parser engine).
Definition: qmuparserbase.h:66
Token reader for the ParserBase class.
std::list< identfun_type > m_vIdentFun
Value token identification function.
int ExtractOperatorToken(QString &a_sTok, int a_iPos) const
Check Expression for the presence of a binary operator token.
QChar m_cArgSep
The character used for separating function arguments.
varmap_type * m_pVarDef
The only non const pointer to parser internals.
const funmap_type * m_pPostOprtDef
bool IsBuiltIn(token_type &a_Tok)
Check if a built in operator or other token can be found.
qreal m_fZero
Dummy value of zero, referenced by undefined variables.
int ExtractToken(const QString &a_szCharSet, QString &a_strTok, int a_iPos) const
Extract all characters that belong to a certain charset.
bool IsArgSep(token_type &a_Tok)
bool IsEOF(token_type &a_Tok)
Check for End of Formula.
void ReInit()
Reset the token reader to the start of the formula.
void AddValIdent(identfun_type a_pCallback)
void SetParent(QmuParserBase *a_pParent)
QmuParserTokenReader(QmuParserBase *a_pParent)
Constructor.
const funmap_type * m_pInfixOprtDef
bool IsValTok(token_type &a_Tok, const QLocale &locale, const QChar &decimal, const QChar &thousand)
Check whether the token at a given position is a value token.
bool IsUndefVarTok(token_type &a_Tok)
Check wheter a token at a given position is an undefined variable.
bool IsStrVarTok(token_type &a_Tok)
QmuParserToken< qreal, QString > token_type
bool IsFunTok(token_type &a_Tok)
Check whether the token at a given position is a function token.
int m_iBrackets
Keep count open brackets.
bool IsInfixOpTok(token_type &a_Tok)
Check if a string position contains a unary infix operator.
const valmap_type * m_pConstDef
bool IsString(token_type &a_Tok)
Check wheter a token at a given position is a string.
void SetFormula(const QString &a_strFormula)
Initialize the token Reader.
const QString & GetExpr() const
Return a reference to the formula.
int GetPos() const
Return the current position of the token reader in the formula string.
bool IsOprt(token_type &a_Tok)
Check if a string position contains a binary operator.
void SetArgSep(char_type cArgSep)
token_type ReadNextToken(const QLocale &locale, const QChar &decimal, const QChar &thousand)
Read the next token from the string.
QmuParserTokenReader * Clone(QmuParserBase *a_pParent) const
Create instance of a QParserTokenReader identical with this and return its pointer.
bool IsVarTok(token_type &a_Tok)
Check wheter a token at a given position is a variable token.
const strmap_type * m_pStrVarDef
void Assign(const QmuParserTokenReader &a_Reader)
Assign state of a token reader to this token reader.
varmap_type & GetUsedVar()
Return a map containing the used variables only.
const funmap_type * m_pOprtDef
QmuParserTokenReader & operator=(const QmuParserTokenReader &a_Reader)
Assignement operator.
bool IsPostOpTok(token_type &a_Tok)
Check if a string position contains a unary post value operator.
void SetVarCreator(facfun_type a_pFactory, void *pUserData)
@ noOPT
to avoid i.e. "(+)"
@ noBC
to avoid i.e. "sin)" or "()"
@ noANY
All of he above flags set.
@ noSTR
to block numeric arguments on string functions
@ noBO
to avoid i.e. "cos(7)("
@ noINFIXOP
to avoid i.e. "++4" "!!4"
@ noEND
to avoid unexpected end of formula
@ noASSIGN
to block assignement to constant i.e. "4=7"
@ noARG_SEP
to avoid i.e. ",," or "+," ...
@ noVAL
to avoid i.e. "tan 2" or "sin(8)3.14"
@ noPOSTOP
to avoid i.e. "(5!!)" "sin!"
@ noFUN
to avoid i.e. "sqrt cos" or "(1)sin"
@ noVAR
to avoid i.e. "sin a" or "sin(8)a"
token_type & SaveBeforeReturn(const token_type &tok)
void Q_NORETURN Error(EErrorCodes a_iErrc, int a_iPos=-1, const QString &a_sTok=QString()) const
Create an error containing the parse error position.
void IgnoreUndefVar(bool bIgnore)
Set Flag that contronls behaviour in case of undefined variables beeing found.
Namespace for mathematical applications.
std::map< QString, QmuParserCallback > funmap_type
Container for Callback objects.
std::map< QString, int > strmap_type
Type for assigning a string name to an index in the internal string table.
Definition: qmuparserdef.h:216
string_type::value_type char_type
The character type used by the parser.
Definition: qmuparserdef.h:202
EErrorCodes
Error codes.
qreal *(* facfun_type)(const QString &, void *)
Callback used for variable creation factory functions.
Definition: qmuparserdef.h:306
int(* identfun_type)(const QString &sExpr, int *nPos, qreal *fVal, const QLocale &locale, const QChar &decimal, const QChar &thousand)
Callback used for functions that identify values in a string.
Definition: qmuparserdef.h:302
std::map< QString, qreal > valmap_type
Type used for storing constants.
Definition: qmuparserdef.h:213
std::map< QString, qreal * > varmap_type
Type used for storing variables.
Definition: qmuparserdef.h:210
Definition of the parser callback class.
This file contains standard definitions used by the parser.
This file defines the error class used by the parser.
This file contains the parser token definition.