⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expreval.html

📁 数学表达式计算和解析 用c语言编写的,内含有例.速度较快
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<html>
<head>
<title>ExprEval Library</title>
<style type="text/css">
.valid {
  color: #00AA00;
}
.invalid {
  color: #FF0000;
}
.excomment {
  color: #0000FF;
}
.container {
  margin-top: 10px;
  margin-bottom: 10px;
  padding-left: 4px;
  padding-right: 4px;
  border-top: 1px solid #000000;
  border-right: 1px solid #000000;
  border-bottom: 1px solid #000000;
  border-left: 1px solid #000000;
  background-color: #BBBBBB;   
}
body {
  background-color: #AAAAAA;
}
</style>
</head>
<body>

<div align="center">
	<h1>ExprEval Library</h1>
	<hr>
</div>

<div align="left" class="container">
	<h2>Contents</h2>
	<h3>
		<ul>
			<a href="#Introduction">Introduction</a><br>
			<a href="#License">License</a><br>
			<a href="#Syntax">Expression Syntax</a><br>
			<a href="#Using">Using ExprEval in an Application</a><br>
			<a href="#FastVar">Fast Variable Access</a><br>
			<a href="#InternalFuncConst">Using the Internal Functions and Constants</a><br>
			<a href="#CustomFunc">Creating Custom Functions</a><br>
			<a href="#Reference">Reference</a><br>
			<a href="#Compiling">Compiling the ExprEval Library</a><br>
			<a href="#Drawbacks">Drawbacks/Problems</a><br>
			<a href="#Example">Example Use</a><br>
			<a href="#ExampleFast">Example Use with Fast Variable Access</a><br>
		</ul>
	</h3>
</div>

<div align="left" class="container">
	<h2><a name="Introduction">Introduction</a></h2>
	<blockquote>
		<p>ExprEval Help document.  This document is probably full of
			bugs and mispellings.  I may get around to proofreading
			it later.</p>
		<p>ExprEval is a C/C++ based expression evaluation library.
			It is entirely C based, but it comes with a C++ wrapper
			class that simplifies it's use.  The source code is
			provided for the library so that it can be recompiled
			for the specific system or compiler.</p>
		<p>ExprEval makes adding mathematical expression support to
			an application easy.  It takes an expression string and
			parses it, and then it can evaluate it over and over.
			This library also has support for functions, constants,
			and variables.  All of these items are stored in
			seperate lists so they can be shared among expressions or
			they can be private to a single expression or any mix and
			match.  It is up to the developer how to link them together.
			You can also create your own custom functions.  However,
			there is no C++ wrapper for custom functions, you must
			use the C routines for the function itself.  You can
			still use the C++ routines to add the functions to the
			lists and work with the expression, just the function
			code must use the C routines.</p>
	</blockquote>
</div>

<div align="left" class="container">
	<h2><a name="License">License</a></h2>
	<blockquote>
		<p>This library is licensed under the 
		<a href="license.txt">ExprEval License.</a>
		</p>
	</blockquote>
</div>

<div align="left" class="container">
	<h2><a name="Syntax">Expression Syntax</a></h2>
	<blockquote>
		<p>Expressions have pretty much the same syntax as they
			would have on paper, with the following exceptions:
			<ul>
				<li>Each expression must end with a semicolon. This
					is because the expression string can actually
					contain multiple expressions.  The semicolon is
					used to mark the end of the expression.<br>
					<b>Examples:</b>
					<ul>
						<li>4*x+5;</li>
						<li>y=5+2;g=4+6;</li>
						<li>y=r*sin(a);x=r*cos(a);</li>
					</ul>
				</li>
				<li>The asterisk '*' must be used to multiply.<br>
					<b>Examples:</b>
					<ul>
						<li>y=5*6; <b class="valid">Valid</b></li>
						<li>g=(x+1)*(x-1); <b class="valid">Valid</b></li>
						<li>g=(x+1)(x-1); <b class="invalid">Invalid</b></li>
					</ul>
				</li>
			</ul>
		</p>
		<p>More than one expression may be contained within an expression string.
			As shown above, each expression must end with a semicolon, even if
			only one expression is in the string. The value of an expression
			string is the value of the last expression in the string.<br>
			<b>Examlples:</b>
			<ul>
				<li>g=7; <b class="excomment">Value: 7</b></li>
				<li>k=z+1; <b class="excomment">Value: z+1</b></li>
				<li>r=4;k=6;o=9+r-k; <b class="excomment">Value: 9+r-k</b></li>
			</ul>
		</p>
		<p>Some functions may take reference parameters.  These parameters are
			references to other variables.  You can mix reference parameters
			with normal parameters.  The order of the normal parameters must
			remain the same and the order of the reference parameters must
			remain the same.<br>
			<b>Examples:</b>
			<ul>
				<li>min(1,2,3,4,&mval); <b class="excomment">&mval is a reference to a variable mval</b></li>
				<li>min(1,2,&mval,3,4); <b class="excomment">You may mix them inside like this.</b></li>
				<li>min(1,2,(&mval),3,4); <b class="invalid">You may not nest reference parameters in any way</b></li>
			</ul>
		</p>
		<p>Expressions may also be nested with parenthesis.<br>
		<b>Examples:</b>
			<ul>
				<li>y=sin(x-cos(5+max(4,5,6*x)));</li>
				<li>6+(5-2*(x+y));</li>
			</ul>
		</p>
		<p>Expressions may also have whitespace characters and comments.
			Whitespace characters such as newlines, linefeeds, carriage
			returns, spaces, and tabs are ignored.  Comments begin with
			the less than-sign '&lt;' and end with the greater than-sign
			'&gt;'.  Comments may be nested as well.<br>
			<b>Example:</b>
			<ul>
				<pre>
&lt;Set the x value&gt;
x = d * cos(r);

&lt;Set the y value&gt;
y = d * sin(r);

&lt;Comment out this for now

&lt;Flip the values&gt;
t = x;
x = y;
y = x;

Stop commenting out&gt;
				</pre>
			</ul>
		</p>
		<p>If a variable is used in an expression, but that variable does not exist,
			it is considered zero.  If it does exist then its value is used instead.
		</p>
	</blockquote>
</div>

<div align="left" class="container">
	<h2><a name="Using">Using ExprEval in an Application</a></h2>
	<blockquote>
		<p>Using ExprEval in an application can be a little difficult.
			You generally follow these steps:
			<ul>
				<li>Create function, variable, and constant lists</li>
				<li>Create the expression object</li>
				<li>Parse the expression</li>
				<li>Evaluate the expression as needed</li>
				<li>Free the expression object</li>
				<li>Free the function, variable, and constant lists</li>
			</ul>
			You can manipulate the lists in any order after their creation.
			However, functions and constants are translated during the parse,
			so after parsing an expression, manipulating the function and
			constant lists will make no change to an expression.  Variables
			can be manipulated after a parse to change the result of an
			expression.</p>
		<p><b>Function, variable, and constant list example:</b>
			<ul>
				<pre>
exprFuncList *f;
exprValList *v;
exprValList *c;
exprObj *o;
EXPRTYPE result;
int err;

/* Create function list */
err = exprFuncListCreate(&amp;f);
if(err != EXPR_ERROR_NOERROR)
	{
	printf("Function List Creation Error %d\n", err);
	return;
	}

/* Initialize internal functions */
err = exprFuncListInit(f);
if(err != EXPR_ERROR_NOERROR)
	{
	printf("Function List Initialization Error %d\n", err);
	printf("Some internal functions may not be usable\n");
	}

/* Create variable list */
err = exprValListCreate(&amp;v);
if(err != EXPR_ERROR_NOERROR)
	{
	printf("Variable List Creation Error %d\n", err);
	exprFuncListFree(f);
	return;
	}

/* Create the constant list */
err = exprValListCreate(&amp;c);
if(err != EXPR_ERROR_NOERROR)
	{
	printf("Constant List Creation Error %d\n", err);
	exprFuncListFree(f);
	exprValListFree(v);
	return;
	}

/* Initialize internal constants */
err = exprValListInit(c);
if(err != EXPR_ERROR_NOERROR)
	{
	printf("Constant List Initialization Error %d\n", err);
	printf("Some internal constants may not be usable\n");
	}

/* Add any application defined functions, constants, or variables to the lists here or down below */
				</pre>
			</ul>
		</p>
		<p><b>Expression object example:</b>
			<ul>
				<pre>
err = exprCreate(&o, f, v, c, NULL, 0);
if(err != EXPR_ERROR_NOERROR)
	{
	printf("Expression Object Creation Error %d\n", err);
	exprFuncListFree(f);
	exprValListFree(c);
	exprValListFree(v);
	return;
	}

/* Add any application defined functions, constants, or variables to the lists here or down below.
   This is the last time you can for the functions or constants. */
				</pre>
			</ul>
		</p>
		<p><b>Expression parse example:</b>
			<ul>
				<pre>
/* Functions and constants may be added or changed here */

err = exprParse(o, "2+sin(M_PI)+3*x;");
if(err != EXPR_ERROR_NOERROR)
	{
	printf("Expression Parse Error %d\n", err);

	/* Free objects and return */
	exprFree(o);

	/* Free lists */
	}

/* Changes to the function or constant lists do not change the expression now */
				</pre>
			</ul>
		</p>
		<p><b>Expression evaluation example:</b>
			<ul>
				<pre>
/* Add or change any variables */

err = exprEval(o, &result);
if(err != EXPR_ERROR_NOERRO)
	{
	printf("Expression Evaluation Error %d\n", err);
	}
else
	{
	printf("Expression Result: %f\n", result);
	}
				</pre>
			</ul>
		</p>
		<p><b>Free the expression object and lists example:</b>
			<ul>
				<pre>
exprFree(o);
exprFreeValList(v);
exprFreeValList(c);
exprFreeFuncList(f);
				</pre>
			</ul>
		</p>
	</blockquote>
</div>

<div align="left" class="container">
	<h2><a name="FastVar">Fast Variable Access</a></h2>
	<blockquote>
		<p>A new feature in ExprEval is fast variable access.  This
			is simply a technique of quickly accessing variables
			by directly accessing their memory locations instead
			of using the value list functions.  If you choose to
			enable fast variable access within ExprEval, you must
			NOT clear a variable list until after all expressions
			using it are completely finished evaluating.  Then you
			must reparse the expressions before using them again.
			The reason is simple.  When fast variable access is not
			used, the value list functions are used and they make
			sure to access the correct memory or add a variable if
			needed.  However, when fast variable access is used,
			the variable memory location is directly accessed, and
			the value list functions are not used.  If you clear a
			variable list and then evaluate an expression, it will
			access invalid memory.</p>
		<p>You can also use fast variable access in you application
			to dramatically speed up loops.  This is accomplished as
			follows:
			<ul>
				<li>Add the desired variable to the variable list</li>
				<li>Get the address of the variable with exprValListGetAddress</li>
				<li>In the loop(s), directly set/get the variable any time needed: *var = 0.0;</li>
			</ul>
		</p>
	</blockquote>
</div>

<div align="left" class="container">
	<h2><a name="InternalFuncConst">Using the Internal Functions and Constants</a></h2>
	<blockquote>
		<p>To use the internal functions, they must first be initialized
			into a function list with exprFuncListInit.  To use the
			internal constants, they must first be initialized into a
			value list with exprValListInit.  For a list of the
			internal functions and constants, see the application
			help template file: <a href="exprtmpl.html">ExprTmpl.html</a>
			You may use this file in your own applications so you don't
			have to write a detail on the functions in ExprEval.  All
			you have to do is add you own functions and constants to
			the file if there are any.
	</blockquote>
</div>

<div align="left" class="container">
	<h2><a name="CustomFunc">Creating Custom Functions</a></h2>
	<blockquote>
		<p>Custom functions must use the C routines, not the C++
			wrapper classes.  There are several macros that make
			creating custom functions easy.  They require that the
			variables passed to these functions be the same though.
			This is how a custom function should normally look:
			<ul>
				<pre>
int custom_func(struct _exprObj *o, struct _exprNode *n, int count, EXPRTYPE **refitems, int refcount, EXPRTYPE *val)
	{
	}
				</pre>
			</ul>
			o is a pointer to the expression object that called
			the function, n is a pointer to an array of nodes
			that are the parameters of this function, count is
			the number of items in the array (the number of parameters),
			refitems is an array of pointers to referenced variables,
			refcount is the number of referenced variables,
			and val is a pointer to a variable to recieve the result
			of the function.  The function should return an error value
			indicating the error status of the function.
		</p>
		<p>If the variables to the function are as above, the macros
			will make working with them easier.  Solving a function
			typically goes as follows:
			<ul>
				<li>Verifiy the number of arguments</li>
				<li>Evaluate the subnodes that you need.  You do not have to
				    evaluate every subnode if you do not need it</li>
				<li>Check for possible error conditions (division by zero)</li>
				<li>Clear math errors (If function uses any math routines)</li>
				<li>Calculate the result</li>
				<li>Check for math errors (If the function uses any math routines)</li>
				<li>return EXPR_ERROR_NOERROR</li>
			</ul>
		</p>
		<p><b>Example without the macros:</b>
			<ul>
				<pre>
int custom_func(struct _exprObj *o, struct _exprNode *n, int count, EXPRTYPE **refitems, int refcount, EXPRTYPE *val)
	{
	int err;
	EXPRTYPE d1, d2;

	/* Need 2 arguments */
	if(count != 2)
		return EXPR_ERROR_BADNUMBERARGUMENTS;

	/* Eval arg 1 */
	err = exprEvalNode(o, &(n[0]), &d1);
	if(err != EXPR_ERROR_NOERROR)
		return err;

	/* Eval arg 2 */
	err = exprEvalNode(o, &(n[1]), &d2);
	if(err != EXPR_ERROR_NOERROR)
		return err;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -