Fixed FormulaParser to allow negative elements in array literals.

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@893898 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Josh Micich 2009-12-25 23:26:47 +00:00
parent e9d0f5aeb6
commit e39f7c367f
2 changed files with 37 additions and 6 deletions

View File

@ -1209,9 +1209,13 @@ public final class FormulaParser {
case 'F': case 'f': case 'F': case 'f':
case 'T': case 't': case 'T': case 't':
return parseBooleanLiteral(); return parseBooleanLiteral();
case '-':
Match('-');
SkipWhite();
return convertArrayNumber(parseNumber(), false);
} }
// else assume number // else assume number
return convertArrayNumber(parseNumber()); return convertArrayNumber(parseNumber(), true);
} }
private Boolean parseBooleanLiteral() { private Boolean parseBooleanLiteral() {
@ -1225,14 +1229,19 @@ public final class FormulaParser {
throw expected("'TRUE' or 'FALSE'"); throw expected("'TRUE' or 'FALSE'");
} }
private static Double convertArrayNumber(Ptg ptg) { private static Double convertArrayNumber(Ptg ptg, boolean isPositive) {
double value;
if (ptg instanceof IntPtg) { if (ptg instanceof IntPtg) {
return new Double(((IntPtg)ptg).getValue()); value = ((IntPtg)ptg).getValue();
} else if (ptg instanceof NumberPtg) {
value = ((NumberPtg)ptg).getValue();
} else {
throw new RuntimeException("Unexpected ptg (" + ptg.getClass().getName() + ")");
} }
if (ptg instanceof NumberPtg) { if (!isPositive) {
return new Double(((NumberPtg)ptg).getValue()); value = -value;
} }
throw new RuntimeException("Unexpected ptg (" + ptg.getClass().getName() + ")"); return new Double(value);
} }
private Ptg parseNumber() { private Ptg parseNumber() {

View File

@ -871,6 +871,28 @@ public final class TestFormulaParser extends TestCase {
confirmTokenClasses(ptgs2, ArrayPtg.class, IntPtg.class, FuncVarPtg.class); confirmTokenClasses(ptgs2, ArrayPtg.class, IntPtg.class, FuncVarPtg.class);
} }
public void testParseArrayNegativeElement() {
Ptg[] ptgs;
try {
ptgs = parseFormula("{-42}");
} catch (FormulaParseException e) {
if (e.getMessage().equals("Parse error near char 1 '-' in specified formula '{-42}'. Expected Integer")) {
throw new AssertionFailedError("Identified bug - failed to parse negative array element.");
}
throw e;
}
confirmTokenClasses(ptgs, ArrayPtg.class);
Object element = ((ArrayPtg)ptgs[0]).getTokenArrayValues()[0][0];
assertEquals(-42.0, ((Double)element).doubleValue(), 0.0);
// Should be able to handle whitespace between unary minus and digits (Excel
// accepts this formula after presenting the user with a confirmation dialog).
ptgs = parseFormula("{- 5}");
element = ((ArrayPtg)ptgs[0]).getTokenArrayValues()[0][0];
assertEquals(-5.0, ((Double)element).doubleValue(), 0.0);
}
public void testRangeOperator() { public void testRangeOperator() {
HSSFWorkbook wb = new HSSFWorkbook(); HSSFWorkbook wb = new HSSFWorkbook();