@@ -39,6 +39,18 @@ let missing_error what startpos endpos =
39
39
let unclosed_error what startpos endpos =
40
40
syntax_error (Printf. sprintf " Unclosed %s" what) startpos endpos
41
41
42
+ let string_to_longident s =
43
+ let open Ppxlib_ast.Ast in
44
+ match String. split_on_char '.' s with
45
+ | [] -> invalid_arg " string_to_longident: empty string"
46
+ | [ x ] -> Lident x
47
+ | x :: xs -> List. fold_left (fun acc s -> Ldot (acc, s)) (Lident x) xs
48
+
49
+ let last_component s =
50
+ match List. rev (String. split_on_char '.' s) with
51
+ | [] -> s
52
+ | hd :: _ -> hd
53
+
42
54
let parse_flags s startpos endpos =
43
55
let rec loop i flags =
44
56
if i > = String. length s then flags
@@ -88,13 +100,13 @@ main_let_expr:
88
100
89
101
pattern:
90
102
| alt_expr { $ 1 }
91
- | alt_expr PIPE func = func_name AS name = IDENT {
103
+ | alt_expr PIPE func = ident AS name = IDENT {
92
104
let name_loc = wrap_loc $ startpos(name) $ endpos(name) name in
93
105
wrap_loc $ startpos $ endpos (Pipe_all (name_loc, func, $ 1 ))
94
106
}
95
107
| alt_expr PIPE { missing_error " function name after '>>>'" $ startpos($ 2 ) $ endpos }
96
- | alt_expr PIPE func_name { missing_error " 'as' and result name after function" $ startpos($ 3 ) $ endpos }
97
- | alt_expr PIPE func_name AS { missing_error " result name after 'as'" $ startpos($ 4 ) $ endpos }
108
+ | alt_expr PIPE ident { missing_error " 'as' and result name after function" $ startpos($ 3 ) $ endpos }
109
+ | alt_expr PIPE ident AS { missing_error " result name after 'as'" $ startpos($ 4 ) $ endpos }
98
110
| { missing_error " pattern expression" $ startpos $ endpos }
99
111
100
112
alt_expr:
@@ -171,10 +183,9 @@ basic_atom:
171
183
| PREDEFINED_CLASS {
172
184
to_pcre_regex $ 1 $ startpos $ endpos
173
185
}
174
- | IDENT {
175
- let ident_loc = wrap_loc $ startpos $ endpos $ 1 in
176
- let pattern_node = to_pcre_regex $ 1 $ startpos $ endpos in
177
- wrap_loc $ startpos $ endpos (Unnamed_subs (ident_loc, pattern_node))
186
+ | IDENT | MOD_IDENT {
187
+ let ident_loc = wrap_loc $ startpos $ endpos (string_to_longident $ 1 ) in
188
+ wrap_loc $ startpos $ endpos (Call ident_loc)
178
189
}
179
190
180
191
| LBRACKET char_set RBRACKET {
@@ -190,55 +201,70 @@ basic_atom:
190
201
| LBRACKET char_set { unclosed_error " character set (missing ']')" $ startpos($ 1 ) $ endpos }
191
202
| LBRACKET error { syntax_error " Invalid character set" $ startpos $ endpos }
192
203
193
- | LPAREN pattern RPAREN {
194
- $ 2
195
- }
196
- | LPAREN RPAREN { missing_error " pattern inside parentheses " $ startpos $ endpos }
197
- | LPAREN pattern EOF ? { unclosed_error " parentheses (missing ')') " $ startpos($ 1 ) $ endpos($ 2 ) }
198
-
199
- | LPAREN IDENT RPAREN {
200
- let ident_loc = wrap_loc $ startpos( $ 2 ) $ endpos( $ 2 ) $ 2 in
201
- let pattern_node = to_pcre_regex $ 2 $ startpos($ 2 ) $ endpos($ 2 ) in
202
- wrap_loc $ startpos $ endpos ( Named_subs (ident_loc, None , None , pattern_node))
203
- }
204
- | LPAREN IDENT AS RPAREN { missing_error " name after 'as' " $ startpos( $ 3 ) $ endpos( $ 4 ) }
205
- | LPAREN IDENT AS name = IDENT RPAREN {
206
- let ident_loc = wrap_loc $ startpos($ 2 ) $ endpos($ 2 ) $ 2 in
204
+ | LPAREN id = IDENT RPAREN
205
+ | LPAREN id = MOD_IDENT RPAREN {
206
+ (* (word) -> captures the result of calling 'word' pattern *)
207
+ let call_loc = wrap_loc $ startpos(id) $ endpos(id) (string_to_longident id) in
208
+ let call_node = wrap_loc $ startpos(id ) $ endpos(id) ( Call call_loc) in
209
+ let name_loc = wrap_loc $ startpos(id) $ endpos(id) (last_component id) in
210
+ wrap_loc $ startpos $ endpos ( Capture_as (name_loc, None , call_node))
211
+ }
212
+ | LPAREN IDENT AS RPAREN | LPAREN MOD_IDENT AS RPAREN { missing_error " name after 'as' " $ startpos($ 3 ) $ endpos($ 4 ) }
213
+ | LPAREN id = IDENT AS name = IDENT RPAREN
214
+ | LPAREN id = MOD_IDENT AS name = IDENT RPAREN {
215
+ (* (word as w) -> captures the result of calling 'word' as 'w' *)
216
+ let call_loc = wrap_loc $ startpos(id) $ endpos(id) (string_to_longident id) in
217
+ let call_node = wrap_loc $ startpos(id ) $ endpos(id) ( Call call_loc) in
207
218
let name_loc = wrap_loc $ startpos(name) $ endpos(name) name in
208
- let pattern_node = to_pcre_regex $ 2 $ startpos($ 2 ) $ endpos($ 2 ) in
209
- wrap_loc $ startpos $ endpos (Named_subs (ident_loc, Some name_loc, None , pattern_node))
219
+ wrap_loc $ startpos $ endpos (Capture_as (name_loc, None , call_node))
210
220
}
211
- | LPAREN IDENT AS IDENT COLON RPAREN {
221
+ | LPAREN IDENT AS IDENT COLON RPAREN
222
+ | LPAREN IDENT AS MOD_IDENT COLON RPAREN {
212
223
missing_error " type converter after ':'" $ startpos($ 5 ) $ endpos($ 6 )
213
224
}
214
- | LPAREN IDENT AS name = IDENT COLON INT_CONVERTER RPAREN {
215
- let ident_loc = wrap_loc $ startpos($ 2 ) $ endpos($ 2 ) $ 2 in
225
+ | LPAREN id = IDENT AS name = IDENT COLON INT_CONVERTER RPAREN
226
+ | LPAREN id = MOD_IDENT AS name = IDENT COLON INT_CONVERTER RPAREN {
227
+ (* (digits as n : int) -> captures 'digits' pattern as 'n' converted to int *)
228
+ let call_loc = wrap_loc $ startpos(id) $ endpos(id) (string_to_longident id) in
229
+ let call_node = wrap_loc $ startpos(id) $ endpos(id) (Call call_loc) in
216
230
let name_loc = wrap_loc $ startpos(name) $ endpos(name) name in
217
- let pattern_node = to_pcre_regex $ 2 $ startpos($ 2 ) $ endpos($ 2 ) in
218
- wrap_loc $ startpos $ endpos (Named_subs (ident_loc, Some name_loc, Some Int , pattern_node))
231
+ wrap_loc $ startpos $ endpos (Capture_as (name_loc, Some Int , call_node))
219
232
}
220
- | LPAREN IDENT AS name = IDENT COLON FLOAT_CONVERTER RPAREN {
221
- let ident_loc = wrap_loc $ startpos($ 2 ) $ endpos($ 2 ) $ 2 in
233
+ | LPAREN id = IDENT AS name = IDENT COLON FLOAT_CONVERTER RPAREN
234
+ | LPAREN id = MOD_IDENT AS name = IDENT COLON FLOAT_CONVERTER RPAREN {
235
+ (* (number as f : float) -> captures 'number' pattern as 'f' converted to float *)
236
+ let call_loc = wrap_loc $ startpos(id) $ endpos(id) (string_to_longident id) in
237
+ let call_node = wrap_loc $ startpos(id) $ endpos(id) (Call call_loc) in
222
238
let name_loc = wrap_loc $ startpos(name) $ endpos(name) name in
223
- let pattern_node = to_pcre_regex $ 2 $ startpos($ 2 ) $ endpos($ 2 ) in
224
- wrap_loc $ startpos $ endpos (Named_subs (ident_loc, Some name_loc, Some Float , pattern_node))
239
+ wrap_loc $ startpos $ endpos (Capture_as (name_loc, Some Float , call_node))
225
240
}
226
- | LPAREN IDENT AS name = IDENT COLON EQUAL func = func_name RPAREN {
227
- let ident_loc = wrap_loc $ startpos($ 2 ) $ endpos($ 2 ) $ 2 in
241
+ | LPAREN id = IDENT AS name = IDENT COLON EQUAL func = ident RPAREN
242
+ | LPAREN id = MOD_IDENT AS name = IDENT COLON EQUAL func = ident RPAREN {
243
+ (* (text as t := process) -> captures 'text' pattern as 't' processed by function *)
244
+ let call_loc = wrap_loc $ startpos(id) $ endpos(id) (string_to_longident id) in
245
+ let call_node = wrap_loc $ startpos(id) $ endpos(id) (Call call_loc) in
228
246
let name_loc = wrap_loc $ startpos(name) $ endpos(name) name in
229
- let pattern_node = to_pcre_regex $ 2 $ startpos($ 2 ) $ endpos($ 2 ) in
230
- wrap_loc $ startpos $ endpos (Named_subs (ident_loc, Some name_loc, Some (Func func), pattern_node))
247
+ wrap_loc $ startpos $ endpos (Capture_as (name_loc, Some (Func func), call_node))
231
248
}
232
- | LPAREN IDENT AS IDENT EOF ? {
249
+ | LPAREN IDENT AS IDENT EOF ?
250
+ | LPAREN MOD_IDENT AS IDENT EOF ? {
233
251
unclosed_error " parentheses (missing ')')" $ startpos($ 1 ) $ endpos($ 4 )
234
252
}
235
- | LPAREN IDENT AS IDENT COLON INT_CONVERTER EOF ? {
253
+ | LPAREN IDENT AS IDENT COLON INT_CONVERTER EOF ?
254
+ | LPAREN MOD_IDENT AS IDENT COLON INT_CONVERTER EOF ? {
236
255
unclosed_error " parentheses (missing ')')" $ startpos($ 1 ) $ endpos($ 6 )
237
256
}
238
- | LPAREN IDENT AS IDENT COLON FLOAT_CONVERTER EOF ? {
257
+ | LPAREN IDENT AS IDENT COLON FLOAT_CONVERTER EOF ?
258
+ | LPAREN MOD_IDENT AS IDENT COLON FLOAT_CONVERTER EOF ? {
239
259
unclosed_error " parentheses (missing ')')" $ startpos($ 1 ) $ endpos($ 6 )
240
260
}
241
261
262
+ | LPAREN pattern RPAREN {
263
+ $ 2
264
+ }
265
+ | LPAREN RPAREN { missing_error " pattern inside parentheses" $ startpos $ endpos }
266
+ | LPAREN pattern EOF ? { unclosed_error " parentheses (missing ')')" $ startpos($ 1 ) $ endpos($ 2 ) }
267
+
242
268
| LPAREN pattern AS RPAREN { missing_error " capture name after 'as'" $ startpos($ 3 ) $ endpos($ 4 ) }
243
269
| LPAREN pattern AS name = IDENT RPAREN {
244
270
let name_loc = wrap_loc $ startpos(name) $ endpos(name) name in
@@ -258,7 +284,7 @@ basic_atom:
258
284
let name_loc = wrap_loc $ startpos(name) $ endpos(name) name in
259
285
wrap_loc $ startpos $ endpos (Capture_as (name_loc, Some Float , $ 2 ))
260
286
}
261
- | LPAREN pattern AS name = IDENT COLON EQUAL func = func_name RPAREN {
287
+ | LPAREN pattern AS name = IDENT COLON EQUAL func = ident RPAREN {
262
288
let name_loc = wrap_loc $ startpos(name) $ endpos(name) name in
263
289
wrap_loc $ startpos $ endpos (Capture_as (name_loc, Some (Func func), $ 2 ))
264
290
}
@@ -272,10 +298,9 @@ basic_atom:
272
298
unclosed_error " parentheses (missing ')')" $ startpos($ 1 ) $ endpos($ 6 )
273
299
}
274
300
275
-
276
301
| LPAREN error { syntax_error " Invalid expression in parentheses" $ startpos($ 2 ) $ endpos }
277
302
278
- func_name :
303
+ ident :
279
304
| IDENT { $ 1 }
280
305
| MOD_IDENT { $ 1 }
281
306
0 commit comments