📄 example3.cpp
字号:
//---------------------------------------------------------------------------
//
// Math Utils Parser
//
// Example 3 - using the parser DLL
//
//---------------------------------------------------------------------------
#include <cstring>
#include <iostream>
#include <cstdlib> // for std::exit()
#include "muParserDLL.h"
#include "muParserError.h"
#define PARSER_CONST_PI 3.141592653589793238462643
#define PARSER_CONST_E 2.718281828459045235360287
//---------------------------------------------------------------------------
// Callbacks for postfix operators
double Mega(double a_fVal) { return a_fVal * 1.0e6; }
double Milli(double a_fVal) { return a_fVal / 1.0e3; }
//---------------------------------------------------------------------------
// Callbacks for infix operators
double Not(double v) { return v==0; }
//---------------------------------------------------------------------------
// Function callbacks
double Rnd(double v) { return v*std::rand() / (double)(RAND_MAX+1.0); }
double SampleQuery(const char *szMsg)
{
if (szMsg) std::cout << szMsg << std::endl;
return 999;
}
double Sum(const double *a_afArg, int a_iArgc)
{
double fRes=0;
for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];
return fRes;
}
//---------------------------------------------------------------------------
// Binarty operator callbacks
double Add(double v1, double v2) { return v1+v2; }
double Mul(double v1, double v2) { return v1*v2; }
//---------------------------------------------------------------------------
// Factory function for creating new parser variables
// This could as well be a function performing database queries.
double* AddVariable(const char *a_szName)
{
static double afValBuf[100]; // I don't want dynamic allocation here
static int iVal = 0; // so i used this buffer
std::cout << "Generating new variable \""
<< a_szName << "\" (slots left: "
<< 99-iVal << ")" << std::endl;
afValBuf[iVal] = 0;
if (iVal>=99)
throw mu::ParserError("Variable buffer overflow.");
return &afValBuf[iVal++];
}
//---------------------------------------------------------------------------
// Function to detect binary values in an expression string
bool IsBinVal(const char *a_szExpr, int &a_iPos, double &a_fVal)
{
if (a_szExpr[0]!='#')
return false;
unsigned iVal = 0, iBits = sizeof(iVal)*8;
unsigned i=0; // BUGFIX of non-standard-conformity of VC++
for (; (a_szExpr[i+1]=='0' || a_szExpr[i+1]=='1') && i<iBits; ++i)
iVal |= (int)(a_szExpr[i+1]=='1') << ((iBits-1)-i);
if (i==0)
return false;
if (i==iBits)
throw mu::ParserError("Binary to integer conversion error (overflow).");
a_fVal = (unsigned)(iVal >> (iBits-i) );
a_iPos += i+1;
return true;
}
//---------------------------------------------------------------------------
void Intro()
{
std::cout << "---------------------------------------\n";
std::cout << "\n";
std::cout << " Math Parser sample application\n";
std::cout << " (DLL version)\n";
std::cout << "\n";
std::cout << "---------------------------------------\n";
std::cout << "Commands:\n";
std::cout << " list var - list parser variables\n";
std::cout << " list exprvar - list expression variables\n";
std::cout << " list const - list all numeric parser constants\n";
std::cout << " exit - exits the parser\n";
std::cout << "Constants:\n";
std::cout << " \"_e\" 2.718281828459045235360287\n";
std::cout << " \"_pi\" 3.141592653589793238462643\n";
std::cout << "---------------------------------------\n";
std::cout << "Please enter a formula:\n";
}
//---------------------------------------------------------------------------
// Callback function for parser errors
void OnError()
{
std::cout << "\nError:\n";
std::cout << "------\n";
std::cout << "Message: " << mupGetErrorMsg() << "\n";
std::cout << "Token: " << mupGetErrorToken() << "\n";
std::cout << "Position: " << mupGetErrorPos() << "\n";
std::cout << "Errc: " << mupGetErrorCode() << "\n";
}
//---------------------------------------------------------------------------
void ListVar(parser_handle a_hParser)
{
int iNumVar = mupGetVarNum(a_hParser);
if (iNumVar==0)
{
std::cout << "No variables defined\n";
return;
}
std::cout << "\nExpression variables:\n";
std::cout << "---------------------\n";
std::cout << "Number: " << iNumVar << "\n";
for (int i=0; i<iNumVar; ++i)
{
const char *szName = 0;
double *pVar = 0;
mupGetVar(a_hParser, i, &szName, &pVar);
std::cout << "Name: " << szName << " Address: [0x" << pVar << "]\n";
}
}
//---------------------------------------------------------------------------
void ListExprVar(parser_handle a_hParser)
{
int iNumVar = mupGetExprVarNum(a_hParser);
if (iNumVar==0)
{
std::cout << "Expression dos not contain variables\n";
return;
}
std::cout << "\nExpression variables:\n";
std::cout << "---------------------\n";
std::cout << "Expression: " << mupGetExpr(a_hParser) << "\n";
std::cout << "Number: " << iNumVar << "\n";
for (int i=0; i<iNumVar; ++i)
{
const char *szName = 0;
double *pVar = 0;
mupGetExprVar(a_hParser, i, &szName, &pVar);
std::cout << "Name: " << szName << " Address: [0x" << pVar << "]\n";
}
}
//---------------------------------------------------------------------------
void ListConst(parser_handle a_hParser)
{
int iNumVar = mupGetConstNum(a_hParser);
if (iNumVar==0)
{
std::cout << "No constants defined\n";
return;
}
std::cout << "\nParser constants:\n";
std::cout << "---------------------\n";
std::cout << "Number: " << iNumVar << "\n";
for (int i=0; i<iNumVar; ++i)
{
const char *szName = 0;
double fVal = 0;
mupGetConst(a_hParser, i, &szName, fVal);
std::cout << " " << szName << " = " << fVal << "\n";
}
}
//---------------------------------------------------------------------------
/** \brief Check for external keywords.
*/
bool CheckKeywords(const char *a_szLine, parser_handle a_hParser)
{
std::string sLine(a_szLine);
if (sLine=="quit")
{
std::exit(0);
}
else if (sLine=="list var")
{
ListVar(a_hParser);
return true;
}
else if (sLine=="list exprvar")
{
ListExprVar(a_hParser);
return true;
}
else if (sLine=="list const")
{
ListConst(a_hParser);
return true;
}
return false;
}
//---------------------------------------------------------------------------
void Calc()
{
char szLine[100];
double fVal = 0,
afVarVal[] = { 1, 2 }; // Values of the parser variables
parser_handle hParser;
hParser = mupInit(); // initialize the parser
// Set an error handler [optional]
// the only function that does not take a parser instance handle
mupSetErrorHandler(OnError);
// Set a variable factory
mupSetVarFactory(hParser, AddVariable);
// Define parser variables and bind them to C++ variables [optional]
mupDefineConst(hParser, "const1", 1);
mupDefineConst(hParser, "const2", 2);
mupDefineStrConst(hParser, "strBuf", "Hallo welt");
// Define parser variables and bind them to C++ variables [optional]
mupDefineVar(hParser, "a", &afVarVal[0]);
mupDefineVar(hParser, "b", &afVarVal[1]);
// Define postfix operators [optional]
mupDefinePostfixOprt(hParser, "M", Mega);
mupDefinePostfixOprt(hParser, "m", Milli);
// Define infix operator [optional]
mupDefineInfixOprt(hParser, "!", Not);
// Define functions [optional]
mupDefineStrFun(hParser, "query", SampleQuery, false); // Add an unoptimizeable function
mupDefineFun1(hParser, "rnd", Rnd, false); // Add an unoptimizeable function
mupDefineFun1(hParser, "rnd2", Rnd);
mupDefineMultFun(hParser, "_sum", Sum); // "sum" is already a default function
// Define binary operators [optional]
mupDefineOprt(hParser, "add", Add, 0);
mupDefineOprt(hParser, "mul", Mul, 1);
// Add support for detection of binary values
mupAddValIdent(hParser, IsBinVal);
while ( fgets(szLine, 99, stdin) )
{
szLine[strlen(szLine)-1] = 0; // overwrite the newline
if (CheckKeywords(szLine, hParser))
continue;
mupSetExpr(hParser, szLine);
fVal = mupEval(hParser);
/*
// Without an Error handler function
// you must use this for error treatment:
if (mupError())
{
std::cout << "\nError:\n";
std::cout << "------\n";
std::cout << "Message: " << mupGetErrorMsg() << "\n";
std::cout << "Token: " << mupGetErrorToken() << "\n";
std::cout << "Position: " << mupGetErrorPos() << "\n";
std::cout << "Errc: " << mupGetErrorCode() << "\n";
continue;
}
*/
if (!mupError())
std::cout << fVal << "\n";
} // while
// parser.EnableOptimizer(true); // set optimizer state (this is the default)
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
Intro();
Calc();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -