Rev 161 | Rev 4078 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev | Author | Line No. | Line |
---|---|---|---|

161 | Franz | 1 | Function parser for C++ v2.63 by Warp. |

2 | ====================================== |
||

3 | |||

4 | Optimization code contributed by Bisqwit (http://iki.fi/bisqwit/) |
||

5 | |||

6 | |||

7 | The usage license of this library is located at the end of this text file. |
||

8 | |||

9 | |||

10 | |||

11 | What's new in v2.63 |
||

12 | ------------------- |
||

13 | - Some tiny fixes to make the library more compatible with BCB4. |
||

14 | |||

15 | What's new in v2.62 |
||

16 | ------------------- |
||

17 | - Only an addition to the usage license. (Please read it.) |
||

18 | |||

19 | What's new in v2.61 |
||

20 | ------------------- |
||

21 | - Tiny bug fix: Tabs and carriage returns now allowed in the function |
||

22 | string. |
||

23 | |||

24 | What's new in v2.6 |
||

25 | ------------------- |
||

26 | - Added a new method: GetParseErrorType(). This method can be used to |
||

27 | get the type of parsing error (which can be used eg. for customized |
||

28 | error messages in another language). |
||

29 | - Added working copy constructor and assignment operator (using the |
||

30 | copy-on-write technique for efficiency). See the "Usage" section for |
||

31 | details. |
||

32 | - Fixed a problem with the comma operator (,): Comma is not allowed |
||

33 | anymore anywhere else than separating function parameters. In other |
||

34 | words, comma is not an operator anymore (just a parameter separator). |
||

35 | |||

36 | |||

37 | |||

38 | ============================================================================= |
||

39 | - Preface |
||

40 | ============================================================================= |
||

41 | |||

42 | Often people need to ask some mathematical expression from the user and |
||

43 | then evaluate values for that expression. The simplest example is a program |
||

44 | which draws the graphic of a user-defined function on screen. |
||

45 | |||

46 | This library adds C-style function string parsing to the program. This |
||

47 | means that you can evaluate the string "sqrt(1-x^2+y^2)" with given values |
||

48 | of 'x' and 'y'. |
||

49 | |||

50 | The library is intended to be very fast. It byte-compiles the function |
||

51 | string at parse time and interpretes this byte-code at evaluation time. |
||

52 | The evaluation is straightforward and no recursions are done (uses stack |
||

53 | arithmetic). |
||

54 | Empirical tests show that it indeed is very fast (specially compared to |
||

55 | libraries which evaluate functions by just interpreting the raw function |
||

56 | string). |
||

57 | |||

58 | The library is made in ISO C++ and requires a standard-conforming C++ |
||

59 | compiler. |
||

60 | |||

61 | |||

62 | ============================================================================= |
||

63 | - Usage |
||

64 | ============================================================================= |
||

65 | |||

66 | To use the FunctionParser class, you have to include "fparser.hh". When |
||

67 | compiling, you have to compile fparser.cc and link it to the main program. |
||

68 | You can also make a library from the fparser.cc (see the help on your |
||

69 | compiler to see how this is done). |
||

70 | |||

71 | |||

72 | * Conditional compiling: |
||

73 | --------------------- |
||

74 | |||

75 | There is a set of precompiler options at the beginning of fparser.cc |
||

76 | which can be used for setting certain features on or off. These lines |
||

77 | can be commented or uncommented depending on the desired behaviour: |
||

78 | |||

79 | NO_ASINH : (Default on) |
||

80 | By default the library does not support the asinh(), acosh() |
||

81 | and atanh() functions because they are not part of the ISO C++ |
||

82 | standard. If your compiler supports them and you want the |
||

83 | parser to support them as well, comment this line. |
||

84 | |||

85 | DISABLE_EVAL : (Default off) |
||

86 | The eval() function can be dangerous because it can cause an |
||

87 | infinite recursion in the parser when not used properly (which |
||

88 | causes the function stack created by the compiler to overflow). |
||

89 | If this possibility should be prevented then the eval() function |
||

90 | can be disabled completely by uncommenting this line. |
||

91 | |||

92 | SUPPORT_OPTIMIZER : (Default on) |
||

93 | If you are not going to use the Optimize() method, you can comment |
||

94 | this line out to speed-up the compilation of fparser.cc a bit, as |
||

95 | well as making the binary a bit smaller. (Optimize() can still be |
||

96 | called, but it will not do anything.) |
||

97 | |||

98 | |||

99 | * Copying and assignment: |
||

100 | ---------------------- |
||

101 | |||

102 | The class implements a safe copy constructor and assignment operator. |
||

103 | |||

104 | It uses the copy-on-write technique for efficiency. This means that |
||

105 | when copying or assigning a FunctionParser instance, the internal data |
||

106 | (which in some cases can be quite lengthy) is not immediately copied |
||

107 | but only when the contents of the copy (or the original) are changed. |
||

108 | This means that copying/assigning is a very fast operation, and if |
||

109 | the copies are never modified then actual data copying never happens |
||

110 | either. |
||

111 | |||

112 | The Eval() and EvalError() methods of the copy can be called without |
||

113 | the internal data being copied. |
||

114 | Calling Parse(), Optimize() or the user-defined constant/function adding |
||

115 | methods will cause a deep-copy. |
||

116 | |||

117 | (C++ basics: The copy constructor is called when a new FunctionParser |
||

118 | instance is initialized with another, ie. like: |
||

119 | |||

120 | FunctionParser fp2 = fp1; // or: FunctionParser fp2(fp1); |
||

121 | |||

122 | or when a function takes a FunctionParser instance as parameter, eg: |
||

123 | |||

124 | void foo(FunctionParser p) // takes an instance of FunctionParser |
||

125 | { ... } |
||

126 | |||

127 | The assignment operator is called when a FunctionParser instance is |
||

128 | assigned to another, like "fp2 = fp1;".) |
||

129 | |||

130 | |||

131 | * Short descriptions of FunctionParser methods: |
||

132 | -------------------------------------------- |
||

133 | |||

134 | int Parse(const std::string& Function, const std::string& Vars, |
||

135 | bool useDegrees = false); |
||

136 | |||

137 | Parses the given function and compiles it to internal format. |
||

138 | Return value is -1 if successful, else the index value to the location |
||

139 | of the error. |
||

140 | |||

141 | |||

142 | const char* ErrorMsg(void) const; |
||

143 | |||

144 | Returns an error message corresponding to the error in Parse(), or 0 if |
||

145 | no such error occurred. |
||

146 | |||

147 | |||

148 | ParseErrorType GetParseErrorType() const; |
||

149 | |||

150 | Returns the type of parsing error which occurred. Possible return types |
||

151 | are described in the long description. |
||

152 | |||

153 | |||

154 | double Eval(const double* Vars); |
||

155 | |||

156 | Evaluates the function given to Parse(). |
||

157 | |||

158 | |||

159 | int EvalError(void) const; |
||

160 | |||

161 | Returns 0 if no error happened in the previous call to Eval(), else an |
||

162 | error code >0. |
||

163 | |||

164 | |||

165 | void Optimize(); |
||

166 | |||

167 | Tries to optimize the bytecode for faster evaluation. |
||

168 | |||

169 | |||

170 | bool AddConstant(const std::string& name, double value); |
||

171 | |||

172 | Add a constant to the parser. Returns false if the name of the constant |
||

173 | is invalid, else true. |
||

174 | |||

175 | |||

176 | bool AddFunction(const std::string& name, |
||

177 | double (*functionPtr)(const double*), |
||

178 | unsigned paramsAmount); |
||

179 | |||

180 | Add a user-defined function to the parser (as a function pointer). |
||

181 | Returns false if the name of the function is invalid, else true. |
||

182 | |||

183 | |||

184 | bool AddFunction(const std::string& name, FunctionParser&); |
||

185 | |||

186 | Add a user-defined function to the parser (as a FunctionParser instance). |
||

187 | Returns false if the name of the function is invalid, else true. |
||

188 | |||

189 | |||

190 | |||

191 | * Long descriptions of FunctionParser methods: |
||

192 | ------------------------------------------- |
||

193 | |||

194 | --------------------------------------------------------------------------- |
||

195 | int Parse(const std::string& Function, const std::string& Vars, |
||

196 | bool useDegrees = false); |
||

197 | --------------------------------------------------------------------------- |
||

198 | |||

199 | Parses the given function (and compiles it to internal format). |
||

200 | Destroys previous function. Following calls to Eval() will evaluate |
||

201 | the given function. |
||

202 | The strings given as parameters are not needed anymore after parsing. |
||

203 | |||

204 | Parameters: |
||

205 | Function : String containing the function to parse. |
||

206 | Vars : String containing the variable names, separated by commas. |
||

207 | Eg. "x,y", "VarX,VarY,VarZ,n" or "x1,x2,x3,x4,__VAR__". |
||

208 | useDegrees: (Optional.) Whether to use degrees or radians in |
||

209 | trigonometric functions. (Default: radians) |
||

210 | |||

211 | Variables can have any size and they are case sensitive (ie. "var", |
||

212 | "VAR" and "Var" are *different* variable names). Letters, digits and |
||

213 | underscores can be used in variable names, but the name of a variable |
||

214 | can't begin with a digit. Each variable name can appear only once in |
||

215 | the string. Function names are not legal variable names. |
||

216 | |||

217 | Using longer variable names causes no overhead whatsoever to the Eval() |
||

218 | method, so it's completely safe to use variable names of any size. |
||

219 | |||

220 | The third, optional parameter specifies whether angles should be |
||

221 | interpreted as radians or degrees in trigonometrical functions. |
||

222 | If not specified, the default value is radians. |
||

223 | |||

224 | Return values: |
||

225 | -On success the function returns -1. |
||

226 | -On error the function returns an index to where the error was found |
||

227 | (0 is the first character, 1 the second, etc). If the error was not |
||

228 | a parsing error returns an index to the end of the string + 1. |
||

229 | |||

230 | Example: parser.Parse("3*x+y", "x,y"); |
||

231 | |||

232 | |||

233 | --------------------------------------------------------------------------- |
||

234 | const char* ErrorMsg(void) const; |
||

235 | --------------------------------------------------------------------------- |
||

236 | |||

237 | Returns a pointer to an error message string corresponding to the error |
||

238 | caused by Parse() (you can use this to print the proper error message to |
||

239 | the user). If no such error has occurred, returns 0. |
||

240 | |||

241 | |||

242 | --------------------------------------------------------------------------- |
||

243 | ParseErrorType GetParseErrorType() const; |
||

244 | --------------------------------------------------------------------------- |
||

245 | |||

246 | Returns the type of parse error which occurred. |
||

247 | |||

248 | This method can be used to get the error type if ErrorMsg() is not |
||

249 | enough for printing the error message. In other words, this can be |
||

250 | used for printing customized error messages (eg. in another language). |
||

251 | If the default error messages suffice, then this method doesn't need |
||

252 | to be called. |
||

253 | |||

254 | FunctionParser::ParseErrorType is an enumerated type inside the class |
||

255 | (ie. its values are accessed like "FunctionParser::SYNTAX_ERROR"). |
||

256 | |||

257 | The possible values for FunctionParser::ParseErrorType are listed below, |
||

258 | along with their equivalent error message returned by the ErrorMsg() |
||

259 | method: |
||

260 | |||

261 | FP_NO_ERROR : If no error occurred in the previous call to Parse(). |
||

262 | SYNTAX_ERROR : "Syntax error" |
||

263 | MISM_PARENTH : "Mismatched parenthesis" |
||

264 | MISSING_PARENTH : "Missing ')'" |
||

265 | EMPTY_PARENTH : "Empty parentheses" |
||

266 | EXPECT_OPERATOR : "Syntax error: Operator expected" |
||

267 | OUT_OF_MEMORY : "Not enough memory" |
||

268 | UNEXPECTED_ERROR : "An unexpected error ocurred. Please make a full bug " |
||

269 | "report to warp@iki.fi" |
||

270 | INVALID_VARS : "Syntax error in parameter 'Vars' given to " |
||

271 | "FunctionParser::Parse()" |
||

272 | ILL_PARAMS_AMOUNT : "Illegal number of parameters to function" |
||

273 | PREMATURE_EOS : "Syntax error: Premature end of string" |
||

274 | EXPECT_PARENTH_FUNC: "Syntax error: Expecting ( after function" |
||

275 | |||

276 | |||

277 | --------------------------------------------------------------------------- |
||

278 | double Eval(const double* Vars); |
||

279 | --------------------------------------------------------------------------- |
||

280 | |||

281 | Evaluates the function given to Parse(). |
||

282 | The array given as parameter must contain the same amount of values as |
||

283 | the amount of variables given to Parse(). Each value corresponds to each |
||

284 | variable, in the same order. |
||

285 | |||

286 | Return values: |
||

287 | -On success returns the evaluated value of the function given to |
||

288 | Parse(). |
||

289 | -On error (such as division by 0) the return value is unspecified, |
||

290 | probably 0. |
||

291 | |||

292 | Example: |
||

293 | |||

294 | double Vars[] = {1, -2.5}; |
||

295 | double result = parser.Eval(Vars); |
||

296 | |||

297 | |||

298 | --------------------------------------------------------------------------- |
||

299 | int EvalError(void) const; |
||

300 | --------------------------------------------------------------------------- |
||

301 | |||

302 | Used to test if the call to Eval() succeeded. |
||

303 | |||

304 | Return values: |
||

305 | If there was no error in the previous call to Eval(), returns 0, |
||

306 | else returns a positive value as follows: |
||

307 | 1: division by zero |
||

308 | 2: sqrt error (sqrt of a negative value) |
||

309 | 3: log error (logarithm of a negative value) |
||

310 | 4: trigonometric error (asin or acos of illegal value) |
||

311 | |||

312 | |||

313 | --------------------------------------------------------------------------- |
||

314 | void Optimize(); |
||

315 | --------------------------------------------------------------------------- |
||

316 | |||

317 | This method can be called after calling the Parse() method. It will try |
||

318 | to simplify the internal bytecode so that it will evaluate faster (it |
||

319 | tries to reduce the amount of opcodes in the bytecode). |
||

320 | |||

321 | For example, the bytecode for the function "5+x*y-25*4/8" will be |
||

322 | reduced to a bytecode equivalent to the function "x*y-7.5" (the original |
||

323 | 11 opcodes will be reduced to 5). Besides calculating constant expressions |
||

324 | (like in the example), it also performs other types of simplifications |
||

325 | with variable and function expressions. |
||

326 | |||

327 | This method is quite slow and the decision of whether to use it or |
||

328 | not should depend on the type of application. If a function is parsed |
||

329 | once and evaluated millions of times, then calling Optimize() may speed-up |
||

330 | noticeably. However, if there are tons of functions to parse and each one |
||

331 | is evaluated once or just a few times, then calling Optimize() will only |
||

332 | slow down the program. |
||

333 | Also, if the original function is expected to be optimal, then calling |
||

334 | Optimize() would be useless. |
||

335 | |||

336 | Note: Currently this method does not make any checks (like Eval() does) |
||

337 | and thus things like "1/0" will cause undefined behaviour. (On the other |
||

338 | hand, if such expression is given to the parser, Eval() will always give |
||

339 | an error code, no matter what the parameters.) If caching this type of |
||

340 | errors is important, a work-around is to call Eval() once before calling |
||

341 | Optimize() and checking EvalError(). |
||

342 | |||

343 | If the destination application is not going to use this method, |
||

344 | the compiler constant SUPPORT_OPTIMIZER can be undefined at the beginning |
||

345 | of fparser.cc to make the library smaller (Optimize() can still be called, |
||

346 | but it will not do anything). |
||

347 | |||

348 | (If you are interested in seeing how this method optimizes the opcode, |
||

349 | you can call the PrintByteCode() method before and after the call to |
||

350 | Optimize() to see the difference.) |
||

351 | |||

352 | |||

353 | --------------------------------------------------------------------------- |
||

354 | bool AddConstant(const std::string& name, double value); |
||

355 | --------------------------------------------------------------------------- |
||

356 | |||

357 | This method can be used to add constants to the parser. Syntactically |
||

358 | constants are identical to variables (ie. they follow the same naming |
||

359 | rules and they can be used in the function string in the same way as |
||

360 | variables), but internally constants are directly replaced with their |
||

361 | value at parse time. |
||

362 | |||

363 | Constants used by a function must be added before calling Parse() |
||

364 | for that function. Constants are preserved between Parse() calls in |
||

365 | the current FunctionParser instance, so they don't need to be added |
||

366 | but once. (If you use the same constant in several instances of |
||

367 | FunctionParser, you will need to add it to all the instances separately.) |
||

368 | |||

369 | Constants can be added at any time and the value of old constants can |
||

370 | be changed, but new additions and changes will only have effect the next |
||

371 | time Parse() is called. (That is, changing the value of a constant |
||

372 | after calling Parse() and before calling Eval() will have no effect.) |
||

373 | |||

374 | The return value will be false if the 'name' of the constant was |
||

375 | illegal, else true. If the name was illegal, the method does nothing. |
||

376 | |||

377 | Example: parser.AddConstant("pi", 3.14159265); |
||

378 | |||

379 | Now for example parser.Parse("x*pi", "x"); will be identical to the |
||

380 | call parser.Parse("x*3.14159265", "x"); |
||

381 | |||

382 | |||

383 | --------------------------------------------------------------------------- |
||

384 | bool AddFunction(const std::string& name, |
||

385 | double (*functionPtr)(const double*), |
||

386 | unsigned paramsAmount); |
||

387 | --------------------------------------------------------------------------- |
||

388 | |||

389 | This method can be used to add new functions to the parser. For example, |
||

390 | if you would like to add a function "sqr(A)" which squares the value |
||

391 | of A, you can do it with this method (so that you don't need to touch |
||

392 | the source code of the parser). |
||

393 | |||

394 | The method takes three parameters: |
||

395 | |||

396 | - The name of the function. The name follows the same naming conventions |
||

397 | as variable names. |
||

398 | |||

399 | - A C++ function, which will be called when evaluating the function |
||

400 | string (if the user-given function is called there). The C++ function |
||

401 | must have the form: |
||

402 | double functionName(const double* params); |
||

403 | |||

404 | - The number of parameters the function takes. NOTE: Currently this |
||

405 | value must be at least 1; the parser does not support functions which |
||

406 | take no parameters (this problem may be fixed in the future). |
||

407 | |||

408 | The return value will be false if the given name was invalid (either it |
||

409 | did not follow the variable naming conventions, or the name was already |
||

410 | reserved), else true. If the return value is false, nothing is added. |
||

411 | |||

412 | Example: |
||

413 | Suppose we have a C++ function like this: |
||

414 | |||

415 | double Square(const double* p) |
||

416 | { |
||

417 | return p[0]*p[0]; |
||

418 | } |
||

419 | |||

420 | Now we can add this function to the parser like this: |
||

421 | |||

422 | parser.AddFunction("sqr", Square, 1); |
||

423 | |||

424 | parser.Parse("2*sqr(x)", "x"); |
||

425 | |||

426 | |||

427 | IMPORTANT NOTE: If you use the Optimize() method, it will assume that |
||

428 | the user-given function has no side-effects, that is, it always |
||

429 | returns the same value for the same parameters. The optimizer will |
||

430 | optimize the function call away in some cases, making this assumption. |
||

431 | |||

432 | |||

433 | --------------------------------------------------------------------------- |
||

434 | bool AddFunction(const std::string& name, FunctionParser&); |
||

435 | --------------------------------------------------------------------------- |
||

436 | |||

437 | This method is almost identical to the previous AddFunction(), but |
||

438 | instead of taking a C++ function, it takes another FunctionParser |
||

439 | instance. |
||

440 | |||

441 | There are some important restrictions on making a FunctionParser instance |
||

442 | call another: |
||

443 | |||

444 | - The FunctionParser instance given as parameter must be initialized |
||

445 | with a Parse() call before giving it as parameter. That is, if you |
||

446 | want to use the parser A in the parser B, you must call A.Parse() |
||

447 | before you can call B.AddFunction("name", A). |
||

448 | |||

449 | - The amount of parameters in the FunctionParser instance given as |
||

450 | parameter must not change after it has been given to the AddFunction() |
||

451 | of another instance. Changing the number of parameters will result in |
||

452 | malfunction. |
||

453 | |||

454 | - AddFunction() will fail (ie. return false) if a recursive loop is |
||

455 | formed. The method specifically checks that no such loop is built. |
||

456 | |||

457 | - As with the other AddFunction(), the number of parameters taken by |
||

458 | the user-defined function must be at least 1 (this may be fixed in |
||

459 | the future). |
||

460 | |||

461 | Example: |
||

462 | |||

463 | FunctionParser f1, f2; |
||

464 | f1.Parse("x*x", "x"); |
||

465 | f2.AddFunction("sqr", f1); |
||

466 | |||

467 | |||

468 | --------------------------------------------------------------------------- |
||

469 | |||

470 | Example program: |
||

471 | |||

472 | #include "fparser.hh" |
||

473 | #include <iostream> |
||

474 | |||

475 | int main() |
||

476 | { |
||

477 | FunctionParser fp; |
||

478 | |||

479 | int ret = fp.Parse("x+y-1", "x,y"); |
||

480 | if(ret >= 0) |
||

481 | { |
||

482 | std::cerr << "At col " << ret << ": " << fp.ErrorMsg() << std::endl; |
||

483 | return 1; |
||

484 | } |
||

485 | |||

486 | double vals[] = { 4, 8 }; |
||

487 | |||

488 | std::cout << fp.Eval(vals) << std::endl; |
||

489 | } |
||

490 | |||

491 | |||

492 | |||

493 | ============================================================================= |
||

494 | - The function string |
||

495 | ============================================================================= |
||

496 | |||

497 | The function string understood by the class is very similar to the C-syntax. |
||

498 | Arithmetic float expressions can be created from float literals, variables |
||

499 | or functions using the following operators in this order of precedence: |
||

500 | |||

501 | () expressions in parentheses first |
||

502 | -A unary minus |
||

503 | A^B exponentiation (A raised to the power B) |
||

504 | A*B A/B A%B multiplication, division and modulo |
||

505 | A+B A-B addition and subtraction |
||

506 | A=B A<B A>B comparison between A and B (result is either 0 or 1) |
||

507 | A&B result is 1 if int(A) and int(B) differ from 0, else 0. |
||

508 | A|B result is 1 if int(A) or int(B) differ from 0, else 0. |
||

509 | |||

510 | Since the unary minus has higher precedence than any other operator, for |
||

511 | example the following expression is valid: x*-y |
||

512 | Note that the '=' comparison can be inaccurate due to floating point |
||

513 | precision problems (eg. "sqrt(100)=10" probably returns 0, not 1). |
||

514 | |||

515 | The class supports these functions: |
||

516 | |||

517 | abs(A) : Absolute value of A. If A is negative, returns -A otherwise |
||

518 | returns A. |
||

519 | acos(A) : Arc-cosine of A. Returns the angle, measured in radians, |
||

520 | whose cosine is A. |
||

521 | acosh(A) : Same as acos() but for hyperbolic cosine. |
||

522 | asin(A) : Arc-sine of A. Returns the angle, measured in radians, whose |
||

523 | sine is A. |
||

524 | asinh(A) : Same as asin() but for hyperbolic sine. |
||

525 | atan(A) : Arc-tangent of (A). Returns the angle, measured in radians, |
||

526 | whose tangent is (A). |
||

527 | atan2(A,B): Arc-tangent of A/B. The two main differences to atan() is |
||

528 | that it will return the right angle depending on the signs of |
||

529 | A and B (atan() can only return values betwen -pi/2 and pi/2), |
||

530 | and that the return value of pi/2 and -pi/2 are possible. |
||

531 | atanh(A) : Same as atan() but for hyperbolic tangent. |
||

532 | ceil(A) : Ceiling of A. Returns the smallest integer greater than A. |
||

533 | Rounds up to the next higher integer. |
||

534 | cos(A) : Cosine of A. Returns the cosine of the angle A, where A is |
||

535 | measured in radians. |
||

536 | cosh(A) : Same as cos() but for hyperbolic cosine. |
||

537 | cot(A) : Cotangent of A (equivalent to 1/tan(A)). |
||

538 | csc(A) : Cosecant of A (equivalent to 1/sin(A)). |
||

539 | eval(...) : This a recursive call to the function to be evaluated. The |
||

540 | number of parameters must be the same as the number of parameters |
||

541 | taken by the function. Usually called inside if() to avoid |
||

542 | infinite recursion. |
||

543 | exp(A) : Exponential of A. Returns the value of e raised to the power |
||

544 | A where e is the base of the natural logarithm, i.e. the |
||

545 | non-repeating value approximately equal to 2.71828182846. |
||

546 | floor(A) : Floor of A. Returns the largest integer less than A. Rounds |
||

547 | down to the next lower integer. |
||

548 | if(A,B,C) : If int(A) differs from 0, the return value of this function is B, |
||

549 | else C. Only the parameter which needs to be evaluated is |
||

550 | evaluated, the other parameter is skipped; this makes it safe to |
||

551 | use eval() in them. |
||

552 | int(A) : Rounds A to the closest integer. 0.5 is rounded to 1. |
||

553 | log(A) : Natural (base e) logarithm of A. |
||

554 | log10(A) : Base 10 logarithm of A. |
||

555 | max(A,B) : If A>B, the result is A, else B. |
||

556 | min(A,B) : If A<B, the result is A, else B. |
||

557 | sec(A) : Secant of A (equivalent to 1/cos(A)). |
||

558 | sin(A) : Sine of A. Returns the sine of the angle A, where A is |
||

559 | measured in radians. |
||

560 | sinh(A) : Same as sin() but for hyperbolic sine. |
||

561 | sqrt(A) : Square root of A. Returns the value whose square is A. |
||

562 | tan(A) : Tangent of A. Returns the tangent of the angle A, where A |
||

563 | is measured in radians. |
||

564 | tanh(A) : Same as tan() but for hyperbolic tangent. |
||

565 | |||

566 | |||

567 | Examples of function string understood by the class: |
||

568 | |||

569 | "1+2" |
||

570 | "x-1" |
||

571 | "-sin(sqrt(x^2+y^2))" |
||

572 | "sqrt(XCoord*XCoord + YCoord*YCoord)" |
||

573 | |||

574 | An example of a recursive function is the factorial function: |
||

575 | |||

576 | "if(n>1, n*eval(n-1), 1)" |
||

577 | |||

578 | Note that a recursive call has some overhead, which makes it a bit slower |
||

579 | than any other operation. It may be a good idea to avoid recursive functions |
||

580 | in very time-critical applications. Recursion also takes some memory, so |
||

581 | extremely deep recursions should be avoided (eg. millions of nested recursive |
||

582 | calls). |
||

583 | |||

584 | Also note that the if() function is the only place where making a recursive |
||

585 | call is safe. In any other place it will cause an infinite recursion (which |
||

586 | will make the program eventually run out of memory). If this is something |
||

587 | which should be avoided, it may be a good idea to disable the eval() |
||

588 | function completely. |
||

589 | The eval() function can be disabled with the DISABLE_EVAL precompiler |
||

590 | constant (see the beginning of fparser.cc). |
||

591 | |||

592 | |||

593 | ============================================================================= |
||

594 | - Contacting the author |
||

595 | ============================================================================= |
||

596 | |||

597 | Any comments, bug reports, etc. should be sent to warp@iki.fi |
||

598 | |||

599 | |||

600 | ============================================================================= |
||

601 | - The algorithm used in the library |
||

602 | ============================================================================= |
||

603 | |||

604 | The whole idea behind the algorithm is to convert the regular infix |
||

605 | format (the regular syntax for mathematical operations in most languages, |
||

606 | like C and the input of the library) to postfix format. The postfix format |
||

607 | is also called stack arithmetic since an expression in postfix format |
||

608 | can be evaluated using a stack and operating with the top of the stack. |
||

609 | |||

610 | For example: |
||

611 | |||

612 | infix postfix |
||

613 | 2+3 2 3 + |
||

614 | 1+2+3 1 2 + 3 + |
||

615 | 5*2+8/2 5 2 * 8 2 / + |
||

616 | (5+9)*3 5 9 + 3 * |
||

617 | |||

618 | The postfix notation should be read in this way: |
||

619 | |||

620 | Let's take for example the expression: 5 2 * 8 2 / + |
||

621 | - Put 5 on the stack |
||

622 | - Put 2 on the stack |
||

623 | - Multiply the two values on the top of the stack and put the result on |
||

624 | the stack (removing the two old values) |
||

625 | - Put 8 on the stack |
||

626 | - Put 2 on the stack |
||

627 | - Divide the two values on the top of the stack |
||

628 | - Add the two values on the top of the stack (which are in this case |
||

629 | the result of 5*2 and 8/2, that is, 10 and 4). |
||

630 | |||

631 | At the end there's only one value in the stack, and that value is the |
||

632 | result of the expression. |
||

633 | |||

634 | Why stack arithmetic? |
||

635 | |||

636 | The last example above can give you a hint. |
||

637 | In infix format operators have precedence and we have to use parentheses to |
||

638 | group operations with lower precedence to be calculated before operations |
||

639 | with higher precedence. |
||

640 | This causes a problem when evaluating an infix expression, specially |
||

641 | when converting it to byte code. For example in this kind of expression: |
||

642 | (x+1)/(y+2) |
||

643 | we have to calculate first the two additions before we can calculate the |
||

644 | division. We have to also keep counting parentheses, since there can be |
||

645 | a countless amount of nested parentheses. This usually means that you |
||

646 | have to do some type of recursion. |
||

647 | |||

648 | The most simple and efficient way of calculating this is to convert it |
||

649 | to postfix notation. |
||

650 | The postfix notation has the advantage that you can make all operations |
||

651 | in a straightforward way. You just evaluate the expression from left to |
||

652 | right, applying each operation directly and that's it. There are no |
||

653 | parentheses to worry about. You don't need recursion anywhere. |
||

654 | You have to keep a stack, of course, but that's extremely easily done. |
||

655 | Also you just operate with the top of the stack, which makes it very easy. |
||

656 | You never have to go deeper than 2 items in the stack. |
||

657 | And even better: Evaluating an expression in postfix format is never |
||

658 | slower than in infix format. All the contrary, in many cases it's a lot |
||

659 | faster (eg. because all parentheses are optimized away). |
||

660 | The above example could be expressed in postfix format: |
||

661 | x 1 + y 2 + / |
||

662 | |||

663 | The good thing about the postfix notation is also the fact that it can |
||

664 | be extremely easily expressed in bytecode form. |
||

665 | You only need a byte value for each operation, for each variable and |
||

666 | to push a constant to the stack. |
||

667 | Then you can interpret this bytecode straightforwardly. You just interpret |
||

668 | it byte by byte, from the beginning to the end. You never have to go back, |
||

669 | make loops or anything. |
||

670 | |||

671 | This is what makes byte-coded stack arithmetic so fast. |
||

672 | |||

673 | |||

674 | |||

675 | ============================================================================= |
||

676 | Usage license: |
||

677 | ============================================================================= |
||

678 | |||

679 | Copyright © 2003 Juha Nieminen, Joel Yliluoma |
||

680 | |||

681 | This library is distributed under two distinct usage licenses depending |
||

682 | on the software ("Software" below) which uses the Function Parser library |
||

683 | ("Library" below). |
||

684 | The reason for having two distinct usage licenses is to make the library |
||

685 | compatible with the GPL license while still being usable in other non-GPL |
||

686 | (even commercial) software. |
||

687 | |||

688 | A) If the Software using the Library is distributed under the GPL license, |
||

689 | then the Library can be used under the GPL license as well. |
||

690 | |||

691 | The Library will be under the GPL license only when used with the |
||

692 | Software. If the Library is separated from the Software and used in |
||

693 | another different software under a different license, then the Library |
||

694 | will have the B) license below. |
||

695 | |||

696 | Exception to the above: If the Library is modified for the GPL Software, |
||

697 | then the Library cannot be used with the B) license without the express |
||

698 | permission of the author of the modifications. A modified library will |
||

699 | be under the GPL license by default. That is, only the original, |
||

700 | unmodified version of the Library can be taken to another software |
||

701 | with the B) license below. |
||

702 | |||

703 | The author of the Software should provide an URL to the original |
||

704 | version of the Library if the one used in the Software has been |
||

705 | modified. (http://iki.fi/warp/FunctionParser/) |
||

706 | |||

707 | This text file must be distributed in its original intact form along |
||

708 | with the sources of the Library. (Documentation about possible |
||

709 | modifications to the library should be put in a different text file.) |
||

710 | |||

711 | B) If the Software using the Library is not distributed under the GPL |
||

712 | license but under any other license, then the following usage license |
||

713 | applies to the Library: |
||

714 | |||

715 | 1. This library is free for non-commercial usage. You can do whatever you |
||

716 | like with it as long as you don't claim you made it yourself. |
||

717 | |||

718 | 2. It is possible to use this library in a commercial program, but in this |
||

719 | case you MUST contact me first (warp@iki.fi) and ask express permission |
||

720 | for this. (Read explanation at the end of the file.) |
||

721 | If you are making a free program or a shareware program with just a |
||

722 | nominal price (5 US dollars or less), you don't have to ask for |
||

723 | permission. |
||

724 | In any case, I DON'T WANT MONEY for the usage of this library. It is |
||

725 | free, period. |
||

726 | |||

727 | 3. You can make any modifications you want to it so that it conforms your |
||

728 | needs. If you make modifications to it, you have, of course, credits for |
||

729 | the modified parts. |
||

730 | |||

731 | 4. If you use this library in your own program, you don't have to provide |
||

732 | the source code if you don't want to (ie. the source code of your program |
||

733 | or this library). |
||

734 | If you DO include the source code for this library, this text file |
||

735 | must be included in its original intact form. |
||

736 | |||

737 | 5. If you distribute a program which uses this library, and specially if you |
||

738 | provide the source code, proper credits MUST be included. Trying to |
||

739 | obfuscate the fact that this library is not made by you or that it is |
||

740 | free is expressly prohibited. When crediting the usage of this library, |
||

741 | it's enough to include my name and email address, that is: |
||

742 | "Juha Nieminen (warp@iki.fi)". Also a URL to the library download page |
||

743 | would be nice, although not required. The official URL is: |
||

744 | http://iki.fi/warp/FunctionParser/ |
||

745 | |||

746 | 6. And the necessary "lawyer stuff": |
||

747 | |||

748 | The above copyright notice and this permission notice shall be |
||

749 | included in all copies or substantial portions of the Software. |
||

750 | |||

751 | The software is provided "as is", without warranty of any kind, |
||

752 | express or implied, including but not limited to the warranties of |
||

753 | merchantability, fitness for a particular purpose and noninfringement. |
||

754 | In no event shall the authors or copyright holders be liable for any |
||

755 | claim, damages or other liability, whether in an action of contract, |
||

756 | tort or otherwise, arising from, out of or in connection with the |
||

757 | software or the use or other dealings in the software. |
||

758 | |||

759 | |||

760 | --- Explanation of the section 2 of the B) license above: |
||

761 | |||

762 | The section 2 tries to define "fair use" of the library in commercial |
||

763 | programs. |
||

764 | "Fair use" of the library means that the program is not heavily dependent |
||

765 | on the library, but the library only provides a minor secondary feature |
||

766 | to the program. |
||

767 | "Heavily dependent" means that the program depends so much on the library |
||

768 | that without it the functionality of the program would be seriously |
||

769 | degraded or the program would even become completely non-functional. |
||

770 | |||

771 | In other words: If the program does not depend heavily on the library, |
||

772 | that is, the library only provides a minor secondary feature which could |
||

773 | be removed without the program being degraded in any considerable way, |
||

774 | then it's OK to use the library in the commercial program. |
||

775 | If, however, the program depends so heavily on the library that |
||

776 | removing it would make the program non-functional or degrade its |
||

777 | functionality considerably, then it's NOT OK to use the library. |
||

778 | |||

779 | The ideology behind this is that it's not fair to use a free library |
||

780 | as a base for a commercial program, but it's fair if the library is |
||

781 | just a minor, unimportant extra. |
||

782 | |||

783 | If you are going to ask me for permission to use the library in a |
||

784 | commercial program, please describe the feature which the library will |
||

785 | be providing and how important it is to the program. |