2014-04-30 07:32:29 +02:00
|
|
|
/***************************************************************************************************
|
|
|
|
**
|
2015-02-27 11:21:09 +01:00
|
|
|
** Copyright (C) 2013 Ingo Berg
|
2014-04-30 07:32:29 +02:00
|
|
|
**
|
|
|
|
** Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
|
|
** software and associated documentation files (the "Software"), to deal in the Software
|
|
|
|
** without restriction, including without limitation the rights to use, copy, modify,
|
|
|
|
** merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
** permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
|
|
**
|
|
|
|
** The above copyright notice and this permission notice shall be included in all copies or
|
|
|
|
** substantial portions of the Software.
|
|
|
|
**
|
|
|
|
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
|
|
** NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
|
|
** DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
**
|
|
|
|
******************************************************************************************************/
|
|
|
|
|
|
|
|
#ifndef QMUPDEF_H
|
|
|
|
#define QMUPDEF_H
|
|
|
|
|
|
|
|
#include <QMap>
|
|
|
|
#include <QString>
|
2015-02-26 21:18:52 +01:00
|
|
|
#include <locale>
|
2018-12-11 21:27:55 +01:00
|
|
|
#include <ciso646>
|
2023-02-09 16:23:11 +01:00
|
|
|
#include <QtGlobal>
|
2018-01-22 09:03:04 +01:00
|
|
|
|
2014-04-30 07:32:29 +02:00
|
|
|
#include "qmuparserfixes.h"
|
|
|
|
|
|
|
|
/** @file
|
|
|
|
@brief This file contains standard definitions used by the parser.
|
|
|
|
*/
|
|
|
|
|
2023-01-10 12:27:19 +01:00
|
|
|
#ifndef QMUP_VERSION
|
|
|
|
#define QMUP_VERSION "2.7.0" // Leave while we still use qmake
|
|
|
|
#endif
|
2019-10-30 10:34:01 +01:00
|
|
|
#define QMUP_VERSION_DATE "20191030; GC"
|
2014-04-30 07:32:29 +02:00
|
|
|
|
2014-10-17 22:26:30 +02:00
|
|
|
// Detect whether the compiler supports C++11 noexcept exception specifications.
|
|
|
|
# if defined(__clang__)
|
|
|
|
# if __has_feature(cxx_noexcept)
|
|
|
|
# define QMUP_NOEXCEPT_EXPR(x) noexcept(x) // Clang 3.0 and above have noexcept
|
|
|
|
# endif
|
|
|
|
# elif defined(__GNUC__)
|
|
|
|
# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__GXX_EXPERIMENTAL_CXX0X__)
|
|
|
|
# define QMUP_NOEXCEPT_EXPR(x) noexcept(x) // GCC 4.7 and following have noexcept
|
|
|
|
# endif
|
2016-07-29 11:07:44 +02:00
|
|
|
# elif defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026
|
|
|
|
# define QMUP_NOEXCEPT_EXPR(x) noexcept(x) // Visual Studio 2015 and following have noexcept
|
2014-10-17 22:26:30 +02:00
|
|
|
# else
|
|
|
|
# define QMUP_NOEXCEPT_EXPR(x)
|
|
|
|
# endif
|
|
|
|
|
2017-05-30 19:56:59 +02:00
|
|
|
#ifndef __has_cpp_attribute
|
|
|
|
# define __has_cpp_attribute(x) 0
|
|
|
|
#endif
|
|
|
|
|
2019-03-27 12:31:02 +01:00
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(5, 8, 0)
|
|
|
|
|
|
|
|
#ifndef QT_HAS_CPP_ATTRIBUTE
|
|
|
|
#ifdef __has_cpp_attribute
|
|
|
|
# define QT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
|
2017-05-30 17:44:16 +02:00
|
|
|
#else
|
2019-03-27 12:31:02 +01:00
|
|
|
# define QT_HAS_CPP_ATTRIBUTE(x) 0
|
|
|
|
#endif
|
|
|
|
#endif // QT_HAS_CPP_ATTRIBUTE
|
|
|
|
|
|
|
|
#if defined(__cplusplus)
|
|
|
|
#if QT_HAS_CPP_ATTRIBUTE(clang::fallthrough)
|
|
|
|
# define Q_FALLTHROUGH() [[clang::fallthrough]]
|
|
|
|
#elif QT_HAS_CPP_ATTRIBUTE(gnu::fallthrough)
|
|
|
|
# define Q_FALLTHROUGH() [[gnu::fallthrough]]
|
|
|
|
#elif QT_HAS_CPP_ATTRIBUTE(fallthrough)
|
|
|
|
# define Q_FALLTHROUGH() [[fallthrough]]
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#ifndef Q_FALLTHROUGH
|
|
|
|
# if (defined(Q_CC_GNU) && Q_CC_GNU >= 700) && !defined(Q_CC_INTEL)
|
|
|
|
# define Q_FALLTHROUGH() __attribute__((fallthrough))
|
|
|
|
# else
|
|
|
|
# define Q_FALLTHROUGH() (void)0
|
2017-05-30 17:44:16 +02:00
|
|
|
#endif
|
2019-03-27 12:31:02 +01:00
|
|
|
#endif // defined(__cplusplus)
|
|
|
|
#endif // QT_VERSION < QT_VERSION_CHECK(5, 8, 0)
|
2017-05-30 17:44:16 +02:00
|
|
|
|
2014-04-30 07:32:29 +02:00
|
|
|
/** @brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */
|
|
|
|
//#define QMUP_MATH_EXCEPTIONS
|
|
|
|
|
|
|
|
/** @brief Activate this option in order to compile with OpenMP support.
|
|
|
|
|
|
|
|
OpenMP is used only in the bulk mode it may increase the performance a bit.
|
|
|
|
*/
|
2014-05-01 11:55:23 +02:00
|
|
|
//#define QMUP_USE_OPENMP
|
2014-04-30 07:32:29 +02:00
|
|
|
|
2014-05-22 14:11:14 +02:00
|
|
|
/** @brief Definition of the basic parser string type. */
|
|
|
|
#define QMUP_STRING_TYPE std::wstring
|
2014-04-30 07:32:29 +02:00
|
|
|
|
2017-01-03 10:14:32 +01:00
|
|
|
class QLocale;
|
|
|
|
|
2023-02-09 16:23:11 +01:00
|
|
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
|
|
|
using qmusizetype = qsizetype;
|
|
|
|
#else
|
|
|
|
using qmusizetype = int;
|
|
|
|
#endif
|
|
|
|
|
2023-02-09 15:43:00 +01:00
|
|
|
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
|
|
|
namespace Qt
|
|
|
|
{
|
|
|
|
static auto endl = ::endl;
|
|
|
|
static auto flush = ::flush;
|
|
|
|
static auto dec = ::dec;
|
|
|
|
static auto SkipEmptyParts = QString::SkipEmptyParts;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-04-30 07:32:29 +02:00
|
|
|
namespace qmu
|
|
|
|
{
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
/** @brief Bytecode values.
|
|
|
|
|
|
|
|
\attention The order of the operator entries must match the order in ParserBase::c_DefaultOprt!
|
|
|
|
*/
|
|
|
|
enum ECmdCode
|
|
|
|
{
|
|
|
|
// The following are codes for built in binary operators
|
|
|
|
// apart from built in operators the user has the opportunity to
|
|
|
|
// add user defined operators.
|
|
|
|
cmLE = 0, ///< Operator item: less or equal
|
|
|
|
cmGE = 1, ///< Operator item: greater or equal
|
|
|
|
cmNEQ = 2, ///< Operator item: not equal
|
|
|
|
cmEQ = 3, ///< Operator item: equals
|
|
|
|
cmLT = 4, ///< Operator item: less than
|
|
|
|
cmGT = 5, ///< Operator item: greater than
|
|
|
|
cmADD = 6, ///< Operator item: add
|
|
|
|
cmSUB = 7, ///< Operator item: subtract
|
|
|
|
cmMUL = 8, ///< Operator item: multiply
|
|
|
|
cmDIV = 9, ///< Operator item: division
|
|
|
|
cmPOW = 10, ///< Operator item: y to the power of ...
|
|
|
|
cmLAND = 11,
|
|
|
|
cmLOR = 12,
|
|
|
|
cmASSIGN = 13, ///< Operator item: Assignment operator
|
|
|
|
cmBO = 14, ///< Operator item: opening bracket
|
|
|
|
cmBC = 15, ///< Operator item: closing bracket
|
|
|
|
cmIF = 16, ///< For use in the ternary if-then-else operator
|
|
|
|
cmELSE = 17, ///< For use in the ternary if-then-else operator
|
|
|
|
cmENDIF = 18, ///< For use in the ternary if-then-else operator
|
|
|
|
cmARG_SEP = 19, ///< function argument separator
|
|
|
|
cmVAR = 20, ///< variable item
|
|
|
|
cmVAL = 21, ///< value item
|
|
|
|
|
|
|
|
// For optimization purposes
|
|
|
|
cmVARPOW2,
|
|
|
|
cmVARPOW3,
|
|
|
|
cmVARPOW4,
|
|
|
|
cmVARMUL,
|
|
|
|
cmPOW2,
|
|
|
|
|
|
|
|
// operators and functions
|
|
|
|
cmFUNC, ///< Code for a generic function item
|
|
|
|
cmFUNC_STR, ///< Code for a function with a string parameter
|
|
|
|
cmFUNC_BULK, ///< Special callbacks for Bulk mode with an additional parameter for the bulk index
|
|
|
|
cmSTRING, ///< Code for a string token
|
|
|
|
cmOPRT_BIN, ///< user defined binary operator
|
|
|
|
cmOPRT_POSTFIX, ///< code for postfix operators
|
|
|
|
cmOPRT_INFIX, ///< code for infix operators
|
|
|
|
cmEND, ///< end of formula
|
|
|
|
cmUNKNOWN ///< uninitialized item
|
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
/** @brief Types internally used by the parser.
|
|
|
|
*/
|
|
|
|
enum ETypeCode
|
|
|
|
{
|
|
|
|
tpSTR = 0, ///< String type (Function arguments and constants only, no string variables)
|
|
|
|
tpDBL = 1, ///< Floating point variables
|
|
|
|
tpVOID = 2 ///< Undefined type.
|
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
enum EParserVersionInfo
|
|
|
|
{
|
|
|
|
pviBRIEF,
|
|
|
|
pviFULL
|
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
/** @brief Parser operator precedence values. */
|
|
|
|
enum EOprtAssociativity
|
|
|
|
{
|
|
|
|
oaLEFT = 0,
|
|
|
|
oaRIGHT = 1,
|
|
|
|
oaNONE = 2
|
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
/** @brief Parser operator precedence values. */
|
|
|
|
enum EOprtPrecedence
|
|
|
|
{
|
|
|
|
// binary operators
|
|
|
|
prLOR = 1,
|
|
|
|
prLAND = 2,
|
|
|
|
prLOGIC = 3, ///< logic operators
|
|
|
|
prCMP = 4, ///< comparsion operators
|
|
|
|
prADD_SUB = 5, ///< addition
|
|
|
|
prMUL_DIV = 6, ///< multiplication/division
|
|
|
|
prPOW = 7, ///< power operator priority (highest)
|
|
|
|
|
|
|
|
// infix operators
|
|
|
|
prINFIX = 6, ///< Signs have a higher priority than ADD_SUB, but lower than power operator
|
|
|
|
prPOSTFIX = 6 ///< Postfix operator priority (currently unused)
|
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// basic types
|
|
|
|
|
|
|
|
/** @brief The stringtype used by the parser.
|
|
|
|
|
|
|
|
Depends on wether UNICODE is used or not.
|
|
|
|
*/
|
|
|
|
typedef QMUP_STRING_TYPE string_type;
|
|
|
|
|
|
|
|
/** @brief The character type used by the parser.
|
|
|
|
|
|
|
|
Depends on wether UNICODE is used or not.
|
|
|
|
*/
|
|
|
|
typedef string_type::value_type char_type;
|
|
|
|
|
|
|
|
/** @brief Typedef for easily using stringstream that respect the parser stringtype. */
|
|
|
|
typedef std::basic_stringstream < char_type, std::char_traits<char_type>, std::allocator<char_type> > stringstream_type;
|
|
|
|
|
|
|
|
// Data container types
|
|
|
|
|
|
|
|
/** @brief Type used for storing variables. */
|
2014-05-21 15:51:47 +02:00
|
|
|
typedef std::map<QString, qreal*> varmap_type;
|
2014-04-30 07:32:29 +02:00
|
|
|
|
|
|
|
/** @brief Type used for storing constants. */
|
|
|
|
typedef std::map<QString, qreal> valmap_type;
|
|
|
|
|
|
|
|
/** @brief Type for assigning a string name to an index in the internal string table. */
|
2023-02-09 16:23:11 +01:00
|
|
|
typedef std::map<QString, qmusizetype> strmap_type;
|
2014-04-30 07:32:29 +02:00
|
|
|
|
|
|
|
// Parser callbacks
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions without arguments. */
|
|
|
|
typedef qreal ( *generic_fun_type ) ();
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions without arguments. */
|
|
|
|
typedef qreal ( *fun_type0 ) ();
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with a single arguments. */
|
|
|
|
typedef qreal ( *fun_type1 ) ( qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with two arguments. */
|
|
|
|
typedef qreal ( *fun_type2 ) ( qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with three arguments. */
|
|
|
|
typedef qreal ( *fun_type3 ) ( qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with four arguments. */
|
|
|
|
typedef qreal ( *fun_type4 ) ( qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *fun_type5 ) ( qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *fun_type6 ) ( qreal, qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *fun_type7 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *fun_type8 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *fun_type9 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *fun_type10 ) ( qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions without arguments. */
|
|
|
|
typedef qreal ( *bulkfun_type0 ) ( int, int );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with a single arguments. */
|
|
|
|
typedef qreal ( *bulkfun_type1 ) ( int, int, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with two arguments. */
|
|
|
|
typedef qreal ( *bulkfun_type2 ) ( int, int, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with three arguments. */
|
|
|
|
typedef qreal ( *bulkfun_type3 ) ( int, int, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with four arguments. */
|
|
|
|
typedef qreal ( *bulkfun_type4 ) ( int, int, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *bulkfun_type5 ) ( int, int, qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *bulkfun_type6 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *bulkfun_type7 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *bulkfun_type8 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *bulkfun_type9 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with five arguments. */
|
|
|
|
typedef qreal ( *bulkfun_type10 ) ( int, int, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions with a variable argument list. */
|
2023-02-09 16:23:11 +01:00
|
|
|
typedef qreal ( *multfun_type ) ( const qreal*, qmusizetype );
|
2014-04-30 07:32:29 +02:00
|
|
|
|
|
|
|
/** @brief Callback type used for functions taking a string as an argument. */
|
|
|
|
typedef qreal ( *strfun_type1 ) ( const QString & );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions taking a string and a value as arguments. */
|
|
|
|
typedef qreal ( *strfun_type2 ) ( const QString &, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback type used for functions taking a string and two values as arguments. */
|
|
|
|
typedef qreal ( *strfun_type3 ) ( const QString &, qreal, qreal );
|
|
|
|
|
|
|
|
/** @brief Callback used for functions that identify values in a string. */
|
2023-02-09 16:23:11 +01:00
|
|
|
typedef int ( *identfun_type ) ( const QString &sExpr, qmusizetype *nPos, qreal *fVal, const QLocale &locale,
|
|
|
|
bool cNumbers, const QChar &decimal, const QChar &thousand );
|
2014-04-30 07:32:29 +02:00
|
|
|
|
|
|
|
/** @brief Callback used for variable creation factory functions. */
|
2014-05-21 15:51:47 +02:00
|
|
|
typedef qreal* ( *facfun_type ) ( const QString &, void* );
|
2014-04-30 07:32:29 +02:00
|
|
|
} // end of namespace
|
|
|
|
|
|
|
|
#endif
|