Skip to content

Commit da93fac

Browse files
committed
added renaming and unnamed substitution
1 parent 6ab4782 commit da93fac

File tree

3 files changed

+36
-9
lines changed

3 files changed

+36
-9
lines changed

common/regexp.ml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ and 'a node =
2929
| Nongreedy of 'a t
3030
| Capture of 'a t
3131
| Capture_as of string Location.loc * 'a t
32-
| Named_as of string Location.loc * 'a t
32+
| Named_subs of string Location.loc * string Location.loc option * 'a t
33+
| Unnamed_subs of string Location.loc * 'a t
3334
| Call of Longident.t Location.loc
3435
(* TODO: | Case_sense of t | Case_blind of t *)
3536

@@ -243,11 +244,32 @@ let parse_exn ?(pos = Lexing.dummy_pos) s =
243244
let k, e = with_loc scan_alt (j + 1) in
244245
k, Capture_as (idr, e))
245246
| 'N' ->
247+
let j, idr = scan_ident (i + 3) in
248+
begin
249+
match get j with
250+
| '>' ->
251+
let k, e = with_loc scan_alt (j + 1) in
252+
k, Named_subs (idr, None, e)
253+
| ' ' ->
254+
let j, jdr = scan_ident (j + 1) in
255+
if jdr.txt = "as" && get j = ' ' then begin
256+
let j, kdr = scan_ident (j + 1) in
257+
if get j <> '>' then fail (j, j + 1) "Unbalanced '<'."
258+
else begin
259+
let k, e = with_loc scan_alt (j + 1) in
260+
k, Named_subs (idr, Some kdr, e)
261+
end
262+
end
263+
else fail (j - 2, j) "Substring name missing."
264+
| _ -> fail (i, i + 1) "Unbalanced '<'."
265+
end
266+
| 'U' ->
246267
let j, idr = scan_ident (i + 3) in
247268
if get j <> '>' then fail (i, i + 1) "Unbalanced '<'."
248-
else (
269+
else begin
249270
let k, e = with_loc scan_alt (j + 1) in
250-
k, Named_as (idr, e))
271+
k, Unnamed_subs (idr, e)
272+
end
251273
| ':' -> scan_alt (i + 2)
252274
| '#' ->
253275
(try String.index_from s (i + 2) ')', Seq [] with Not_found -> fail (i - 1, i + 1) "Unterminated comment.")

common/regexp.mli

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ and 'a node =
2626
| Nongreedy of 'a t
2727
| Capture of 'a t
2828
| Capture_as of string Location.loc * 'a t
29-
| Named_as of string Location.loc * 'a t
29+
| Named_subs of string Location.loc * string Location.loc option * 'a t
30+
| Unnamed_subs of string Location.loc * 'a t
3031
| Call of Longident.t Location.loc
3132
(* TODO: | Case_sense of t | Case_blind of t *)
3233

ppx_regexp/ppx_regexp.ml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ module Ctx = struct
3939
let find name ctx = Hashtbl.find_opt ctx name
4040

4141
let update_used name ctx =
42-
let old_value, _ = Hashtbl.find ctx name in
43-
Hashtbl.replace ctx name (old_value, true)
42+
match Hashtbl.find_opt ctx name with
43+
| Some (old_value, _) -> Hashtbl.replace ctx name (old_value, true)
44+
| None -> ()
4445

4546
let is_used name ctx = Hashtbl.find_opt ctx name |> Option.value ~default:("", false) |> snd
4647
end
@@ -60,7 +61,9 @@ module Regexp = struct
6061
| Nongreedy e -> recurse must_match e
6162
| Capture _ -> error ~loc "Unnamed capture is not allowed for %%pcre."
6263
| Capture_as (idr, e) -> fun (nG, bs) -> recurse must_match e (nG + 1, (idr, Some nG, must_match) :: bs)
63-
| Named_as (idr, e) -> fun (nG, bs) -> recurse must_match e (nG + 1, (idr, Some nG, must_match) :: bs)
64+
| Named_subs (idr, None, e) -> fun (nG, bs) -> recurse must_match e (nG + 1, (idr, Some nG, must_match) :: bs)
65+
| Named_subs (_, Some idr, e) -> fun (nG, bs) -> recurse must_match e (nG + 1, (idr, Some nG, must_match) :: bs)
66+
| Unnamed_subs (_, e) -> fun (nG, bs) -> recurse must_match e (nG + 1, bs)
6467
| Call _ -> error ~loc "(&...) is not implemented for %%pcre."
6568
in
6669
function
@@ -86,7 +89,7 @@ module Regexp = struct
8689
| Nongreedy e -> recurse p_suffix e ^ "?"
8790
| Capture _ -> error ~loc "Unnamed capture is not allowed for %%pcre."
8891
| Capture_as (_, e) -> "(" ^ recurse p_alt e ^ ")"
89-
| Named_as (idr, _) ->
92+
| Named_subs (idr, _, _) | Unnamed_subs (idr, _) ->
9093
let var_name = idr.txt in
9194
let content =
9295
match Ctx.find var_name ctx with
@@ -121,6 +124,7 @@ let rec must_match p i =
121124
let extract_bindings ~ctx ~pos s =
122125
let r = Regexp.parse_exn ~pos s in
123126
let nG, bs = Regexp.bindings r in
127+
List.iter (fun (idr, i, b) -> Format.printf "%s, %i, %b@." idr.txt (match i with Some i -> i | None -> -1) b) bs;
124128
let re_str = Regexp.to_string ~ctx r in
125129
let loc = Location.none in
126130
estring ~loc re_str, bs, nG
@@ -275,9 +279,9 @@ let suppress_unused_inlined ctx =
275279
let impl str =
276280
let ctx = Ctx.empty () in
277281
let str, rev_bindings = (transformation ctx)#structure str [] in
278-
let str = (suppress_unused_inlined ctx)#structure str in
279282
if rev_bindings = [] then str
280283
else (
284+
let str = (suppress_unused_inlined ctx)#structure str in
281285
let re_str =
282286
let loc = Location.none in
283287
[%str

0 commit comments

Comments
 (0)