aboutsummaryrefslogtreecommitdiff
path: root/lib/qparser/qsp_expression.mly
blob: 937570171adc403e0df3860b1750353a160d7df4 (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
%%

%public arguments(X):
    (** This rule allow the difference between elements with a single argument 
        (when the separator is required) which allow to write a spectif case when
        we only have one element.
     *)
    | hd = X
      COMA
      tl = separated_nonempty_list(COMA, X)
      { hd :: tl }
    (** The case where we have nothing is easy to manage here *)
    |
      { [] }
    (** The remaining case (only one argument) is handled outside of this
        block: if we have a single argument we don’t have to bother with the
        paren, they belongs to the expression.
     *)

%inline argument(X):
    | a = delimited(L_PAREN, arguments(X), R_PAREN) { a }
    | a = X { [ a ] }

(** Declare an expression *)
%public expression:
    | ex = delimited(L_PAREN, expression, R_PAREN) 
      { ex }
    | op = unary_operator 
      expr = expression 
      { Analyzer.Expression.uoperator $loc  op  expr }
      %prec NO
    | 
      expr1 = expression 
      op = binary_operator 
      expr2 = expression 
      { Analyzer.Expression.boperator $loc op expr1 expr2 }
    | v = delimited(TEXT_MARKER, literal*, TEXT_MARKER)
      { Analyzer.Expression.literal $loc v }
    | i = INTEGER  { Analyzer.Expression.integer $loc i }
    | v = variable { Analyzer.Expression.ident v }
    %prec p_variable
    | k = FUNCTION
      arg = argument(expression)
    {
        (Analyzer.Expression.function_ $loc k arg)
    }
literal:
    | v = LITERAL { Qsp_syntax.T.Text v }
    | e = delimited(ENTER_EMBED, expression*, LEAVE_EMBED) 
      { Qsp_syntax.T.Expression e }

unary_operator:
    | OBJ
    | NO    { T.No }
    | MINUS { T.Neg }
    | PLUS  { T.Add }

%inline binary_operator:
    | EQUAL { T.Eq }
    | LT GT { T.Neq }
    | EXCLAMATION { T.Neq }
    | PLUS  { T.Plus }
    | MINUS { T.Minus }
    | STAR { T.Product }
    | DIV { T.Div }
    | MOD { T.Mod }
    | GT { T.Gt }
    | LT { T.Lt }
    | AND  { T.And }
    | GT EQUAL { T.Gte }
    | LT EQUAL { T.Lte }
    | EQUAL GT { T.Gte }
    | EQUAL LT { T.Lte }
    | OR { T.Or }

(** Declare a variable, either in the assignation (let var = …) or as a
    reference is an expression 
 *)
%public variable:
    | name = IDENT
      brackets = delimited(L_BRACKET, expression?, R_BRACKET)?
    { 
        let index = match brackets with 
        | None -> 
            (* No declaration, consider index at 0 *)
            None
        | Some other -> other in
        Qsp_syntax.S.{ pos = $loc ; name ; index }
    }