first commit

This commit is contained in:
2025-07-28 13:56:49 +05:30
commit e9eb805edb
3438 changed files with 520990 additions and 0 deletions

View File

@@ -0,0 +1,325 @@
package jxl.biff.formula;
import common.Assert;
import common.Logger;
import java.util.Stack;
import jxl.Cell;
import jxl.WorkbookSettings;
import jxl.biff.WorkbookMethods;
class TokenFormulaParser implements Parser {
private static Logger logger = Logger.getLogger(TokenFormulaParser.class);
private byte[] tokenData;
private Cell relativeTo;
private int pos;
private ParseItem root;
private Stack tokenStack;
private ExternalSheet workbook;
private WorkbookMethods nameTable;
private WorkbookSettings settings;
public TokenFormulaParser(byte[] data, Cell c, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws) {
this.tokenData = data;
this.pos = 0;
this.relativeTo = c;
this.workbook = es;
this.nameTable = nt;
this.tokenStack = new Stack();
this.settings = ws;
}
public void parse() throws FormulaException {
parseSubExpression(this.tokenData.length);
this.root = this.tokenStack.pop();
Assert.verify(this.tokenStack.empty());
}
private void parseSubExpression(int len) throws FormulaException {
int tokenVal = 0;
Token t = null;
Stack ifStack = new Stack();
int endpos = this.pos + len;
while (this.pos < endpos) {
tokenVal = this.tokenData[this.pos];
this.pos++;
t = Token.getToken(tokenVal);
if (t == Token.UNKNOWN)
throw new FormulaException(FormulaException.unrecognizedToken, tokenVal);
Assert.verify((t != Token.UNKNOWN));
if (t == Token.REF) {
CellReference cr = new CellReference(this.relativeTo);
this.pos += cr.read(this.tokenData, this.pos);
this.tokenStack.push(cr);
continue;
}
if (t == Token.REF) {
CellReferenceError cr = new CellReferenceError();
this.pos += cr.read(this.tokenData, this.pos);
this.tokenStack.push(cr);
continue;
}
if (t == Token.REFV) {
SharedFormulaCellReference cr = new SharedFormulaCellReference(this.relativeTo);
this.pos += cr.read(this.tokenData, this.pos);
this.tokenStack.push(cr);
continue;
}
if (t == Token.REF3D) {
CellReference3d cr = new CellReference3d(this.relativeTo, this.workbook);
this.pos += cr.read(this.tokenData, this.pos);
this.tokenStack.push(cr);
continue;
}
if (t == Token.AREA) {
Area a = new Area();
this.pos += a.read(this.tokenData, this.pos);
this.tokenStack.push(a);
continue;
}
if (t == Token.AREAV) {
SharedFormulaArea a = new SharedFormulaArea(this.relativeTo);
this.pos += a.read(this.tokenData, this.pos);
this.tokenStack.push(a);
continue;
}
if (t == Token.AREA3D) {
Area3d a = new Area3d(this.workbook);
this.pos += a.read(this.tokenData, this.pos);
this.tokenStack.push(a);
continue;
}
if (t == Token.NAME) {
Name n = new Name();
this.pos += n.read(this.tokenData, this.pos);
this.tokenStack.push(n);
continue;
}
if (t == Token.NAMED_RANGE) {
NameRange nr = new NameRange(this.nameTable);
this.pos += nr.read(this.tokenData, this.pos);
this.tokenStack.push(nr);
continue;
}
if (t == Token.INTEGER) {
IntegerValue i = new IntegerValue();
this.pos += i.read(this.tokenData, this.pos);
this.tokenStack.push(i);
continue;
}
if (t == Token.DOUBLE) {
DoubleValue d = new DoubleValue();
this.pos += d.read(this.tokenData, this.pos);
this.tokenStack.push(d);
continue;
}
if (t == Token.BOOL) {
BooleanValue bv = new BooleanValue();
this.pos += bv.read(this.tokenData, this.pos);
this.tokenStack.push(bv);
continue;
}
if (t == Token.STRING) {
StringValue sv = new StringValue(this.settings);
this.pos += sv.read(this.tokenData, this.pos);
this.tokenStack.push(sv);
continue;
}
if (t == Token.MISSING_ARG) {
MissingArg ma = new MissingArg();
this.pos += ma.read(this.tokenData, this.pos);
this.tokenStack.push(ma);
continue;
}
if (t == Token.UNARY_PLUS) {
UnaryPlus up = new UnaryPlus();
this.pos += up.read(this.tokenData, this.pos);
addOperator(up);
continue;
}
if (t == Token.UNARY_MINUS) {
UnaryMinus um = new UnaryMinus();
this.pos += um.read(this.tokenData, this.pos);
addOperator(um);
continue;
}
if (t == Token.PERCENT) {
Percent p = new Percent();
this.pos += p.read(this.tokenData, this.pos);
addOperator(p);
continue;
}
if (t == Token.SUBTRACT) {
Subtract s = new Subtract();
this.pos += s.read(this.tokenData, this.pos);
addOperator(s);
continue;
}
if (t == Token.ADD) {
Add s = new Add();
this.pos += s.read(this.tokenData, this.pos);
addOperator(s);
continue;
}
if (t == Token.MULTIPLY) {
Multiply s = new Multiply();
this.pos += s.read(this.tokenData, this.pos);
addOperator(s);
continue;
}
if (t == Token.DIVIDE) {
Divide s = new Divide();
this.pos += s.read(this.tokenData, this.pos);
addOperator(s);
continue;
}
if (t == Token.CONCAT) {
Concatenate c = new Concatenate();
this.pos += c.read(this.tokenData, this.pos);
addOperator(c);
continue;
}
if (t == Token.POWER) {
Power p = new Power();
this.pos += p.read(this.tokenData, this.pos);
addOperator(p);
continue;
}
if (t == Token.LESS_THAN) {
LessThan lt = new LessThan();
this.pos += lt.read(this.tokenData, this.pos);
addOperator(lt);
continue;
}
if (t == Token.LESS_EQUAL) {
LessEqual lte = new LessEqual();
this.pos += lte.read(this.tokenData, this.pos);
addOperator(lte);
continue;
}
if (t == Token.GREATER_THAN) {
GreaterThan gt = new GreaterThan();
this.pos += gt.read(this.tokenData, this.pos);
addOperator(gt);
continue;
}
if (t == Token.GREATER_EQUAL) {
GreaterEqual gte = new GreaterEqual();
this.pos += gte.read(this.tokenData, this.pos);
addOperator(gte);
continue;
}
if (t == Token.NOT_EQUAL) {
NotEqual ne = new NotEqual();
this.pos += ne.read(this.tokenData, this.pos);
addOperator(ne);
continue;
}
if (t == Token.EQUAL) {
Equal e = new Equal();
this.pos += e.read(this.tokenData, this.pos);
addOperator(e);
continue;
}
if (t == Token.PARENTHESIS) {
Parenthesis p = new Parenthesis();
this.pos += p.read(this.tokenData, this.pos);
addOperator(p);
continue;
}
if (t == Token.ATTRIBUTE) {
Attribute a = new Attribute(this.settings);
this.pos += a.read(this.tokenData, this.pos);
if (a.isSum()) {
addOperator(a);
continue;
}
if (a.isIf())
ifStack.push(a);
continue;
}
if (t == Token.FUNCTION) {
BuiltInFunction bif = new BuiltInFunction(this.settings);
this.pos += bif.read(this.tokenData, this.pos);
addOperator(bif);
continue;
}
if (t == Token.FUNCTIONVARARG) {
VariableArgFunction vaf = new VariableArgFunction(this.settings);
this.pos += vaf.read(this.tokenData, this.pos);
if (vaf.getFunction() != Function.ATTRIBUTE) {
addOperator(vaf);
continue;
}
vaf.getOperands(this.tokenStack);
Attribute ifattr = null;
if (ifStack.empty()) {
ifattr = new Attribute(this.settings);
} else {
ifattr = ifStack.pop();
}
ifattr.setIfConditions(vaf);
this.tokenStack.push(ifattr);
continue;
}
if (t == Token.MEM_FUNC) {
MemFunc memFunc = new MemFunc();
this.pos += memFunc.read(this.tokenData, this.pos);
Stack oldStack = this.tokenStack;
this.tokenStack = new Stack();
parseSubExpression(memFunc.getLength());
ParseItem[] subexpr = new ParseItem[this.tokenStack.size()];
int i = 0;
while (!this.tokenStack.isEmpty()) {
subexpr[i] = this.tokenStack.pop();
i++;
}
memFunc.setSubExpression(subexpr);
this.tokenStack = oldStack;
this.tokenStack.push(memFunc);
}
}
}
private void addOperator(Operator o) {
o.getOperands(this.tokenStack);
this.tokenStack.push(o);
}
public String getFormula() {
StringBuffer sb = new StringBuffer();
this.root.getString(sb);
return sb.toString();
}
public void adjustRelativeCellReferences(int colAdjust, int rowAdjust) {
this.root.adjustRelativeCellReferences(colAdjust, rowAdjust);
}
public byte[] getBytes() {
return this.root.getBytes();
}
public void columnInserted(int sheetIndex, int col, boolean currentSheet) {
this.root.columnInserted(sheetIndex, col, currentSheet);
}
public void columnRemoved(int sheetIndex, int col, boolean currentSheet) {
this.root.columnRemoved(sheetIndex, col, currentSheet);
}
public void rowInserted(int sheetIndex, int row, boolean currentSheet) {
this.root.rowInserted(sheetIndex, row, currentSheet);
}
public void rowRemoved(int sheetIndex, int row, boolean currentSheet) {
this.root.rowRemoved(sheetIndex, row, currentSheet);
}
}