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
|
%{
module T = Qsp_syntax.T
%}
%parameter<Analyzer: Qsp_syntax.S.Analyzer>
%start <Analyzer.Location.repr>main
%%
main:
| EOL*
LOCATION_START
EOL+
expressions = line_statement*
LOCATION_END
{
Analyzer.Location.location $loc expressions
}
(* All these statement should terminate with EOL *)
line_statement:
| COMMENT EOL+ { Analyzer.Instruction.comment $loc }
| COLUMN i=IDENT EOL* { Analyzer.Instruction.location $loc i }
| s = terminated(instruction, line_sep)
| s = terminated(inline_action, line_sep)
{ s }
| a = action_bloc(IF, elif_else_body)
{ let loc, expression, statements, loc_s, body = a in
let elifs, else_ = match body with
| None -> [], []
| Some (elifs, else_) -> (elifs, else_)
in
Analyzer.Instruction.if_
loc
(loc_s, expression, statements)
~elifs
~else_
}
| a = action_bloc(ACT, empty_body)
{ let loc, label, statements, _, _ = a in
Analyzer.Instruction.act loc ~label statements
}
(** Represent an instruction which can either be on a single line,
or created in a block until an END
*)
%inline action_bloc(TOKEN, BODY):
| TOKEN
e = expression
COLUMN EOL+
s = line_statement*
b = BODY
END TOKEN?
line_sep
{ $loc, e, s, $loc(s), b }
empty_body:
| { None }
elif:
| ELIF
e = expression
COLUMN EOL+
s = line_statement*
{ $loc, e, s }
else_:
| ELSE EOL+
expressions = line_statement*
{ expressions }
| { [] }
elif_else_body:
| elifs = elif*
else_ = else_
{ Some (elifs, else_) }
%inline line_sep:
| EOL+
| AMPERSAND+ EOL*
{}
|