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 'T': case 't':
return parseBooleanLiteral();
case '-':
Match('-');
SkipWhite();
return convertArrayNumber(parseNumber(), false);
}
// else assume number
return convertArrayNumber(parseNumber());
return convertArrayNumber(parseNumber(), true);
}
private Boolean parseBooleanLiteral() {
@ -1225,15 +1229,20 @@ public final class FormulaParser {
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) {
return new Double(((IntPtg)ptg).getValue());
}
if (ptg instanceof NumberPtg) {
return new Double(((NumberPtg)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 (!isPositive) {
value = -value;
}
return new Double(value);
}
private Ptg parseNumber() {
String number2 = null;

View File

@ -871,6 +871,28 @@ public final class TestFormulaParser extends TestCase {
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() {
HSSFWorkbook wb = new HSSFWorkbook();