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

%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 ~ctx:{ f = (fun _ -> None) } $loc op expr
    }
    %prec NO
  | expr1 = expression op = binary_operator expr2 = expression
    {
      Analyzer.Expression.boperator ~ctx:{ f = (fun _ -> None) } $loc op expr1 expr2
    }
  | v = delimited(TEXT_MARKER, list(literal), TEXT_MARKER)
    {
      Analyzer.Expression.literal ~ctx:{ f = (fun _ -> None) } $loc v
    }
  | i = INTEGER
    {
      Analyzer.Expression.integer ~ctx:{ f = (fun _ -> None) } $loc i
    }
  | v = variable
    { Analyzer.Expression.ident ~ctx:{ f = (fun _ -> None) } v }
    %prec p_variable
  | k = FUNCTION arg = argument(expression)
    {
      Analyzer.Expression.function_ ~ctx:{ f = (fun _ -> None) } $loc k arg
    }

  (* Function without any argument can be used either
    - without any parens
    - or with parens but empty and with nothing inside
  *)
  | k = FUNCTION_NOARGS
    {
      Analyzer.Expression.function_ ~ctx:{ f = (fun _ -> None) } $loc k []
    }
  | k = FUNCTION_NOARGS L_PAREN R_PAREN
    {
      Analyzer.Expression.function_ ~ctx:{ f = (fun _ -> None) } $loc k []
    }

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 = option(
      delimited(L_BRACKET, option(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 }
    }