Hi All, but especially Avik.
Attached inline please see a patch demonstrating formula elements as the
key parser pieces. This doesn't RPN yet.. I started with "precedence"
but haven't implemented...much of anything yet.
I imagine the if statements will be replaced with a method similar to
o.a.p.h.r.RecordFactory in the final version. (except all ptgs will be
stored in an array as opposed to a map)
Let me know what you think of this approach. I'm not committing this
because it may break some things for 1.5 (and since we don't HAVE to
branch, we shan't) and it doesn't meet coding standards yet.
I wrote what is in the current formula package but please no one think I
like it. I only committed it (before we had standards ;-) ) because
Marc was taking it over and I was doing other things. It will be
seriously commented, have tests applied and etc before I'm done.
I've committed Avik's current code despite it not meeting standards for
collaborative purposes (I'll make it meet standard soon).
Index: src/java/org/apache/poi/hssf/record/FormulaRecord.java
===================================================================
RCS file:
/home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/FormulaRecord.java,v
retrieving revision 1.4
diff -u -r1.4 FormulaRecord.java
--- src/java/org/apache/poi/hssf/record/FormulaRecord.java 17 Apr 2002 22:21:16
-0000 1.4
+++ src/java/org/apache/poi/hssf/record/FormulaRecord.java 18 Apr 2002 01:18:12
+-0000
@@ -157,7 +157,7 @@
int offset)
{
Stack stack = new Stack();
- int pos = 22 + offset;
+ /*int pos = 22 + offset;
while (pos < size)
{
@@ -165,7 +165,7 @@
pos += ptg.getSize();
stack.push(ptg);
- }
+ }*/
return stack;
}
Index: src/java/org/apache/poi/hssf/record/formula/AddPtg.java
===================================================================
RCS file:
/home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/formula/AddPtg.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 AddPtg.java
--- src/java/org/apache/poi/hssf/record/formula/AddPtg.java 31 Jan 2002 02:23:44
-0000 1.1.1.1
+++ src/java/org/apache/poi/hssf/record/formula/AddPtg.java 18 Apr 2002 01:18:12
+-0000
@@ -71,6 +71,8 @@
{
public final static int SIZE = 1;
public final static byte sid = 0x03;
+
+ private final static String ADD = "+";
/** Creates new AddPtg */
@@ -83,6 +85,10 @@
// doesn't need anything
}
+
+ protected AddPtg(String formula, int offset) {
+
+ }
public void writeBytes(byte [] array, int offset)
{
@@ -108,6 +114,21 @@
{
return "+";
}
+
+
+ public static boolean isNextStringToken(String formula, int pos) {
+ boolean retval = false;
+ while (pos < formula.length() && Character.isWhitespace(formula.charAt(pos)))
+{
+ pos++;
+ }
+
+ if (pos < formula.length()) {
+ if (formula.charAt(pos) == ADD.toCharArray()[0]) {
+ retval = true;
+ }
+ }
+ return retval;
+ }
public String toFormulaString(Ptg [] operands)
{
@@ -117,5 +138,13 @@
buffer.append("+");
buffer.append(operands[ 1 ].toFormulaString());
return buffer.toString();
+ }
+
+ public int getPrecedence() {
+ return 5;
+ }
+
+ public int getStringLength() {
+ return 1;
}
}
Index: src/java/org/apache/poi/hssf/record/formula/IntPtg.java
===================================================================
RCS file:
/home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/formula/IntPtg.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 IntPtg.java
--- src/java/org/apache/poi/hssf/record/formula/IntPtg.java 31 Jan 2002 02:23:44
-0000 1.1.1.1
+++ src/java/org/apache/poi/hssf/record/formula/IntPtg.java 18 Apr 2002 01:18:12
+-0000
@@ -75,6 +75,8 @@
public final static byte sid = 0x1e;
private short field_1_value;
+ private String val;
+ private int strlen = 0;
/** Creates new IntPtg */
public IntPtg()
@@ -85,6 +87,14 @@
{
setValue(LittleEndian.getShort(data, offset + 1));
}
+
+ protected IntPtg(String formula, int offset) {
+ val = parseString(formula, offset);
+ if (val == null) throw new RuntimeException("WHOOAA there...thats got no
+int!");
+ strlen=val.length();
+ field_1_value = Short.parseShort(val);
+ }
+
public void setValue(short value)
{
@@ -111,4 +121,45 @@
{
return "" + getValue();
}
+
+ private static String parseString(String formula, int pos) {
+ String retval = null;
+ while (pos < formula.length() && Character.isWhitespace(formula.charAt(pos)))
+{
+ pos++;
+ }
+
+ if (pos < formula.length()) {
+ if (Character.isDigit(formula.charAt(pos)) ) {
+ int numpos = pos;
+
+ while (numpos < formula.length() &&
+Character.isDigit(formula.charAt(numpos))){
+ numpos++;
+ }
+
+ if (numpos == formula.length() || formula.charAt(numpos) != '.') {
+ String numberstr = formula.substring(pos,numpos);
+ try {
+ int number = Short.parseShort(numberstr);
+ retval = numberstr;
+ } catch (NumberFormatException e) {
+ retval = null;
+ }
+ }
+ }
+ }
+ return retval;
+
+ }
+
+ public static boolean isNextStringToken(String formula, int pos) {
+ return (parseString(formula,pos) != null);
+ }
+
+ public int getPrecedence() {
+ return 5;
+ }
+
+ public int getStringLength() {
+ return strlen;
+ }
}
Index: src/java/org/apache/poi/hssf/record/formula/Ptg.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/record/formula/Ptg.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 Ptg.java
--- src/java/org/apache/poi/hssf/record/formula/Ptg.java 31 Jan 2002 02:23:44
-0000 1.1.1.1
+++ src/java/org/apache/poi/hssf/record/formula/Ptg.java 18 Apr 2002 01:18:12
+-0000
@@ -60,6 +60,9 @@
*/
package org.apache.poi.hssf.record.formula;
+import java.util.List;
+import java.util.ArrayList;
+
/**
*
* @author andy
@@ -69,12 +72,78 @@
{
/** Creates new Ptg */
-
+
public Ptg()
{
}
+
+ public static Ptg[] parse(String formula, int offset) {
+ List ptgs = new ArrayList();
+
+ while (offset < formula.length()) {
+ Ptg ptg = getNextToken(formula,offset);
+ offset += ptg.getStringLength();
+ ptgs.add(ptg);
+ }
+
+ Ptg[] retval = new Ptg[ptgs.size()];
+ retval = (Ptg[])ptgs.toArray(retval);
+ return retval;
+ }
+
+ public static String ptgsToString(Ptg[] ptgs) {
+ StringBuffer res = new StringBuffer();
+ for (int k =0; k < ptgs.length; k++) {
+ Ptg ptg = ptgs[k];
+ res.append(ptg.toFormulaString());
+ }
+ return res.toString();
+ }
+
+ public static Ptg getNextToken(String formula, int offset) {
+ //later use array of reflected methods like RecordFactory
+ Ptg retval = null;
+
+ if (AddPtg.isNextStringToken(formula,offset)) {
+ retval = new AddPtg(formula,offset);
+ } else if (IntPtg.isNextStringToken(formula,offset)) {
+ retval = new IntPtg(formula,offset);
+ } else {
+ throw new RuntimeException("didn't parse "+formula+" at " +offset);
+ }
+ return retval;
+ }
+
+/* private static List ptgsToList(Class [] ptgs)
+ {
+ List result = new ArrayList();
+ Constructor constructor;
- public static Ptg createPtg(byte [] data, int offset)
+ for (int i = 0; i < ptgs.length; i++)
+ {
+ Class ptg = null;
+
+ ptg = ptgs[ i ];
+ try
+ {
+
+ constructor = ptg.getConstructor(new Class[]
+ {
+ byte [].class, int.class
+ });
+ }
+ catch (Exception illegalArgumentException)
+ {
+ throw new RuntimeException(
+ "Now that didn't work nicely at all (couldn't do that there list
+of ptgs)");
+ }
+ result.add(constructor);
+ }
+ return result;
+ }*/
+
+
+ /*public static Ptg createPtg(byte [] data, int offset)
{
byte id = data[ offset + 0 ];
Ptg retval = null;
@@ -148,7 +217,7 @@
+ " (" + ( int ) id + ")");
}
return retval;
- }
+ }*/
public abstract int getSize();
@@ -164,4 +233,26 @@
public abstract void writeBytes(byte [] array, int offset);
public abstract String toFormulaString();
+
+ /**
+ * Ptg's should override this
+ */
+// public boolean isNextStringToken(String formula, int pos) {
+// return false;
+// }
+
+ public int getPrecedence() {
+ return 100;
+ }
+
+ public int getStringLength() {
+ return 0;
+ }
+
+ public static void main(String[] args) {
+ if (args != null && args[0] != null) {
+ System.out.println("Parsed Formula="+ ptgsToString(parse(args[0],0)));
+ }
+ }
+
}
Index: src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
===================================================================
RCS file: /home/cvs/jakarta-poi/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java,v
retrieving revision 1.4
diff -u -r1.4 HSSFSheet.java
--- src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java 14 Mar 2002 11:05:04
-0000 1.4
+++ src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java 18 Apr 2002 01:18:12
+-0000
@@ -171,6 +171,7 @@
hrow = getRow(cval.getRow());
}
lastrow = hrow;
+ log.log(DEBUG, "record id = "+
+Integer.toHexString(((Record)cval).getSid()));
hrow.createCellFromRecord(cval);
cval = sheet.getNextValueRecord();
log.log(DEBUG, "record took ",
--
http://www.superlinksoftware.com
http://jakarta.apache.org/poi - port of Excel/Word/OLE 2 Compound
Document
format to java
http://developer.java.sun.com/developer/bugParade/bugs/4487555.html
- fix java generics!
The avalanche has already started. It is too late for the pebbles to
vote.
-Ambassador Kosh