-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathParser.grm
335 lines (312 loc) · 15.3 KB
/
Parser.grm
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
fun makeUnaryFunction (name,constr) = (name, Syntax.Func (["x"], constr (Syntax.ID ("x"))))
fun makeBinaryFunction (name,constr) = (name, Syntax.Func (["x","y"], constr (Syntax.ID ("x"), Syntax.ID ("y"))))
(* Define the predefined functions *)
val predef = List.map makeUnaryFunction
[("-", Syntax.UMINUS),
("d", Syntax.D),
("z", Syntax.Z),
("sum", Syntax.SUM),
("sign", Syntax.SIGN),
("count", Syntax.COUNT),
("min",fn (e) => Syntax.LEAST (Syntax.NUM (1), e)),
("max",fn (e) => Syntax.LARGEST (Syntax.NUM (1), e)),
("minimal", Syntax.MINIMAL),
("maximal", Syntax.MAXIMAL),
("choose", Syntax.CHOOSE),
("different", Syntax.DIFFERENT) ]
@
List.map makeBinaryFunction
[("+", Syntax.PLUS),
("*", Syntax.TIMES),
("U", Syntax.CONC)]
%%
%name troll_parser
%pos int
%start Dice
%verbose
%noshift EOF
%eop EOF
%term NUM of int
| ID of string
| STRINGS of string list
| D
| Z
| SUM
| LEAST
| LARGEST
| MIN
| MAX
| CONC
| HASH
| COUNT
| AND
| PLUS
| MINUS
| TIMES
| DIVIDE
| MOD
| LPAR
| RPAR
| LBRACE
| RBRACE
| COMMA
| ASSGN
| EQ
| NEQ
| LT
| GT
| LE
| GE
| DOTDOT
| SEMI
| LET
| IN
| FOREACH
| DO
| IF
| THEN
| ELSE
| CHOOSE
| DROP
| KEEP
| PICK
| DIFFERENT
| MEDIAN
| ACCUM
| REPEAT
| WHILE
| UNTIL
| FUNCTION
| CALL
| COMPOSITIONAL
| EOF
| SAMPLE
| HCONC
| VCONCL
| VCONCR
| VCONCC
| UMINUS
| QUESTION
| MINIMAL
| MAXIMAL
| SETMINUS
| LBRACK
| RBRACK
| FIRST
| SECOND
| SIGN
| TILDE
| BANG
| REAL of real
%nonterm Dice of Syntax.Program
| Decl of (string * Syntax.Declaration)
| Decls of ((string * Syntax.Declaration) list)
| Exp of Syntax.Exp
| ExpNoUn of Syntax.Exp
| ExpList of Syntax.Exp
| ExpList1 of Syntax.Exp
| ExpList2 of Syntax.Exp list
| Ids of string list
| IDorUnop of string
| IDorBinop of string
%nonassoc FUNCTION
%right SEMI
%nonassoc DO ELSE WHILE UNTIL
%right VCONCL VCONCR VCONCC HCONC
%nonassoc DOTDOT
%left DROP KEEP PICK SETMINUS
%right CONC AND
%left PLUS MINUS
%left TIMES DIVIDE MOD
%nonassoc UMINUS
%nonassoc SUM COUNT LEAST LARGEST MIN MAX CHOOSE DIFFERENT SAMPLE MINIMAL MAXIMAL MEDIAN FIRST SECOND SIGN BANG
%right NEQ EQ LT GT LE GE
%right HASH TILDE
%left D Z
%%
Dice : Decls Exp Decls (Decls1 @ Decls2 @ predef, Exp)
Decls : Decl Decls (Decl :: Decls)
| ([])
Decl : FUNCTION ID LPAR Ids RPAR EQ Exp %prec FUNCTION (ID, Syntax.Func (Ids, Exp))
| COMPOSITIONAL ID LPAR Exp COMMA IDorUnop COMMA IDorBinop RPAR (ID, Syntax.Comp (Exp, IDorUnop, IDorBinop))
IDorUnop : ID (ID)
| MINUS ("-")
| D ("d")
| Z ("z")
| SUM ("sum")
| SIGN ("sgn")
| COUNT ("count")
| MIN ("min")
| MAX ("max")
| MINIMAL ("minimal")
| MAXIMAL ("maximal")
| CHOOSE ("choose")
| DIFFERENT ("different")
IDorBinop : ID (ID)
| PLUS ("+")
| TIMES ("*")
| CONC ("U")
Ids : ID ([ID])
| ID COMMA Ids (ID::Ids)
Exp : NUM (Syntax.NUM NUM)
| ID (Syntax.ID ID)
| Exp CONC Exp (Syntax.CONC (Exp1, Exp2))
| CHOOSE Exp (Syntax.CHOOSE (Exp))
| DIFFERENT Exp (Syntax.DIFFERENT (Exp))
| LBRACE ExpList RBRACE (ExpList)
| Exp PLUS Exp (Syntax.PLUS (Exp1, Exp2))
| Exp MINUS Exp (Syntax.MINUS (Exp1, Exp2))
| Exp TIMES Exp (Syntax.TIMES (Exp1, Exp2))
| Exp DIVIDE Exp (Syntax.DIVIDE (Exp1, Exp2))
| Exp MOD Exp (Syntax.MOD (Exp1, Exp2))
| SUM Exp (Syntax.SUM (Exp))
| SIGN Exp (Syntax.SIGN (Exp))
| COUNT Exp (Syntax.COUNT (Exp))
| MIN Exp (Syntax.LEAST (Syntax.NUM (1), Exp))
| MAX Exp (Syntax.LARGEST (Syntax.NUM (1), Exp))
| MEDIAN Exp (Syntax.MEDIAN (Exp))
| MINIMAL Exp (Syntax.MINIMAL (Exp))
| MAXIMAL Exp (Syntax.MAXIMAL (Exp))
| Exp HASH Exp (Syntax.HASH (Exp1, Exp2))
| Exp AND Exp (Syntax.AND (Exp1, Exp2))
| D Exp (Syntax.D (Exp))
| Exp Z Exp %prec HASH (Syntax.HASH (Exp1,Syntax.Z (Exp2)))
| Exp D Exp %prec HASH (Syntax.HASH (Exp1,Syntax.D (Exp2)))
| Exp EQ Exp (Syntax.EQ (Exp1, Exp2))
| Exp NEQ Exp (Syntax.NEQ (Exp1, Exp2))
| Exp LT Exp (Syntax.LT (Exp1, Exp2))
| Exp GT Exp (Syntax.GT (Exp1, Exp2))
| Exp LE Exp (Syntax.LE (Exp1, Exp2))
| Exp GE Exp (Syntax.GE (Exp1, Exp2))
| Exp DROP Exp (Syntax.DROP (Exp1, Exp2))
| Exp KEEP Exp (Syntax.KEEP (Exp1, Exp2))
| Exp PICK Exp (Syntax.PICK (Exp1, Exp2))
| Exp SETMINUS Exp (Syntax.SETMINUS (Exp1, Exp2))
| Exp DOTDOT Exp (Syntax.FROMTO (Exp1,Exp2))
| ID ASSGN Exp SEMI Exp (Syntax.LET (ID, Exp1, Exp2))
| ACCUM ID ASSGN Exp WHILE Exp (Syntax.ACCUM (ID, Exp1, Exp2, true))
| ACCUM ID ASSGN Exp UNTIL Exp (Syntax.ACCUM (ID, Exp1, Exp2, false))
| REPEAT ID ASSGN Exp WHILE Exp (Syntax.REPEAT (ID, Exp1, Exp2, true))
| REPEAT ID ASSGN Exp UNTIL Exp (Syntax.REPEAT (ID, Exp1, Exp2, false))
| FOREACH ID IN Exp DO Exp (Syntax.FOREACH (ID, Exp1, Exp2) )
| IF Exp THEN Exp ELSE Exp (Syntax.IF (Exp1, Exp2, Exp3))
| CALL ID LPAR ExpList2 RPAR (Syntax.CALL (ID, ExpList2))
| Exp SAMPLE Exp %prec HASH (Syntax.SAMPLES (Exp1, Exp2))
| Exp HCONC Exp (Syntax.HCONC (Exp1, Exp2))
| Exp VCONCL Exp (Syntax.VCONCL (Exp1, Exp2))
| Exp VCONCR Exp (Syntax.VCONCR (Exp1, Exp2))
| Exp VCONCC Exp (Syntax.VCONCC (Exp1, Exp2))
| QUESTION REAL (Syntax.QUESTION (REAL))
| FIRST Exp (Syntax.FIRST (Exp))
| SECOND Exp (Syntax.SECOND (Exp))
| LBRACK Exp COMMA Exp RBRACK (Syntax.PAIR (Exp1, Exp2))
| BANG Exp (Syntax.IF (Exp, Syntax.EMPTY, Syntax.NUM (1)))
| ID TILDE Exp (Syntax.DEFAULT (ID, Exp))
| LPAR Exp RPAR (Exp)
| MINUS Exp %prec UMINUS (Syntax.UMINUS (Exp))
| Z Exp (Syntax.Z (Exp))
| SAMPLE Exp (Syntax.SAMPLE (Exp))
| LEAST ExpNoUn Exp (Syntax.LEAST (ExpNoUn, Exp))
| LEAST MINUS ExpNoUn Exp (Syntax.LEAST (Syntax.UMINUS(ExpNoUn), Exp))
| LEAST SAMPLE ExpNoUn Exp (Syntax.LEAST (Syntax.SAMPLE(ExpNoUn), Exp))
| LEAST D ExpNoUn Exp (Syntax.LEAST (Syntax.D(ExpNoUn), Exp))
| LEAST Z ExpNoUn Exp (Syntax.LEAST (Syntax.Z(ExpNoUn), Exp))
| LARGEST ExpNoUn Exp (Syntax.LARGEST (ExpNoUn,Exp))
| LARGEST MINUS ExpNoUn Exp (Syntax.LARGEST (Syntax.UMINUS(ExpNoUn), Exp))
| LARGEST SAMPLE ExpNoUn Exp (Syntax.LARGEST (Syntax.SAMPLE(ExpNoUn), Exp))
| LARGEST Z ExpNoUn Exp (Syntax.LARGEST (Syntax.Z(ExpNoUn), Exp))
| LARGEST D ExpNoUn Exp (Syntax.LARGEST (Syntax.D(ExpNoUn), Exp))
| STRINGS (let fun build [] = Syntax.STRING ("")
| build [s] = Syntax.STRING (s)
| build ("|>" :: ss) = Syntax.VCONCL(Syntax.STRING (""), build ss)
| build ("<|" :: ss) = Syntax.VCONCR(Syntax.STRING (""), build ss)
| build ("<>" :: ss) = Syntax.VCONCC(Syntax.STRING (""), build ss)
| build ("||" :: ss) = Syntax.HCONC(Syntax.STRING (""), build ss)
| build (s :: "|>" :: ss) = Syntax.VCONCL(Syntax.STRING (s), build ss)
| build (s :: "<|" :: ss) = Syntax.VCONCR(Syntax.STRING (s), build ss)
| build (s :: "<>" :: ss) = Syntax.VCONCC(Syntax.STRING (s), build ss)
| build (s :: "||" :: ss) = Syntax.HCONC(Syntax.STRING (s), build ss)
| build (s :: ss) = Syntax.HCONC(Syntax.STRING (s), build ss)
in
build (STRINGS)
end)
ExpNoUn : NUM (Syntax.NUM NUM)
| ID (Syntax.ID ID)
| ExpNoUn CONC ExpNoUn (Syntax.CONC (ExpNoUn1, ExpNoUn2))
| CHOOSE ExpNoUn (Syntax.CHOOSE (ExpNoUn))
| DIFFERENT ExpNoUn (Syntax.DIFFERENT (ExpNoUn))
| LBRACE ExpList RBRACE (ExpList)
| ExpNoUn PLUS ExpNoUn (Syntax.PLUS (ExpNoUn1, ExpNoUn2))
| ExpNoUn TIMES ExpNoUn (Syntax.TIMES (ExpNoUn1, ExpNoUn2))
| ExpNoUn DIVIDE ExpNoUn (Syntax.DIVIDE (ExpNoUn1, ExpNoUn2))
| ExpNoUn MOD ExpNoUn (Syntax.MOD (ExpNoUn1, ExpNoUn2))
| SUM ExpNoUn (Syntax.SUM (ExpNoUn))
| SIGN ExpNoUn (Syntax.SIGN (ExpNoUn))
| COUNT ExpNoUn (Syntax.COUNT (ExpNoUn))
| MIN ExpNoUn (Syntax.LEAST (Syntax.NUM (1), ExpNoUn))
| MAX ExpNoUn (Syntax.LARGEST (Syntax.NUM (1), ExpNoUn))
| MEDIAN ExpNoUn (Syntax.MEDIAN (ExpNoUn))
| MINIMAL ExpNoUn (Syntax.MINIMAL (ExpNoUn))
| MAXIMAL ExpNoUn (Syntax.MAXIMAL (ExpNoUn))
| ExpNoUn HASH ExpNoUn (Syntax.HASH (ExpNoUn1, ExpNoUn2))
| ExpNoUn AND ExpNoUn (Syntax.AND (ExpNoUn1, ExpNoUn2))
| ExpNoUn EQ ExpNoUn (Syntax.EQ (ExpNoUn1, ExpNoUn2))
| ExpNoUn NEQ ExpNoUn (Syntax.NEQ (ExpNoUn1, ExpNoUn2))
| ExpNoUn LT ExpNoUn (Syntax.LT (ExpNoUn1, ExpNoUn2))
| ExpNoUn GT ExpNoUn (Syntax.GT (ExpNoUn1, ExpNoUn2))
| ExpNoUn LE ExpNoUn (Syntax.LE (ExpNoUn1, ExpNoUn2))
| ExpNoUn GE ExpNoUn (Syntax.GE (ExpNoUn1, ExpNoUn2))
| ExpNoUn DROP ExpNoUn (Syntax.DROP (ExpNoUn1, ExpNoUn2))
| ExpNoUn KEEP ExpNoUn (Syntax.KEEP (ExpNoUn1, ExpNoUn2))
| ExpNoUn PICK ExpNoUn (Syntax.PICK (ExpNoUn1, ExpNoUn2))
| ExpNoUn SETMINUS Exp (Syntax.SETMINUS (ExpNoUn, Exp))
| ExpNoUn DOTDOT Exp (Syntax.FROMTO (ExpNoUn, Exp))
| ID ASSGN ExpNoUn SEMI ExpNoUn (Syntax.LET (ID, ExpNoUn1, ExpNoUn2))
| ACCUM ID ASSGN ExpNoUn WHILE ExpNoUn (Syntax.ACCUM (ID, ExpNoUn1, ExpNoUn2, true))
| ACCUM ID ASSGN ExpNoUn UNTIL ExpNoUn (Syntax.ACCUM (ID, ExpNoUn1, ExpNoUn2, false))
| REPEAT ID ASSGN ExpNoUn WHILE ExpNoUn (Syntax.REPEAT (ID, ExpNoUn1, ExpNoUn2, true))
| REPEAT ID ASSGN ExpNoUn UNTIL ExpNoUn (Syntax.REPEAT (ID, ExpNoUn1, ExpNoUn2, false))
| FOREACH ID IN ExpNoUn DO ExpNoUn (Syntax.FOREACH (ID, ExpNoUn1, ExpNoUn2))
| IF ExpNoUn THEN ExpNoUn ELSE ExpNoUn (Syntax.IF (ExpNoUn1, ExpNoUn2, ExpNoUn3))
| CALL ID LPAR ExpList2 RPAR (Syntax.CALL (ID, ExpList2))
| ExpNoUn HCONC ExpNoUn (Syntax.HCONC (ExpNoUn1,ExpNoUn2))
| ExpNoUn VCONCL ExpNoUn (Syntax.VCONCL (ExpNoUn1,ExpNoUn2))
| ExpNoUn VCONCR ExpNoUn (Syntax.VCONCR (ExpNoUn1,ExpNoUn2))
| ExpNoUn VCONCC ExpNoUn (Syntax.VCONCC (ExpNoUn1,ExpNoUn2))
| QUESTION REAL (Syntax.QUESTION (REAL))
| FIRST ExpNoUn (Syntax.FIRST (ExpNoUn))
| SECOND ExpNoUn (Syntax.SECOND (ExpNoUn))
| LBRACK ExpNoUn COMMA ExpNoUn RBRACK (Syntax.PAIR (ExpNoUn1, ExpNoUn2))
| BANG ExpNoUn (Syntax.IF (ExpNoUn, Syntax.EMPTY, Syntax.NUM (1)))
| ID TILDE ExpNoUn (Syntax.DEFAULT (ID, ExpNoUn))
| LPAR Exp RPAR (Exp)
| LEAST ExpNoUn Exp (Syntax.LEAST (ExpNoUn, Exp))
| LEAST MINUS ExpNoUn Exp (Syntax.LEAST (ExpNoUn, Exp))
| LEAST SAMPLE ExpNoUn Exp (Syntax.LEAST (ExpNoUn, Exp))
| LEAST D ExpNoUn Exp (Syntax.LEAST (ExpNoUn, Exp))
| LEAST Z ExpNoUn Exp (Syntax.LEAST (ExpNoUn, Exp))
| LARGEST ExpNoUn Exp (Syntax.LARGEST (ExpNoUn, Exp))
| LARGEST MINUS ExpNoUn Exp (Syntax.LARGEST (ExpNoUn,Exp))
| LARGEST SAMPLE ExpNoUn Exp (Syntax.LARGEST (ExpNoUn, Exp))
| LARGEST Z ExpNoUn Exp (Syntax.LARGEST (ExpNoUn, Exp))
| LARGEST D ExpNoUn Exp (Syntax.LARGEST (ExpNoUn, Exp))
| STRINGS (let fun build [] = Syntax.STRING ("")
| build [s] = Syntax.STRING (s)
| build ("|>" :: ss) = Syntax.VCONCL(Syntax.STRING (""), build ss)
| build ("<|" :: ss) = Syntax.VCONCR(Syntax.STRING (""), build ss)
| build ("<>" :: ss) = Syntax.VCONCC(Syntax.STRING (""), build ss)
| build ("||" :: ss) = Syntax.HCONC(Syntax.STRING (""), build ss)
| build (s :: "|>" :: ss) = Syntax.VCONCL(Syntax.STRING (s), build ss)
| build (s :: "<|" :: ss) = Syntax.VCONCR(Syntax.STRING (s), build ss)
| build (s :: "<>" :: ss) = Syntax.VCONCC(Syntax.STRING (s), build ss)
| build (s :: "||" :: ss) = Syntax.HCONC(Syntax.STRING (s), build ss)
| build (s :: ss) = Syntax.HCONC(Syntax.STRING (s), build ss)
in
build (STRINGS)
end)
ExpList : (Syntax.EMPTY)
| ExpList1 (ExpList1)
ExpList1 : Exp (Exp)
| Exp COMMA ExpList1 (Syntax.CONC (Exp,ExpList1))
ExpList2 : Exp ([Exp])
| Exp COMMA ExpList2 (Exp :: ExpList2)