Skip to content

Commit c40f200

Browse files
committed
case insensitivity, unnamed substitution bug fix
1 parent d091998 commit c40f200

File tree

2 files changed

+47
-29
lines changed

2 files changed

+47
-29
lines changed

ppx_regexp.opam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ license: "LGPL-3.0-or-later WITH LGPL-3.0-linking-exception"
88
homepage: "https://github.com/paurkedal/ppx_regexp"
99
bug-reports: "https://github.com/paurkedal/ppx_regexp/issues"
1010
depends: [
11-
"ocaml" {>= "5.0.0"}
11+
"ocaml" {>= "4.02.3"}
1212
"dune" {>= "1.11"}
1313
"ppxlib" {>= "0.9.0"}
1414
"re" {>= "1.7.2"}

ppx_regexp/ppx_regexp.ml

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ module Regexp = struct
6161
| Nongreedy e -> recurse must_match e
6262
| Capture _ -> error ~loc "Unnamed capture is not allowed for %%pcre."
6363
| Capture_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)
64+
| Named_subs (idr, None, e) | Named_subs (_, Some idr, e) ->
65+
fun (nG, bs) -> recurse must_match e (nG + 1, (idr, Some nG, must_match) :: bs)
66+
| Unnamed_subs (_, e) -> recurse must_match e
6767
| Call _ -> error ~loc "(&...) is not implemented for %%pcre."
6868
in
6969
function
@@ -75,6 +75,17 @@ module Regexp = struct
7575
let delimit_if b s = if b then "(?:" ^ s ^ ")" else s in
7676
let rec recurse p (e' : _ Location.loc) =
7777
let loc = e'.Location.loc in
78+
let parse_inside idr =
79+
let var_name = idr.txt in
80+
let content =
81+
match Ctx.find var_name ctx with
82+
| Some (value, _) -> parse_exn value
83+
| None ->
84+
error ~loc "Variable '%s' not found. %%pcre only supports global let bindings for substitution." var_name
85+
in
86+
Ctx.update_used var_name ctx;
87+
content
88+
in
7889
match e'.Location.txt with
7990
| Code s ->
8091
(* Delimiters not needed as Regexp.parse_exn only returns single
@@ -89,16 +100,12 @@ module Regexp = struct
89100
| Nongreedy e -> recurse p_suffix e ^ "?"
90101
| Capture _ -> error ~loc "Unnamed capture is not allowed for %%pcre."
91102
| Capture_as (_, e) -> "(" ^ recurse p_alt e ^ ")"
92-
| Named_subs (idr, _, _) | Unnamed_subs (idr, _) ->
93-
let var_name = idr.txt in
94-
let content =
95-
match Ctx.find var_name ctx with
96-
| Some (value, _) -> parse_exn value
97-
| None ->
98-
error ~loc "Variable '%s' not found. %%pcre only supports global let bindings for substitution." var_name
99-
in
100-
Ctx.update_used var_name ctx;
103+
| Named_subs (idr, _, _) ->
104+
let content = parse_inside idr in
101105
"(" ^ recurse p_alt content ^ ")"
106+
| Unnamed_subs (idr, _) ->
107+
let content = parse_inside idr in
108+
recurse p_alt content
102109
| Call _ -> error ~loc "(&...) is not implemented for %%pcre."
103110
in
104111
function { Location.txt = Capture_as (_, e); _ } -> recurse 0 e | e -> recurse 0 e
@@ -124,7 +131,6 @@ let rec must_match p i =
124131
let extract_bindings ~ctx ~pos s =
125132
let r = Regexp.parse_exn ~pos s in
126133
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;
128134
let re_str = Regexp.to_string ~ctx r in
129135
let loc = Location.none in
130136
estring ~loc re_str, bs, nG
@@ -142,7 +148,7 @@ let rec wrap_group_bindings ~loc rhs offG = function
142148
let [%p ppat_var ~loc varG] = [%e eG] in
143149
[%e wrap_group_bindings ~loc rhs offG bs]]
144150

145-
let transform_cases ~loc ~ctx cases =
151+
let transform_cases ~opts ~loc ~ctx cases =
146152
let aux case =
147153
if case.pc_guard <> None then error ~loc "Guards are not implemented for match%%pcre."
148154
else
@@ -177,9 +183,17 @@ let transform_cases ~loc ~ctx cases =
177183
in
178184
let cases = List.rev_map aux cases in
179185
let res = pexp_array ~loc (List.map (fun (re, _, _, _) -> re) cases) in
186+
let opts_expr =
187+
let rec opts_to_expr = function
188+
| [] -> [%expr []]
189+
| `Caseless :: rest -> [%expr `Caseless :: [%e opts_to_expr rest]]
190+
| _ -> assert false
191+
in
192+
opts_to_expr opts
193+
in
180194
let comp =
181195
[%expr
182-
let a = Array.map (fun s -> Re.mark (Re.Perl.re s)) [%e res] in
196+
let a = Array.map (fun s -> Re.mark (Re.Perl.re ~opts:[%e opts_expr] s)) [%e res] in
183197
let marks = Array.map fst a in
184198
let re = Re.compile (Re.alt (Array.to_list (Array.map snd a))) in
185199
re, marks]
@@ -226,22 +240,26 @@ let transformation ctx =
226240

227241
method! expression e_ext acc =
228242
let e_ext, acc = super#expression e_ext acc in
243+
let make_transformations ~opts ~loc = function
244+
| Pexp_match (e, cases) ->
245+
let cases, binding = transform_cases ~opts ~loc ~ctx cases in
246+
( [%expr
247+
let _ppx_regexp_v = [%e e] in
248+
[%e cases]],
249+
binding :: acc )
250+
| Pexp_function cases ->
251+
(* | Pexp_function (_, _, Pfunction_cases (cases, _, _)) -> *)
252+
let cases, binding = transform_cases ~opts ~loc ~ctx cases in
253+
[%expr fun _ppx_regexp_v -> [%e cases]], binding :: acc
254+
| _ -> error ~loc "[%%pcre] only applies to match and function."
255+
in
229256
match e_ext.pexp_desc with
230257
| Pexp_extension ({ txt = "pcre"; _ }, PStr [ { pstr_desc = Pstr_eval (e, _); _ } ]) ->
231258
let loc = e.pexp_loc in
232-
begin
233-
match e.pexp_desc with
234-
| Pexp_match (e, cases) ->
235-
let cases, binding = transform_cases ~loc ~ctx cases in
236-
( [%expr
237-
let _ppx_regexp_v = [%e e] in
238-
[%e cases]],
239-
binding :: acc )
240-
| Pexp_function cases ->
241-
let cases, binding = transform_cases ~ctx ~loc cases in
242-
[%expr fun _ppx_regexp_v -> [%e cases]], binding :: acc
243-
| _ -> error ~loc "[%%pcre] only applies to match and function."
244-
end
259+
make_transformations ~opts:[] ~loc e.pexp_desc
260+
| Pexp_extension ({ txt = "pcre_i"; _ }, PStr [ { pstr_desc = Pstr_eval (e, _); _ } ]) ->
261+
let loc = e.pexp_loc in
262+
make_transformations ~opts:[ `Caseless ] ~loc e.pexp_desc
245263
| _ -> e_ext, acc
246264
end
247265

0 commit comments

Comments
 (0)