header { import struct import Utils from UnicodeUtils import upack1 from ExcelMagic import * _RVAdelta = {"R": 0, "V": 0x20, "A": 0x40} _RVAdeltaRef = {"R": 0, "V": 0x20, "A": 0x40, "D": 0x20} _RVAdeltaArea = {"R": 0, "V": 0x20, "A": 0x40, "D": 0} class FormulaParseException(Exception): """ An exception indicating that a Formula could not be successfully parsed. """ } header "ExcelFormulaParser.__init__" { self.rpn = "" self.sheet_references = [] self.xcall_references = [] } options { language = "Python"; } class ExcelFormulaParser extends Parser; options { k = 2; defaultErrorHandler = false; buildAST = false; } tokens { TRUE_CONST; FALSE_CONST; STR_CONST; NUM_CONST; INT_CONST; FUNC_IF; FUNC_CHOOSE; NAME; QUOTENAME; EQ; NE; GT; LT; GE; LE; ADD; SUB; MUL; DIV; POWER; PERCENT; LP; RP; LB; RB; COLON; COMMA; SEMICOLON; REF2D; REF2D_R1C1; BANG; } formula : expr["V"] ; expr[arg_type] : // {print "\n**expr %s" % arg_type} prec0_expr[arg_type] ( ( EQ { op = struct.pack('B', ptgEQ) } | NE { op = struct.pack('B', ptgNE) } | GT { op = struct.pack('B', ptgGT) } | LT { op = struct.pack('B', ptgLT) } | GE { op = struct.pack('B', ptgGE) } | LE { op = struct.pack('B', ptgLE) } ) prec0_expr[arg_type] { self.rpn += op } )* ; prec0_expr[arg_type] : prec1_expr[arg_type] ( ( CONCAT { op = struct.pack('B', ptgConcat) } ) prec1_expr[arg_type] { self.rpn += op } )* ; prec1_expr[arg_type] : // {print "**prec1_expr1 %s" % arg_type} prec2_expr[arg_type] // {print "**prec1_expr2 %s" % arg_type} ( ( ADD { op = struct.pack('B', ptgAdd) } | SUB { op = struct.pack('B', ptgSub) } ) // {print "**prec1_expr3 %s" % arg_type} prec2_expr[arg_type] { self.rpn += op; // print "**prec1_expr4 %s" % arg_type } )* ; prec2_expr[arg_type] : prec3_expr[arg_type] ( ( MUL { op = struct.pack('B', ptgMul) } | DIV { op = struct.pack('B', ptgDiv) } ) prec3_expr[arg_type] { self.rpn += op } )* ; prec3_expr[arg_type] : prec4_expr[arg_type] ( ( POWER { op = struct.pack('B', ptgPower) } ) prec4_expr[arg_type] { self.rpn += op } )* ; prec4_expr[arg_type] : prec5_expr[arg_type] ( PERCENT { self.rpn += struct.pack('B', ptgPercent) } )? ; prec5_expr[arg_type] : primary[arg_type] | SUB primary[arg_type] { self.rpn += struct.pack('B', ptgUminus) } ; primary[arg_type] : TRUE_CONST { self.rpn += struct.pack("2B", ptgBool, 1) } | FALSE_CONST { self.rpn += struct.pack("2B", ptgBool, 0) } | str_tok:STR_CONST { self.rpn += struct.pack("B", ptgStr) + upack1(str_tok.text[1:-1].replace("\"\"", "\"")) } | int_tok:INT_CONST { // print "**int_const", int_tok.text int_value = int(int_tok.text) if int_value <= 65535: self.rpn += struct.pack("