Skip to content

Commit c222fc4

Browse files
committed
Improve match-all handling and restrict it to the last pattern.
1 parent 8147c58 commit c222fc4

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

ppx_regexp.ml

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,18 +99,29 @@ let transform_cases ~loc e cases =
9999
if case.pc_guard <> None then
100100
error ~loc "Guards are not implemented for match%pcre." else
101101
(match case.pc_lhs with
102-
| {ppat_desc = Ppat_any} ->
103-
(Exp.constant (Const.string ""), 0, [], case.pc_rhs)
104102
| {ppat_desc = Ppat_constant (Pconst_string (re_src,_)); ppat_loc = loc} ->
105103
let re_str, bs, nG = extract_bindings ~loc re_src in
106104
(try ignore (Re_pcre.regexp re_str) with
107105
| Re_perl.Not_supported -> error ~loc "Unsupported regular expression."
108106
| Re_perl.Parse_error -> error ~loc "Invalid regular expression.");
109107
(Exp.constant (Const.string re_str), nG, bs, case.pc_rhs)
108+
| {ppat_desc = Ppat_any} ->
109+
error ~loc "Universal wildcard must be the last pattern."
110110
| {ppat_loc = loc} ->
111111
error ~loc "Regular expression pattern should be a string.")
112112
in
113-
let cases = List.map aux cases in
113+
let cases, default_rhs =
114+
(match List.rev cases with
115+
| {pc_lhs = {ppat_desc = Ppat_any}; pc_rhs} :: cases ->
116+
(cases, pc_rhs)
117+
| cases ->
118+
let pos = loc.loc_start in
119+
let e0 = Exp.constant (Const.string pos.pos_fname) in
120+
let e1 = Exp.constant (Const.int pos.pos_lnum) in
121+
let e2 = Exp.constant (Const.int (pos.pos_cnum - pos.pos_bol)) in
122+
(cases, [%expr raise (Match_failure ([%e e0], [%e e1], [%e e2]))]))
123+
in
124+
let cases = List.rev_map aux cases in
114125
let res = Exp.array (List.map (fun (re, _, _, _) -> re) cases) in
115126
let comp = [%expr
116127
let a = Array.map (fun s -> Re.mark (Re_pcre.re s)) [%e res] in
@@ -146,16 +157,10 @@ let transform_cases ~loc e cases =
146157
else
147158
[%e handle_cases (i + 1) (offG + nG) cases]]
148159
in
149-
let pos = loc.loc_start in
150-
let e0 = Exp.constant (Const.string pos.pos_fname) in
151-
let e1 = Exp.constant (Const.int pos.pos_lnum) in
152-
let e2 = Exp.constant (Const.int (pos.pos_cnum - pos.pos_bol)) in
153160
[%expr
154-
let _g =
155-
try Re.exec (fst [%e e_comp]) [%e e] with
156-
Not_found -> raise (Match_failure ([%e e0], [%e e1], [%e e2]))
157-
in
158-
[%e handle_cases 0 0 cases]]
161+
(match Re.exec_opt (fst [%e e_comp]) [%e e] with
162+
| None -> [%e default_rhs]
163+
| Some _g -> [%e handle_cases 0 0 cases])]
159164

160165
let rewrite_expr mapper e_ext =
161166
(match e_ext.pexp_desc with

0 commit comments

Comments
 (0)