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");