📄 example1.cpp
字号:
//---------------------------------------------------------------------------
//
// Math Utils Parser
//
// Example 1 - using the parser as a static library
//
//---------------------------------------------------------------------------
#include "muParserTest.h"
/** \brief This macro will enable mathematical constants like M_PI. */
#define _USE_MATH_DEFINES
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <string>
#include <iostream>
#include "muParser.h"
#if defined(_MSC_VER) && (_MSC_VER>1200)
#if defined(_DEBUG)
#pragma comment(lib, "../ParserLib/muParserDbg.lib")
#else
#pragma comment(lib, "../ParserLib/muParser.lib")
#endif
#endif
using namespace std;
using namespace mu;
// Operator callback functions
value_type Mega(value_type a_fVal) { return a_fVal * 1e6; }
value_type Milli(value_type a_fVal) { return a_fVal / (value_type)1e3; }
value_type Rnd(value_type v) { return v*std::rand()/(value_type)(RAND_MAX+1.0); }
value_type Not(value_type v) { return v==0; }
value_type Add(value_type v1, value_type v2) { return v1+v2; }
value_type Mul(value_type v1, value_type v2) { return v1*v2; }
mu::value_type SampleQuery(const char *szMsg)
{
if (szMsg) std::cout << szMsg << std::endl;
return 999;
};
//---------------------------------------------------------------------------
// Factory function for creating new parser variables
// This could as well be a function performing database queries.
double* AddVariable(const char *a_szName)
{
// I don't want dynamic allocation here, so i used this static buffer
// If you want dynamic allocation you must allocate all variables dynamically
// in order to delete them later on. Or you find other ways to keep track of
// variables that have been created implicitely.
static double afValBuf[100];
static int iVal = 0;
cout << "Generating new variable \""
<< a_szName << "\" (slots left: "
<< 99-iVal << ")" << endl;
afValBuf[iVal] = 0;
if (iVal>=99)
throw mu::ParserError("Variable buffer overflow.");
return &afValBuf[iVal++];
}
//---------------------------------------------------------------------------
void SelfTest()
{
std::cout << "---------------------------------------\n";
std::cout << "\n";
std::cout << " Math Parser sample application\n";
std::cout << "\n";
std::cout << "---------------------------------------\n";
mu::Test::ParserTester pt;
pt.Run();
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 << "Enter a formula or a command:\n";
}
//---------------------------------------------------------------------------
void ListVar(const mu::ParserBase &parser)
{
// Query the used variables (must be done after calc)
mu::varmap_type variables = parser.GetVar();
if (!variables.size())
return;
cout << "\nParser variables:\n";
cout << "-----------------\n";
cout << "Number: " << (int)variables.size() << "\n";
varmap_type::const_iterator item = variables.begin();
for (; item!=variables.end(); ++item)
cout << "Name: " << item->first << " Address: [0x" << item->second << "]\n";
}
//---------------------------------------------------------------------------
void ListConst(const mu::ParserBase &parser)
{
cout << "\nParser constants:\n";
cout << "-----------------\n";
mu::valmap_type cmap = parser.GetConst();
if (!cmap.size())
{
cout << "Expression does not contain constants\n";
}
else
{
valmap_type::const_iterator item = cmap.begin();
for (; item!=cmap.end(); ++item)
cout << " " << item->first << " = " << item->second << "\n";
}
}
//---------------------------------------------------------------------------
void ListExprVar(const mu::ParserBase &parser)
{
std::string sExpr = parser.GetExpr();
if (sExpr.length()==0)
{
cout << "Expression string is empty\n";
return;
}
// Query the used variables (must be done after calc)
cout << "\nExpression variables:\n";
cout << "---------------------\n";
cout << "Expression: " << parser.GetExpr() << "\n";
varmap_type variables = parser.GetUsedVar();
if (!variables.size())
{
cout << "Expression does not contain variables\n";
}
else
{
cout << "Number: " << (int)variables.size() << "\n";
mu::varmap_type::const_iterator item = variables.begin();
for (; item!=variables.end(); ++item)
cout << "Name: " << item->first << " Address: [0x" << item->second << "]\n";
}
}
//---------------------------------------------------------------------------
/** \brief Check for external keywords.
*/
bool CheckKeywords(const char *a_szLine, mu::ParserBase &a_Parser)
{
std::string sLine(a_szLine);
if (sLine=="quit")
{
exit(0);
}
else if (sLine=="list var")
{
ListVar(a_Parser);
return true;
}
else if (sLine=="list const")
{
ListConst(a_Parser);
return true;
}
else if (sLine=="list exprvar")
{
ListExprVar(a_Parser);
return true;
}
else if (sLine=="list const")
{
ListConst(a_Parser);
return true;
}
return false;
}
//---------------------------------------------------------------------------
void Calc()
{
char line[100];
mu::Parser parser;
// Add some variables
value_type vVarVal[] = { 1, 2 }; // Values of the parser variables
parser.DefineVar("a", &vVarVal[0]); // Assign Variable names and bind them to the C++ variables
parser.DefineVar("b", &vVarVal[1]);
parser.DefineStrConst("strBuf", "hello world");
// Add user defined unary operators
parser.DefinePostfixOprt("M", Mega);
parser.DefinePostfixOprt("m", Milli);
parser.DefineInfixOprt("!", Not);
parser.DefineFun("query", SampleQuery, false);
parser.DefineFun("rnd", Rnd, false); // Add an unoptimizeable function
parser.DefineOprt("add", Add, 0);
parser.DefineOprt("mul", Mul, 1);
// Define the variable factory
parser.SetVarFactory(AddVariable);
parser.EnableOptimizer(false); // set optimizer state (true is the default)
while(true)
{
try
{
while ( fgets(line, 99, stdin) )
{
line[std::strlen(line)-1] = 0; // overwrite nl
if (CheckKeywords(line, parser))
continue;
parser.SetExpr(line);
cout << parser.Eval() << "\n";
cout << parser.Eval() << "\n";
}
}
catch(mu::Parser::exception_type &e)
{
cout << "\nError:\n";
cout << "------\n";
cout << "Message: " << e.GetMsg() << "\n";
cout << "Formula: " << e.GetExpr() << "\n";
cout << "Token: " << e.GetToken() << "\n";
cout << "Position: " << (int)e.GetPos() << "\n";
cout << "Errc: " << e.GetCode() << "\n";
}
} // while running
}
//---------------------------------------------------------------------------
int main(int argc, char* argv[])
{
using namespace mu;
SelfTest();
try
{
Calc();
}
catch(Parser::exception_type &e)
{
// Only erros raised during the initialization will end up here
// formula related errors are treated in Calc()
cout << "Initialization error: " << e.GetMsg() << endl;
while(1);
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -