%{ open ScTypes module F = Functions let u = UTF8.from_utf8string let extractColumnNameFromNum (fixed, (str, value)) = (fixed, value) %} %token REAL %token NUM %token STR %token LETTERS %token DOLLAR %token LPAREN %token RPAREN %token PLUS %token TIMES %token DIVIDE %token MINUS %token EQ NEQ %token LT LE GT GE %token EOF %token SEMICOLON %token COLON %token POW %nonassoc EQ NEQ LT LE GT GE %left PLUS MINUS %left TIMES DIVIDE %left POW %start value %start content %% value: | EQ expr EOF {$2} content: | basic EOF {$1} basic: | PLUS num {Result (number $2)} | MINUS num {Result (number (DataType.Num.neg $2))} | num {Result (number $1)} | NUM DIVIDE NUM DIVIDE NUM {Result ( date ( DataType.Date.get_julian_day (int_of_string $1) (int_of_string $3) (int_of_string $5) ))} | NUM COLON NUM COLON NUM {Result ( date ( let nhour = DataType.Num.div (DataType.Num.of_int @@ int_of_string $1) (DataType.Num.of_int 24) and nmin = DataType.Num.div (DataType.Num.of_int @@ int_of_string $3) (DataType.Num.of_int 1440) and nsec = DataType.Num.div (DataType.Num.of_int @@ int_of_string $5) (DataType.Num.of_int 86400) in DataType.Num.add (DataType.Num.add nhour nmin) nsec ) )} expr: | num {Value (number ($1))} | MINUS expr {Call (F.sub, [$2])} | PLUS expr {Call (F.add, [$2])} | LETTERS ident LPAREN separated_list(SEMICOLON, expr) RPAREN { Call (u($1 ^ $2), $4) } | cell {Ref (Cell $1)} | cell COLON cell {Ref (Range ($1, $3))} | LPAREN expr RPAREN {Expression $2} | STR {Value (string (u $1))} (* Mathematical operators *) | expr MINUS expr {Call (F.sub, [$1; $3])} | expr DIVIDE expr {Call (F.div, [$1; $3])} | expr TIMES expr {Call (F.mul, [$1; $3])} | expr PLUS expr {Call (F.add, [$1; $3])} | expr POW expr {Call (F.pow, [$1; $3])} (* Comparaison *) | expr EQ expr {Call (F.eq, [$1; $3])} | expr NEQ expr {Call (F.neq, [$1; $3])} | expr LT expr {Call (F.lt, [$1; $3])} | expr GT expr {Call (F.gt, [$1; $3])} | expr LE expr {Call (F.le, [$1; $3])} | expr GE expr {Call (F.ge, [$1; $3])} %inline cell: | LETTERS NUM { Cell.from_string (false, $1) (false, int_of_string $2) } | DOLLAR LETTERS NUM { Cell.from_string (true, $2) (false, int_of_string $3) } | LETTERS DOLLAR NUM { Cell.from_string (false, $1) (true, int_of_string $3) } | DOLLAR LETTERS DOLLAR NUM { Cell.from_string (true, $2) (true, int_of_string $4) } num: | REAL {DataType.Num.of_float @@ float_of_string $1} | NUM {DataType.Num.of_int @@ int_of_string $1} ident: | text* { String.concat "" $1 } text: | LETTERS { $1 } | NUM { $1 }