aboutsummaryrefslogtreecommitdiff
path: root/src/odf/odf_ExpressionParser.mly
blob: 1b9e8e2766d89c4c94d2089311542222fb151ef7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
(*
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 <http://www.gnu.org/licenses/>.
*)

%{
    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 <string> REAL
%token <string> NUM
%token <string> STR

%token <string> LETTERS
%token <string> 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<ScTypes.Expr.t> 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 }