-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.mly
112 lines (108 loc) · 3.11 KB
/
parser.mly
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
%{
open Types
%}
%token EOI
%token<Range.t> DEFEQ EQ BAR BRECORD ERECORD LPAREN RPAREN LBRACKET RBRACKET COLON COMMA
%token<Range.t> META_OUTPUT META_LANGUAGE_VERSION META_EXTERNAL
%token<Range.t * Types.parsed_variable> VARIABLE
%token<Range.t * string> LOWER
%token<Range.t * string> UPPER
%token<Range.t * string> STRING
%start toplevel
%type<((Range.t * Types.parsed_constructor) * Types.parsed_message option) list> variant
%type<Types.top_level> toplevel
%type<(Range.t * Types.parsed_variable) list> params
%type<Types.parsed_message list> argssub
%type<Types.meta_spec> meta
%%
toplevel:
| metas=list(meta); decls=list(msgdecl); EOI { (metas, decls) }
;
meta:
| META_OUTPUT; s=STRING; COLON; dict=dict { MetaOutput(s, dict) }
| META_LANGUAGE_VERSION; s=STRING { MetaLanguageVersion(s) }
;
dict:
| posL=BRECORD; fields=fields; posR=ERECORD {
let rng = Range.unite posL posR in
(rng, fields)
}
;
fields:
| { [] }
| field=field { field :: [] }
| field=field; COMMA; tail=fields { field :: tail }
;
field:
| key=LOWER; EQ; v=value { (key, v) }
;
value:
| tok=STRING {
let (rng, s) = tok in
(rng, VString(s))
}
| tokL=LBRACKET; rmvs=values; tokR=RBRACKET {
let rng = Range.unite tokL tokR in
(rng, VList(rmvs))
}
;
values:
| { [] }
| rmv=value { [ rmv ] }
| rmv=value; COMMA; rmvs=values { rmv :: rmvs }
;
msgdecl:
| name=msgname; params=params; DEFEQ; msg=msg {
(name, { pdef_params = params; pdef_main = PGivenNormal(msg); })
}
| name=msgname; params=params; DEFEQ; variant=variant {
(name, { pdef_params = params; pdef_main = PGivenVariant(variant) })
}
| name=msgname; params=params; DEFEQ; BRECORD; rcd=record; ERECORD {
(name, { pdef_params = params; pdef_main = PGivenRecord(rcd) })
}
| name=msgname; params=params; DEFEQ; externals=list(extern) {
(name, { pdef_params = params; pdef_main = PGivenExternal(externals) })
}
;
extern:
META_EXTERNAL; s=STRING; COLON; dict=dict { (s, dict) }
;
msgname:
| name=LOWER { name }
;
params:
| { [] }
| LPAREN; x=VARIABLE; tail=paramssub { x :: tail }
;
paramssub:
| RPAREN { [] }
| COMMA; RPAREN { [] }
| COMMA; x=VARIABLE; tail=paramssub { x :: tail }
;
key:
| key=LOWER { key }
;
msg:
| x=VARIABLE { PVariable(x) }
| name=msgname { PName(name, []) }
| name=msgname; LPAREN; msg=msg; tail=argssub { PName(name, msg :: tail) }
;
argssub:
| RPAREN { [] }
| COMMA; RPAREN { [] }
| COMMA; msg=msg; tail=argssub { msg :: tail }
;
record:
| { [] }
| key=key; COLON; msg=msg { (key, msg) :: [] }
| key=key; COLON; msg=msg; COMMA; tail=record { (key, msg) :: tail }
;
variant:
| ctor=UPPER; COLON; msg=msg; tail=list(barvariant) { (ctor, Some(msg)) :: tail }
| bv=barvariant; tail=list(barvariant) { bv :: tail }
;
barvariant:
| BAR; ctor=UPPER; COLON; msg=msg { (ctor, Some(msg)) }
| BAR; ctor=UPPER; { (ctor, None) }
;