******************************************************************************* Document: README.txt Date : 06/14/2004 (mm/dd/yyyy) Author : Maulin H. Vasavada ******************************************************************************* README ------ (0) Motivation for this project =============================== I had to use a evaluation process on infix expression in one of the applications and I looked for an Java API for such evaluation on the internet. To my surprise, I found that many have done this work internally for academic purposes etc but nobody have publicly available API for that. I thought that is because it is not complicated to write infix to postfix conversion and execution of the postfix but I felt if it is that simple and publicly known then why not to write it once and use it again and again, which would save time? So I started to build up this little API which might be useful in academic demos and initial learning during Computer Science. To my personal use I have used this API in two places, 1. To form rule expressions for Rule Engine and execute them 2. In rule conditions where we have "math operations" to be resolved before we can evaluate rule conditions like, IF (field1.value) < (field2.value + field3.value ) * 2.5 - field4.value THEN ... (A) What this package is for? ============================= This package is designed to do two things, 1. provide API for Infix to postix conversion of "simple" expressions 2. provide API for Evaluating postfix conversion (B) What this package is not for? ================================= 1. This package is not intended to evaluate any complex expressions having ternary operators, nested function operators etc. If that is needed to be done via Java then open source project JEP (http://www.singularsys.com/jep/) is recommended with which this package can't compete or be compared. 2. This package is not meant to be "yet another scripting language" or replace any of the existing scripting language that provides rich functionality. e.g of such scripting languages are, 1. BeanShell - http://www.beanshell.org/ 2. Ruby - http://www.ruby-lang.org/en/ 3. Groovy - http://groovy.codehaus.org/ In other words, this package should not be extended to achieve very complex functionality which is already supported by some packages mentioned above. (C) Why this package supports "max" like function operators if it is supposed to only support "infix" expressions. (Note: 'max' is not an infix operator) =============================================================================== 1. This is an anomaly and the reason for that is- I wanted to create simple expression evaluator and I observed that this is useful to couple of folks but they got stuck when it came to 'max' operator "even if they had simple input like max(2,3) somewhere in middle of their expression. So, I thought it would be worth to go little out of way so we don't get stuck just by such little hurdle. This is critical point to keep in mind while using/extending this package to maintain simplicity of this package and avoid running into "re-invent the wheel" phenomenon. (D) Is this an open source project? =================================== 1. If I see some meaningful use of this package I would make it open source. Meanwhile I would love to keep gathering feedback on this and make it more meaningful in initial stages. I am packaging the source so I can get more feedback from experts in every sense. NOTE: By now it is an open source package under LGPL license. (E) Structure of the package ============================ Here is the directory structure of this zip file, -root - REAME.txt -- This file - design -- I have tried to put up some UML diagrams for this application using Poseidon tool. Also the folder contains GIF files for those who don't have access to Poseidon. This is also my learning part so please feel free to comment on the diagrams if you feel so - docs -- Javadocs for the package - samples -- Directory containing sample program about how to use this package - infix2postfix.jar -- Ready to use jar file without source in it - src -- Source directory (F) Which Java to use for this? =============================== JDK above 1.4.0. (G) Known issues ================ 1. The input to the program (infix expression) must be space separated string. 2. Parsing of this input is done by String.split() method hence it doesn't support multiple spaces/whitespaces in the expression but you can overridde the parse() method in Infix2PostfixConverter.java to fix it. Though if this package is found useful upto some substantial level I would replace the parsing method to use StringTokenizer which would fix the problem. (For now I am kind of lazy to do it :( ) (H) Future additions ==================== I have kept this package simple and hence I have not included, 1. build.xml (using ANT) 2. JUnit test cases 3. More granular packaging instead just one "infix2postfix" Java package (I) How to add custom operators? ================================ Here is the sample code depicting how to add an operator 'max' to MathClient for Infix2Postfix. final MathClient mc = new MathClient(); mc.addOperator(new BinaryFunctionOperator("max",50) { public Object applyOperator (Object operand1,Object operand2) throws InvalidOperandException { OperandManager operandManager = mc.getOperandManager(); if (operandManager instanceof IntegerOperandManager ) { return mc.convertForRadix( Math.max( mc.getIntegerOperand(operand1), mc.getIntegerOperand(operand2))); } if (operandManager instanceof LongOperandManager ) { return mc.convertForRadix( Math.max( mc.getLongOperand(operand1), mc.getLongOperand(operand2))); } if (operandManager instanceof FloatOperandManager ) { return mc.convertForRadix( Math.max( mc.getFloatOperand(operand1), mc.getFloatOperand(operand2))); } if (operandManager instanceof DoubleOperandManager ) { return mc.convertForRadix( Math.max( mc.getDoubleOperand(operand1), mc.getDoubleOperand(operand2))); } return ""; } }); NOTE: Please refer to the MathClient.java source to understand "operator priority" used here (that is 50). Here is the sample of how you can remove an operator, ----------------------------------------------------- mc.removeOperator("max"); // The symbol name for the operator, given here is // case-sensitive. Use same symbol as you used to // addOperator() (J) Where/how do I send comments and feedback? ============================================== 1. You can send comments/feedback on this at maulin_v@yahoo.com?subject=i2pc_feedback