(* This file is part of licht. licht is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. licht is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with licht. If not, see . *) %{ open ScTypes module S = Symbols let u = UTF8.from_utf8string let extractColumnNameFromNum (fixed, str) = (fixed, int_of_string str) let build_call ident = function | [] -> Expr.call0 ident | [p1] -> Expr.call1 ident p1 | [p1;p2] -> Expr.call2 ident p1 p2 | [p1;p2;p3] -> Expr.call3 ident p1 p2 p3 | n -> Expr.callN ident n %} %token REAL %token NUM %token STR %token LETTERS %token IDENT %token DOLLAR %token DOT %token LPAREN RPAREN %token L_SQ_BRACKET R_SQ_BRACKET %token PLUS %token TIMES %token DIVIDE %token MINUS %token EQ NEQ %token LT LE GT GE %token EOF %token COLON SEMICOLON %token POW %nonassoc EQ NEQ LT LE GT GE %left PLUS MINUS %left TIMES DIVIDE %left POW %start value %% value: | LETTERS COLON EQ expr EOF {$4} expr: | num {Expr.value (Type.number ($1))} | MINUS expr {Expr.call1 S.sub $2} | PLUS expr {Expr.call1 S.add $2} | L_SQ_BRACKET ref R_SQ_BRACKET {$2} | LPAREN expr RPAREN {Expr.expression $2} | STR {Expr.value (Type.string (u $1))} (* Mathematical operators *) | expr MINUS expr {Expr.call2 S.sub $1 $3} | expr DIVIDE expr {Expr.call2 S.div $1 $3} | expr TIMES expr {Expr.call2 S.mul $1 $3} | expr PLUS expr {Expr.call2 S.add $1 $3} | expr POW expr {Expr.call2 S.pow $1 $3} (* Comparaison *) | expr EQ expr {Expr.call2 S.eq $1 $3} | expr NEQ expr {Expr.call2 S.neq $1 $3} | expr LT expr {Expr.call2 S.lt $1 $3} | expr GT expr {Expr.call2 S.gt $1 $3} | expr LE expr {Expr.call2 S.le $1 $3} | expr GE expr {Expr.call2 S.ge $1 $3} | ident LPAREN separated_list(SEMICOLON, expr) RPAREN { build_call (u $1) $3 } ref: | cell {Expr.ref (Refs.cell $1)} | cell COLON cell {Expr.ref (Refs.range $1 $3)} cell: | DOT fixed(LETTERS) fixed(NUM){Cell.from_string $2 (extractColumnNameFromNum $3)} fixed(X): | DOLLAR X {true, $2} | X {false, $1} num: | REAL {DataType.Num.of_float @@ float_of_string $1} | NUM {DataType.Num.of_int @@ int_of_string $1} ident: | IDENT { $1 } | text+ { String.concat "" $1 } text: | LETTERS { $1 } | NUM { $1 }