CPPEVAL - A C ++ expression analysis library

xiaoxiao2021-03-05  50

When writing a program, it will be used in a lot of ways to use expression analysis, such as the user interface, system configuration. Although this is not a difficult thing for most programmers, it is necessary to ensure that the expression analysis is complete and the function is powerful, not a matter. You want to handle similar " AA * AA / B - B / -1 / 2/2/2 - 5 ** 2 -100 (AA * AA / B - B / -2 / 2" / 2 - 5 ** 2 -100) RETURN1 () Negative (1) sum (1, 2, 3, SUM (1 2 * 5-7, 555, 111)) "This metamorphosis Expression? (In this expression, not only constant, variables, functions, but also the number of parameters of some functions or variable) Use CPPEVAL, you only need include a header file!

interface

Template Number eval (const char * expression); this directly calculates an expression, supports - * / () and one yuan -, and supports ** as a passer

Template Number Eval (const char * expression, const :: std :: map <:: std :: string, number> & variables); this is also supported in addition to supporting the above features. The Variables you provide is the map of the variable to the number.

Template Number Eval (const char * expression, const :: string, number> & variables, functions & funcs); this is supported in addition to supporting the above features function. For specific definition methods, please refer to the example

Cppeval.h

#ifndef CPP_EVAL_H_DFF520DB406EDCF31AB9A538F7E1C3BD_20040721 __ # define CPP_EVAL_H_DFF520DB406EDCF31AB9A538F7E1C3BD_20040721__

#include #include #include #include #include #include

Namespace CPP_EVAL {

Template Number EVAL (const char * expression);

Template Number Eval (Const Char * Expression, Const :: std :: map <:: std :: string, number> & variables);

template number eval (const char * expression, const :: std :: map <:: std :: string, number> & variables, functions & funcs); class eval_exception: public :: std :: logic_error {public: evAl_exception (const char * DESC): logic_error (dec) {}};

template class dummy_functions {public: number operator () (const char *, const :: std :: vector & params) {throw eval_exception ( "unexisting function called"); // return number (); }};

Template Number Eval (const char * express) {:: std :: map <:: std :: string, number> variables; dummy_functions funcs; return evAl (Expression, variables, funcs);}

template number eval (const char * expression, const :: std :: map <:: std :: string, number> & variables) {dummy_functions funcs; return eval (expression, variables, funcs); }

template class evaler {const :: std :: map <:: std :: string, number> & mVariables; functions & mFuncs; const char * mCurrent; enum Type {ADD_OR_POSITIVE = ' ', SUBTRACT_OR_NEGATIVE = ', Multiply =' * ', divide =' / ', power =' ~ ', left_bracket =' (', right_bracket =') ', parameter_seperator =', ', Identifier = 257, Number = 258, Finished = 259}; type mtype; std :: string midentifier; Number Mvalue; Void Look_Ahead () {for (;;) {IF (iSSpace (* mcurrent)) { mcurrent; continue;} else if (* mcurrent == ' * '&& * (mCurrent 1) ==' * ') mType = POWER, mCurrent = 2; else if (* mCurrent == ADD_OR_POSITIVE || * mCurrent == SUBTRACT_OR_NEGATIVE || * mCurrent == MULTIPLY || * mCurrent == DIVIDE || * mcurrent == Left_ BRACKET || * mCurrent == RIGHT_BRACKET || * mCurrent == PARAMETER_SEPERATOR) mType = (Type) * mCurrent, mCurrent; else if (isalpha (* mCurrent)) {mType = IDENTIFIER; mIdentifier.clear (); mIdentifier = * mcurrent; mcurrent; while (isalpha (* mcurrent) || isdigit (* mcurrent)) MIDENTIFIER = * MCURRENT,

mcurrent;} else = finished; else {mtype = number; istringstream ISS (McURRENT); ISS >> Mvalue; if (! is) throw eval_exception ("Error In Number Format"); McURRENT = ISS.RDBUF () -> Pubseekoff (0, ios :: cur, ios :: in);} Break;}} void match (mtype type) {if (mtype == type) Look_ahead (); else throw eval_exception ( "unmatched token");} number expression () {// expression -> higher_expression expression_R number result = expression_R (higher_expression ()); return result;} number expression_R (const number & left) {// expression_R -> higher_expression Expression_r | - Higher_Expression Expression_r | / E / NUMBER Result = Left; IF (mtype == add_or_positive) match (ADD_OR_POSITIVE), result = expression_R (left higher_expression ()); else if (mType == SUBTRACT_OR_NEGATIVE) match (SUBTRACT_OR_NEGATIVE), result = expression_R (left - higher_expression ()); return result;} number higher_expression () {/ / higher_expression -> sign_expression higher_expression_R return higher_expression_R (sign_expression ());} number higher_expression_R (const number & left) {// higher_expression_R -> * sign_expression higher_expression_R | / sign_expression higher_expression_R | / e / number result = left;

if (mType == MULTIPLY) match (MULTIPLY), result = higher_expression_R (left * sign_expression ()); else if (mType == DIVIDE) match (DIVIDE), result = higher_expression_R (left / sign_expression ()); return result; } number sign_expression () {// sign_expression -> sign_expression | - sign_expression | power_expression number result; if (mType == ADD_OR_POSITIVE) match (ADD_OR_POSITIVE), result = sign_expression (); else if (mType == SUBTRACT_OR_NEGATIVE) match (SUBTRACT_OR_NEGATIVE ), result = - sign_expression (); else result = power_expression (); return result;} number power_expression () {// power_expression -> factor ** power_expression | factor number result = factor (); if (mType == POWER) Match (power), result = std :: pow (result, static_cast )))); Return Result;} Number Factor () {// factor -> number | (expression) | lang_structure number result; if (mType == NUMBER) result = mValue, match (NUMBER); else if (mType == LEFT_BRACKET) match (LEFT_BRACKET), result = expression (), match (RIGHT_BRACKET); else result = lang_structure (); return result;} number lang_structure () {// lang_structure -> identifier lang_tail std :: string id = mIdentifier; match (iDENTIFIER); return lang_tail (id); Number LANG_TAIL (Const std :: string &

ID) {// LANG_TAIL -> (parameter_list | / e / number result; if (mtype == left_bracket) {match (left_bracket); std :: vector param = parameter_list (); result = mfuncs (id.c_str (), param);} else {if (id) == mvariables.end ()) throw eval_exception ("cannot find variable"); result = mvariables.find (ID) -> second;} returnrate result } Std :: Vector parameter_list () {// parameter_list -> | express parameter_tail std :: vector result; for (;;) {if (mtype == right_bracket) {match (Right_bracket); Break;} result.push_back (expression ()); parameter_tail (result);} Return Result;} void parameter_tail (std :: vector & param) {// parameter_tail ->, e Xpression parameter_tail | / e / if (mtype == parameter_seperator) Match (parameter_seperator), param.push_back (express: evaler);} public: evaler (const: evalent); string, number> & variables, functions & funcs): mVariables (variables), mFuncs (funcs) {} number operator () (const char * expr) {mCurrent = expr; look_ahead (); number result = expression (); if ( MTYPE! = finished) Throw Eval_Exception ("Unexpect Expression Format"; Return Result;}};

template number eval (const char * expression, const :: std :: map <:: std :: string, number> & variables, functions & funcs) {return evaler (variables, Funcs (Expression);}};

# ENDIF / / CPP_EVAL_H_DFF520DB406EDCF31AB9A538F7E1C3BD_20040721__

C program for testing:

#include "cppeval.h" #include #include

Using namespace std;

Class funnces {public: int operator () (const :: std :: vector & params) {if (Strics) == 0) {ix (paraMs.size )! = 0) throw 1; Return 1;} else IF (Stricmp (Name, "NEGATIVE") == 0) {IF (params.size ()! = 1) throw 1; return - params [0];} ELSE IF (StricsP (Name, "SUM") == 0) {Return Acumulation (params.begin (), params.end (), 0);}}};

INT main () {map variables; variables ["aa"] = 100; variables ["b"] = 200; functions f; cout << CPP_EVAL :: EVAL (" aa * aa / b - b / -2 / 2/2 - 5 ** 2 -100 "" (AA * AA / B - B / -2 / 2/2/2/2 ** 2 -100) "" RETURN1 () NEGATIVE (1) SUM (1, 2, 3, SUM (1 2 * 5-7, 555, 111) ", Variables, f) << Endl; Return 0;

转载请注明原文地址:https://www.9cbs.com/read-36667.html

New Post(0)