From b69356262683270173a684576f6878151237ca5b Mon Sep 17 00:00:00 2001 From: Danny Muid Date: Wed, 7 May 2003 03:40:52 +0000 Subject: [PATCH] FormulaParser patch to address: 1) embedded ifs 2) GreaterEqual, LessEqual, NotEqual 3) Refactored stringliteral detection BR: 19079 Submitted By: fred at stsci dot edu git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353089 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/hssf/model/FormulaParser.java | 117 +++++++++++++---- .../hssf/record/formula/GreaterEqualPtg.java | 121 +++++++++++++++++ .../poi/hssf/record/formula/LessEqualPtg.java | 122 +++++++++++++++++ .../poi/hssf/record/formula/NotEqualPtg.java | 124 ++++++++++++++++++ .../apache/poi/hssf/record/formula/Ptg.java | 14 +- .../poi/hssf/model/TestFormulaParser.java | 39 ++++-- 6 files changed, 500 insertions(+), 37 deletions(-) create mode 100755 src/java/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java create mode 100755 src/java/org/apache/poi/hssf/record/formula/LessEqualPtg.java create mode 100755 src/java/org/apache/poi/hssf/record/formula/NotEqualPtg.java diff --git a/src/java/org/apache/poi/hssf/model/FormulaParser.java b/src/java/org/apache/poi/hssf/model/FormulaParser.java index 6d7ff6f70..b41f08487 100644 --- a/src/java/org/apache/poi/hssf/model/FormulaParser.java +++ b/src/java/org/apache/poi/hssf/model/FormulaParser.java @@ -457,6 +457,7 @@ public class FormulaParser { if (look != ')') { numArgs++; Expression(); + addArgumentPointer(); } while (look == ',' || look == ';') { //TODO handle EmptyArgs if(look == ',') { @@ -466,6 +467,7 @@ public class FormulaParser { Match(';'); } Expression(); + addArgumentPointer(); numArgs++; } return numArgs; @@ -478,7 +480,6 @@ public class FormulaParser { Expression(); Match(')'); tokens.add(new ParenthesisPtg()); - return; } else if (IsAlpha(look)){ Ident(); } else if(look == '"') { @@ -499,9 +500,23 @@ public class FormulaParser { private void StringLiteral() { Match('"'); - String name= GetNameAsIs(); - Match('"'); - tokens.add(new StringPtg(name)); + StringBuffer Token = new StringBuffer(); + for(;;) { + if(look == '"') { + GetChar(); + SkipWhite(); //potential white space here since it doesnt matter up to the operator + if(look == '"') + Token.append("\""); + else + break; + } else if(look == 0) { + break; + } else { + Token.append(look); + GetChar(); + } + } + tokens.add(new StringPtg(Token.toString())); } /** Recognize and Translate a Multiply */ @@ -525,16 +540,13 @@ public class FormulaParser { /** Parse and Translate a Math Term */ private void Term(){ Factor(); - while (look == '*' || look == '/' || look == '^' || look == '&' || - look == '=' || look == '>' || look == '<' ) { + while (look == '*' || look == '/' || look == '^' || look == '&') { + ///TODO do we need to do anything here?? if (look == '*') Multiply(); - if (look == '/') Divide(); - if (look == '^') Power(); - if (look == '&') Concat(); - if (look == '=') Equal(); - if (look == '>') GreaterThan(); - if (look == '<') LessThan(); + else if (look == '/') Divide(); + else if (look == '^') Power(); + else if (look == '&') Concat(); } } @@ -555,7 +567,7 @@ public class FormulaParser { /** Recognize and Translate a test for Equality */ private void Equal() { Match('='); - Term(); + Expression(); tokens.add(new EqualPtg()); } @@ -581,31 +593,80 @@ public class FormulaParser { Term(); } while (IsAddop(look)) { - if ( look == '+' ) Add(); - if (look == '-') Subtract(); - if (look == '*') Multiply(); - if (look == '/') Divide(); - if (look == '>') GreaterThan(); - if (look == '<') LessThan(); + if (look == '+' ) Add(); + else if (look == '-') Subtract(); } - addArgumentPointer(); + + /* + * This isn't quite right since it would allow multiple comparison operators. + */ + + if(look == '=' || look == '>' || look == '<') { + if (look == '=') Equal(); + else if (look == '>') GreaterThan(); + else if (look == '<') LessThan(); + return; + } + } /** Recognize and Translate a Greater Than */ private void GreaterThan() { - Match('>'); - Term(); - tokens.add(new GreaterThanPtg()); + Match('>'); + if(look == '=') + GreaterEqual(); + else { + Expression(); + tokens.add(new GreaterThanPtg()); + } } /** Recognize and Translate a Less Than */ private void LessThan() { - Match('<'); - Term(); - tokens.add(new LessThanPtg()); - } - + Match('<'); + if(look == '=') + LessEqual(); + else if(look == '>') + NotEqual(); + else { + Expression(); + tokens.add(new LessThanPtg()); + } + + } + + /** + * Recognize and translate Greater than or Equal + * + */ + private void GreaterEqual() { + Match('='); + Expression(); + tokens.add(new GreaterEqualPtg()); + } + + /** + * Recognize and translate Less than or Equal + * + */ + + private void LessEqual() { + Match('='); + Expression(); + tokens.add(new LessEqualPtg()); + } + + /** + * Recognize and not Equal + * + */ + + private void NotEqual() { + Match('>'); + Expression(); + tokens.add(new NotEqualPtg()); + } //{--------------------------------------------------------------} //{ Parse and Translate an Assignment Statement } diff --git a/src/java/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java b/src/java/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java new file mode 100755 index 000000000..de0b6238d --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java @@ -0,0 +1,121 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2003 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache POI" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache POI", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.poi.hssf.record.formula; + + +import org.apache.poi.hssf.util.SheetReferences; + +/** + * PTG class to implement greater or equal to + * @author fred at stsci dot edu + */ +public class GreaterEqualPtg + extends OperationPtg +{ + public final static int SIZE = 1; + public final static byte sid = 0x0c; + + /** Creates new AddPtg */ + + public GreaterEqualPtg() + { + } + + public GreaterEqualPtg(byte [] data, int offset) + { + + // doesn't need anything + } + + public void writeBytes(byte [] array, int offset) + { + array[ offset + 0 ] = sid; + } + + public int getSize() + { + return SIZE; + } + + public int getType() + { + return TYPE_BINARY; + } + + public int getNumberOfOperands() + { + return 2; + } + + public String toFormulaString(SheetReferences refs) + { + return ">="; + } + + public String toFormulaString(String[] operands) { + StringBuffer buffer = new StringBuffer(); + + + buffer.append(operands[ 0 ]); + buffer.append(toFormulaString((SheetReferences)null)); + buffer.append(operands[ 1 ]); + return buffer.toString(); + } + + public Object clone() { + return new GreaterEqualPtg(); + } + + +} \ No newline at end of file diff --git a/src/java/org/apache/poi/hssf/record/formula/LessEqualPtg.java b/src/java/org/apache/poi/hssf/record/formula/LessEqualPtg.java new file mode 100755 index 000000000..0c8165fb7 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/LessEqualPtg.java @@ -0,0 +1,122 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2003 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache POI" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache POI", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ +package org.apache.poi.hssf.record.formula; + +import org.apache.poi.hssf.util.SheetReferences; + + +/** + * Ptg class to implement less than or equal + * @author fred at stsci dot edu + */ + +public class LessEqualPtg + extends OperationPtg +{ + public final static int SIZE = 1; + public final static byte sid = 0x0a; + + /** Creates new AddPtg */ + + public LessEqualPtg() + { + } + + public LessEqualPtg(byte [] data, int offset) + { + + // doesn't need anything + } + + public void writeBytes(byte [] array, int offset) + { + array[ offset + 0 ] = sid; + } + + public int getSize() + { + return SIZE; + } + + public int getType() + { + return TYPE_BINARY; + } + + public int getNumberOfOperands() + { + return 2; + } + + public String toFormulaString(SheetReferences refs) + { + return "<="; + } + + public String toFormulaString(String[] operands) { + StringBuffer buffer = new StringBuffer(); + + + buffer.append(operands[ 0 ]); + buffer.append(toFormulaString((SheetReferences)null)); + buffer.append(operands[ 1 ]); + return buffer.toString(); + } + + public Object clone() { + return new LessEqualPtg(); + } + + +} \ No newline at end of file diff --git a/src/java/org/apache/poi/hssf/record/formula/NotEqualPtg.java b/src/java/org/apache/poi/hssf/record/formula/NotEqualPtg.java new file mode 100755 index 000000000..c43c19678 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/formula/NotEqualPtg.java @@ -0,0 +1,124 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" and + * "Apache POI" must not be used to endorse or promote products + * derived from this software without prior written permission. For + * written permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * "Apache POI", nor may "Apache" appear in their name, without + * prior written permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + */ + +package org.apache.poi.hssf.record.formula; + +import java.util.List; + +import org.apache.poi.hssf.util.SheetReferences; + +/** + * Ptg class to implement not equal + * @author fred at stsci dot edu + */ + +public class NotEqualPtg + extends OperationPtg +{ + public final static int SIZE = 1; + public final static byte sid = 0x0e; + + /** Creates new AddPtg */ + + public NotEqualPtg() + { + } + + public NotEqualPtg(byte [] data, int offset) + { + + // doesn't need anything + } + + public void writeBytes(byte [] array, int offset) + { + array[ offset + 0 ] = sid; + } + + public int getSize() + { + return SIZE; + } + + public int getType() + { + return TYPE_BINARY; + } + + public int getNumberOfOperands() + { + return 2; + } + + public String toFormulaString(SheetReferences refs) + { + return "<>"; + } + + public String toFormulaString(String[] operands) { + StringBuffer buffer = new StringBuffer(); + + + buffer.append(operands[ 0 ]); + buffer.append(toFormulaString((SheetReferences)null)); + buffer.append(operands[ 1 ]); + return buffer.toString(); + } + + public Object clone() { + return new NotEqualPtg(); + } + + +} \ No newline at end of file diff --git a/src/java/org/apache/poi/hssf/record/formula/Ptg.java b/src/java/org/apache/poi/hssf/record/formula/Ptg.java index 1e4a5c397..3787d0056 100644 --- a/src/java/org/apache/poi/hssf/record/formula/Ptg.java +++ b/src/java/org/apache/poi/hssf/record/formula/Ptg.java @@ -184,7 +184,19 @@ public abstract class Ptg case LessThanPtg.sid: retval = new LessThanPtg(data, offset); break; - + + case LessEqualPtg.sid: + retval = new LessEqualPtg(data, offset); + break; + + case GreaterEqualPtg.sid: + retval = new GreaterEqualPtg(data, offset); + break; + + case NotEqualPtg.sid: + retval = new NotEqualPtg(data, offset); + break; + case ConcatPtg.sid : retval = new ConcatPtg(data, offset); break; diff --git a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java index 339fdcd86..c4722a9a7 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java +++ b/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java @@ -251,16 +251,39 @@ public class TestFormulaParser extends TestCase { } - public void testSimpleLogical() { - FormulaParser fp=new FormulaParser("IF(A1=1,\"*\",IF(4<>1,\"first\",\"second\"))",null); + fp.parse(); + Ptg[] ptgs = fp.getRPNPtg(); + assertTrue("Ptg array should not be null", ptgs !=null); + assertEquals("Ptg array length", 17, ptgs.length); + + assertEquals("6th Ptg is not a goto (Attr) ptg",AttrPtg.class,ptgs[5].getClass()); + assertEquals("9th Ptg is not a not equal ptg",NotEqualPtg.class,ptgs[8].getClass()); + assertEquals("15th Ptg is not the inner IF variable function ptg",FuncVarPtg.class,ptgs[14].getClass()); + + } public static void main(String [] args) { System.out.println("Testing org.apache.poi.hssf.record.formula.FormulaParser");