All Downloads are FREE. Search and download functionalities are using the official Maven repository.

Explore the source code of the class excel-formula.g


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("