1 19 20 package jxl.biff.formula; 21 22 import java.util.Stack ; 23 24 import common.Assert; 25 import common.Logger; 26 27 import jxl.Cell; 28 import jxl.WorkbookSettings; 29 import jxl.biff.WorkbookMethods; 30 31 34 class TokenFormulaParser implements Parser 35 { 36 39 private static Logger logger = Logger.getLogger(TokenFormulaParser.class); 40 41 44 private byte[] tokenData; 45 46 50 private Cell relativeTo; 51 52 55 private int pos; 56 57 60 private ParseItem root; 61 62 65 private Stack tokenStack; 66 67 71 private ExternalSheet workbook; 72 73 76 private WorkbookMethods nameTable; 77 78 81 private WorkbookSettings settings; 82 83 86 public TokenFormulaParser(byte[] data, Cell c, ExternalSheet es, 87 WorkbookMethods nt, 88 WorkbookSettings ws) 89 { 90 tokenData = data; 91 pos = 0; 92 relativeTo = c; 93 workbook = es; 94 nameTable = nt; 95 tokenStack = new Stack (); 96 settings = ws; 97 } 98 99 105 public void parse() throws FormulaException 106 { 107 parseSubExpression(tokenData.length); 108 109 root = (ParseItem) tokenStack.pop(); 112 113 Assert.verify(tokenStack.empty()); 114 115 } 116 117 124 private void parseSubExpression(int len) throws FormulaException 125 { 126 int tokenVal = 0; 127 Token t = null; 128 129 Stack ifStack = new Stack (); 132 133 int endpos = pos + len; 135 136 while (pos < endpos) 137 { 138 tokenVal = tokenData[pos]; 139 pos++; 140 141 t = Token.getToken(tokenVal); 142 143 if (t == Token.UNKNOWN) 144 { 145 throw new FormulaException 146 (FormulaException.unrecognizedToken, tokenVal); 147 } 148 149 Assert.verify(t != Token.UNKNOWN); 150 151 if (t == Token.REF) 153 { 154 CellReference cr = new CellReference(relativeTo); 155 pos += cr.read(tokenData, pos); 156 tokenStack.push(cr); 157 } 158 else if (t == Token.REFV) 159 { 160 SharedFormulaCellReference cr = 161 new SharedFormulaCellReference(relativeTo); 162 pos += cr.read(tokenData, pos); 163 tokenStack.push(cr); 164 } 165 else if (t == Token.REF3D) 166 { 167 CellReference3d cr = new CellReference3d(relativeTo, workbook); 168 pos += cr.read(tokenData, pos); 169 tokenStack.push(cr); 170 } 171 else if (t == Token.AREA) 172 { 173 Area a = new Area(); 174 pos += a.read(tokenData, pos); 175 tokenStack.push(a); 176 } 177 else if (t == Token.AREAV) 178 { 179 SharedFormulaArea a = new SharedFormulaArea(relativeTo); 180 pos += a.read(tokenData, pos); 181 tokenStack.push(a); 182 } 183 else if (t == Token.AREA3D) 184 { 185 Area3d a = new Area3d(workbook); 186 pos += a.read(tokenData, pos); 187 tokenStack.push(a); 188 } 189 else if (t == Token.NAME) 190 { 191 Name n = new Name(); 192 pos += n.read(tokenData, pos); 193 tokenStack.push(n); 194 } 195 else if (t == Token.NAMED_RANGE) 196 { 197 NameRange nr = new NameRange(nameTable); 198 pos += nr.read(tokenData, pos); 199 tokenStack.push(nr); 200 } 201 else if (t == Token.INTEGER) 202 { 203 IntegerValue i = new IntegerValue(); 204 pos += i.read(tokenData, pos); 205 tokenStack.push(i); 206 } 207 else if (t == Token.DOUBLE) 208 { 209 DoubleValue d = new DoubleValue(); 210 pos += d.read(tokenData, pos); 211 tokenStack.push(d); 212 } 213 else if (t == Token.BOOL) 214 { 215 BooleanValue bv = new BooleanValue(); 216 pos += bv.read(tokenData, pos); 217 tokenStack.push(bv); 218 } 219 else if (t == Token.STRING) 220 { 221 StringValue sv = new StringValue(settings); 222 pos += sv.read(tokenData, pos); 223 tokenStack.push(sv); 224 } 225 else if (t == Token.MISSING_ARG) 226 { 227 MissingArg ma = new MissingArg(); 228 pos += ma.read(tokenData, pos); 229 tokenStack.push(ma); 230 } 231 232 else if (t == Token.UNARY_PLUS) 234 { 235 UnaryPlus up = new UnaryPlus(); 236 pos += up.read(tokenData, pos); 237 addOperator(up); 238 } 239 else if (t == Token.UNARY_MINUS) 240 { 241 UnaryMinus um = new UnaryMinus(); 242 pos += um.read(tokenData, pos); 243 addOperator(um); 244 } 245 else if (t == Token.PERCENT) 246 { 247 Percent p = new Percent(); 248 pos += p.read(tokenData, pos); 249 addOperator(p); 250 } 251 252 else if (t == Token.SUBTRACT) 254 { 255 Subtract s = new Subtract(); 256 pos += s.read(tokenData, pos); 257 addOperator(s); 258 } 259 else if (t == Token.ADD) 260 { 261 Add s = new Add(); 262 pos += s.read(tokenData, pos); 263 addOperator(s); 264 } 265 else if (t == Token.MULTIPLY) 266 { 267 Multiply s = new Multiply(); 268 pos += s.read(tokenData, pos); 269 addOperator(s); 270 } 271 else if (t == Token.DIVIDE) 272 { 273 Divide s = new Divide(); 274 pos += s.read(tokenData, pos); 275 addOperator(s); 276 } 277 else if (t == Token.CONCAT) 278 { 279 Concatenate c = new Concatenate(); 280 pos += c.read(tokenData, pos); 281 addOperator(c); 282 } 283 else if (t == Token.POWER) 284 { 285 Power p = new Power(); 286 pos += p.read(tokenData, pos); 287 addOperator(p); 288 } 289 else if (t == Token.LESS_THAN) 290 { 291 LessThan lt = new LessThan(); 292 pos += lt.read(tokenData, pos); 293 addOperator(lt); 294 } 295 else if (t == Token.LESS_EQUAL) 296 { 297 LessEqual lte = new LessEqual(); 298 pos += lte.read(tokenData, pos); 299 addOperator(lte); 300 } 301 else if (t == Token.GREATER_THAN) 302 { 303 GreaterThan gt = new GreaterThan(); 304 pos += gt.read(tokenData, pos); 305 addOperator(gt); 306 } 307 else if (t == Token.GREATER_EQUAL) 308 { 309 GreaterEqual gte = new GreaterEqual(); 310 pos += gte.read(tokenData, pos); 311 addOperator(gte); 312 } 313 else if (t == Token.NOT_EQUAL) 314 { 315 NotEqual ne = new NotEqual(); 316 pos += ne.read(tokenData, pos); 317 addOperator(ne); 318 } 319 else if (t == Token.EQUAL) 320 { 321 Equal e = new Equal(); 322 pos += e.read(tokenData, pos); 323 addOperator(e); 324 } 325 else if (t == Token.PARENTHESIS) 326 { 327 Parenthesis p = new Parenthesis(); 328 pos += p.read(tokenData, pos); 329 addOperator(p); 330 } 331 332 else if (t == Token.ATTRIBUTE) 334 { 335 Attribute a = new Attribute(settings); 336 pos += a.read(tokenData, pos); 337 338 if (a.isSum()) 339 { 340 addOperator(a); 341 } 342 else if (a.isIf()) 343 { 344 ifStack.push(a); 346 } 347 } 348 else if (t == Token.FUNCTION) 349 { 350 BuiltInFunction bif = new BuiltInFunction(settings); 351 pos += bif.read(tokenData, pos); 352 353 addOperator(bif); 354 } 355 else if (t == Token.FUNCTIONVARARG) 356 { 357 VariableArgFunction vaf = new VariableArgFunction(settings); 358 pos += vaf.read(tokenData, pos); 359 360 if (vaf.getFunction() != Function.ATTRIBUTE) 361 { 362 addOperator(vaf); 363 } 364 else 365 { 366 vaf.getOperands(tokenStack); 369 370 Attribute ifattr = null; 371 if (ifStack.empty()) 372 { 373 ifattr = new Attribute(settings); 374 } 375 else 376 { 377 ifattr = (Attribute) ifStack.pop(); 378 } 379 380 ifattr.setIfConditions(vaf); 381 tokenStack.push(ifattr); 382 } 383 } 384 385 else if (t == Token.MEM_FUNC) 387 { 388 MemFunc memFunc = new MemFunc(); 389 pos += memFunc.read(tokenData, pos); 390 391 Stack oldStack = tokenStack; 393 tokenStack = new Stack (); 394 395 parseSubExpression(memFunc.getLength()); 396 397 ParseItem[] subexpr = new ParseItem[tokenStack.size()]; 398 int i = 0; 399 while (!tokenStack.isEmpty()) 400 { 401 subexpr[i] = (ParseItem) tokenStack.pop(); 402 i++; 403 } 404 405 memFunc.setSubExpression(subexpr); 406 407 tokenStack = oldStack; 408 tokenStack.push(memFunc); 409 } 410 } 411 } 412 413 417 private void addOperator(Operator o) 418 { 419 o.getOperands(tokenStack); 421 422 tokenStack.push(o); 424 } 425 426 429 public String getFormula() 430 { 431 StringBuffer sb = new StringBuffer (); 432 root.getString(sb); 433 return sb.toString(); 434 } 435 436 443 public void adjustRelativeCellReferences(int colAdjust, int rowAdjust) 444 { 445 root.adjustRelativeCellReferences(colAdjust, rowAdjust); 446 } 447 448 454 public byte[] getBytes() 455 { 456 return root.getBytes(); 457 } 458 459 469 public void columnInserted(int sheetIndex, int col, boolean currentSheet) 470 { 471 root.columnInserted(sheetIndex, col, currentSheet); 472 } 473 483 public void columnRemoved(int sheetIndex, int col, boolean currentSheet) 484 { 485 root.columnRemoved(sheetIndex, col, currentSheet); 486 } 487 488 498 public void rowInserted(int sheetIndex, int row, boolean currentSheet) 499 { 500 root.rowInserted(sheetIndex, row, currentSheet); 501 } 502 503 513 public void rowRemoved(int sheetIndex, int row, boolean currentSheet) 514 { 515 root.rowRemoved(sheetIndex, row, currentSheet); 516 } 517 } 518 519 520 521 522 523 524 525 526 527 | Popular Tags |