You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by dm...@apache.org on 2003/05/07 05:40:53 UTC
cvs commit: jakarta-poi/src/testcases/org/apache/poi/hssf/model TestFormulaParser.java
dmui 2003/05/06 20:40:53
Modified: src/java/org/apache/poi/hssf/model FormulaParser.java
src/java/org/apache/poi/hssf/record/formula Ptg.java
src/testcases/org/apache/poi/hssf/model
TestFormulaParser.java
Added: src/java/org/apache/poi/hssf/record/formula
GreaterEqualPtg.java LessEqualPtg.java
NotEqualPtg.java
Log:
FormulaParser patch to address:
1) embedded ifs
2) GreaterEqual, LessEqual, NotEqual
3) Refactored stringliteral detection
BR: 19079
Submitted By: fred at stsci dot edu
Revision Changes Path
1.13 +89 -28 jakarta-poi/src/java/org/apache/poi/hssf/model/FormulaParser.java
Index: FormulaParser.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/model/FormulaParser.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- FormulaParser.java 6 May 2003 15:30:52 -0000 1.12
+++ FormulaParser.java 7 May 2003 03:40:52 -0000 1.13
@@ -457,6 +457,7 @@
if (look != ')') {
numArgs++;
Expression();
+ addArgumentPointer();
}
while (look == ',' || look == ';') { //TODO handle EmptyArgs
if(look == ',') {
@@ -466,6 +467,7 @@
Match(';');
}
Expression();
+ addArgumentPointer();
numArgs++;
}
return numArgs;
@@ -478,7 +480,6 @@
Expression();
Match(')');
tokens.add(new ParenthesisPtg());
- return;
} else if (IsAlpha(look)){
Ident();
} else if(look == '"') {
@@ -499,9 +500,23 @@
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 @@
/** 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 @@
/** Recognize and Translate a test for Equality */
private void Equal() {
Match('=');
- Term();
+ Expression();
tokens.add(new EqualPtg());
}
@@ -581,31 +593,80 @@
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 }
1.29 +13 -1 jakarta-poi/src/java/org/apache/poi/hssf/record/formula/Ptg.java
Index: Ptg.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/formula/Ptg.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- Ptg.java 5 May 2003 15:35:39 -0000 1.28
+++ Ptg.java 7 May 2003 03:40:52 -0000 1.29
@@ -184,7 +184,19 @@
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;
1.1 jakarta-poi/src/java/org/apache/poi/hssf/record/formula/GreaterEqualPtg.java
Index: GreaterEqualPtg.java
===================================================================
/* ====================================================================
* 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
* <http://www.apache.org/>.
*/
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();
}
}
1.1 jakarta-poi/src/java/org/apache/poi/hssf/record/formula/LessEqualPtg.java
Index: LessEqualPtg.java
===================================================================
/* ====================================================================
* 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
* <http://www.apache.org/>.
*/
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();
}
}
1.1 jakarta-poi/src/java/org/apache/poi/hssf/record/formula/NotEqualPtg.java
Index: NotEqualPtg.java
===================================================================
/* ====================================================================
* 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
* <http://www.apache.org/>.
*/
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();
}
}
1.7 +31 -8 jakarta-poi/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java
Index: TestFormulaParser.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/testcases/org/apache/poi/hssf/model/TestFormulaParser.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- TestFormulaParser.java 4 May 2003 18:22:09 -0000 1.6
+++ TestFormulaParser.java 7 May 2003 03:40:52 -0000 1.7
@@ -251,16 +251,39 @@
}
- public void testSimpleLogical() {
- FormulaParser fp=new FormulaParser("IF(A1<A2,B1,B2)",null);
- fp.parse();
- Ptg[] ptgs = fp.getRPNPtg();
- assertTrue("Ptg array should not be null", ptgs !=null);
- assertEquals("Ptg array length", 9, ptgs.length);
- assertEquals("3rd Ptg is less than",LessThanPtg.class,ptgs[2].getClass());
+ public void testSimpleLogical() {
+ FormulaParser fp=new FormulaParser("IF(A1<A2,B1,B2)",null);
+ fp.parse();
+ Ptg[] ptgs = fp.getRPNPtg();
+ assertTrue("Ptg array should not be null", ptgs !=null);
+ assertEquals("Ptg array length", 9, ptgs.length);
+ assertEquals("3rd Ptg is less than",LessThanPtg.class,ptgs[2].getClass());
- }
+ }
+
+ public void testParenIf() {
+ FormulaParser fp=new FormulaParser("IF((A1+A2)<=3,\"yes\",\"no\")",null);
+ fp.parse();
+ Ptg[] ptgs = fp.getRPNPtg();
+ assertTrue("Ptg array should not be null", ptgs !=null);
+ assertEquals("Ptg array length", 12, ptgs.length);
+ assertEquals("6th Ptg is less than equal",LessEqualPtg.class,ptgs[5].getClass());
+ assertEquals("11th Ptg is not a goto (Attr) ptg",AttrPtg.class,ptgs[10].getClass());
+ }
+
+ public void testEmbeddedIf() {
+ FormulaParser fp=new FormulaParser("IF(3>=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");