Make Money

Friday, August 8, 2008

Math Expression Parser

Today I would like to talk about a specific subject, Mathematical Expression Parser software to parse and evaluate math expressions in Delphi. Delphi is the beloved IDE and the language (Delphi Pascal) of many programmers including myself. It has been very successful in bringing object oriented, event based GUI programming to the mainstream use and it has been a great competitor to Visual Basic and even to Visual C++. One of the strengths of Delphi is it's expressive syntax that makes it possible to solve sophisticated problems. One such problem is revealed when we want to allow the users of our programs input a mathematical formula at runtime. As we know, it is easy to compute mathematical expressions that are known at compile time. We type it in our program and the compiler compiles it and when we execute our program, we get the result. For example x+sin(x) can be easily computed when the value of x is supplied. However, when the mathematical expression is given as string at runtime, for example "x+sin(x)", then, to the program, it is no different then a meaningless "abc". The programmer has to make an explicit effort to make the program understand that there is a plus (+) sign that adds the value of x and the value of sin(x). Of crourse, the program also needs to understand the concept of a function call such as "sin(x)". The concept of breaking such an expression into it's conceptual sub-sections is called parsing. The programmer writes code which typically creates a data structure which represents the mathematical expression in a way that can be used to evaluate it efficiently. This is a gross simplification of the process but that is how it looks from a very high level, birds eye view. When parsing a mathematical formula, there are many challenges. These can be classified in two groups:A. Syntactic processing of the math expression.B. Numerical computation of the given formula.Syntactic processing of the math expression is about the necessity of recognizing valid variable names, function names, operators, value literals, whether they be simple integers, numbers with decimal points, or floating point numbers in scientific notation such as 1E-3 (0.001). There is also the need to gracefully ignore empty space, but detect errors caused by it. For example a function name broken by space: "si n(x)" is invalid. The paranthesis of an expression must match: "(x+1*(1/y)" is invalid. A literal value such as "3ABC" is invalid. The list goes on and on. Proper coverage of all possibilities requires extensive effort in programming and perhaps even more in terms of testing. Numerical computation of the given formula may sound like a simple operation to the beginner programmer. However, those of us who are experienced in numerical computing very well know how round off errors can accumulate and use of infinity in intermediate calculations can cause great deviations in the output. After the expression is parsed and formed into some sort of an expression tree, we can recursively walk the tree and compute the expression. During this stage, subtle, hard to detect errors may come into play. For example, if the expression is "3*(x/f(y))", in some cases the value of f(y) could be zero 0. Depending on the compiler settings and the libraries being used, this could cause an exception (Typical in Borland Delphi), or it could continue to execute (default in Visual C++) with x/f(y) as 0 and result would be 3. Now that result is debateable, but it is something that the programmer needs to be aware of. Tackling all of these challenges is almost impossible within the scope of a broader project where there are pressing requirements in terms of time and functionality to be delivered. Most of us need to focus on the actual business problem at hand and view the mathematical expression parsing aspect of the problem as a side issue. Thus, it becomes very very hard to deliver correct, united tested, proven code on time and in budget. Trying to code a expression parser could take an experienced developer a month to write and to test. When such as road block appears, the best way is to find a good component that can easily be integrated into your Delphi project, leaving you free time to focus on other aspects of your project or to simply go home and rest. There is peace of mind in using a component that many others have used for many years and flushed out the bugs for you. A good math parser component should allow the programmer control certain aspects of it's behaviour. For example it should allow the programmer define his own variables, create user defined functions, report proper error messages that can eventually be displayed to the end user. If you ever need to parse mathematical expressions, try the TbcParser math expression parser from Bestcode.com. TbcParser is an easy to use Math Parser Delphi Component which can parse and evaluate mathematical expressions with lightning speed. Bestcode.com provides high quality software to solve everyday problems at affordable price or as free downloads. C++ Builder, C++, .NET, COM, Java math parser components are available as well.

No comments: