Skip to content

Commit de23c41

Browse files
committed
Fix group indices.
1 parent 2f7c29c commit de23c41

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

ppx_regexp.ml

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ let extract_bindings ~loc p =
4141
let
4242
rec parse_normal nG stack bs i =
4343
if i = l then
44-
if stack = [] then bs else
44+
if stack = [] then (bs, nG) else
4545
error ~loc "Unmatched start of group."
4646
else begin
4747
Buffer.add_char buf p.[i];
@@ -52,7 +52,7 @@ let extract_bindings ~loc p =
5252
| _ -> parse_normal nG stack bs (i + 1))
5353
end
5454
and parse_escape nG stack bs i =
55-
if i = l then bs else begin
55+
if i = l then (bs, nG) else begin
5656
Buffer.add_char buf p.[i];
5757
parse_normal nG stack bs (i + 1)
5858
end
@@ -81,24 +81,24 @@ let extract_bindings ~loc p =
8181
in
8282
parse_normal nG stack' (List.rev_append bs bs') i
8383
in
84-
let bs = parse_normal 1 [] [] 0 in
85-
(Buffer.contents buf, bs)
84+
let bs, nG = parse_normal 0 [] [] 0 in
85+
(Buffer.contents buf, bs, nG)
8686

8787
let transform_cases ~loc e cases =
8888
let aux case =
8989
if case.pc_guard <> None then
9090
error ~loc "Guards are not implemented for match%pcre." else
9191
(match case.pc_lhs with
9292
| {ppat_desc = Ppat_any} ->
93-
(Exp.constant (Const.string ""), [], case.pc_rhs)
93+
(Exp.constant (Const.string ""), 0, [], case.pc_rhs)
9494
| {ppat_desc = Ppat_constant (Pconst_string (re_src,_)); ppat_loc = loc} ->
95-
let re_str, bs = extract_bindings ~loc re_src in
96-
(Exp.constant (Const.string re_str), bs, case.pc_rhs)
95+
let re_str, bs, nG = extract_bindings ~loc re_src in
96+
(Exp.constant (Const.string re_str), nG, bs, case.pc_rhs)
9797
| {ppat_loc = loc} ->
9898
error ~loc "Regular expression pattern should be a string.")
9999
in
100100
let cases = List.map aux cases in
101-
let res = Exp.array (List.map (fun (re, _, _) -> re) cases) in
101+
let res = Exp.array (List.map (fun (re, _, _, _) -> re) cases) in
102102
let comp = [%expr
103103
let a = Array.map (fun s -> Re.mark (Re_pcre.re s)) [%e res] in
104104
let marks = Array.map fst a in
@@ -109,27 +109,29 @@ let transform_cases ~loc e cases =
109109
add_binding (Vb.mk (Pat.var {txt = var; loc}) comp);
110110
let e_comp = Exp.ident {txt = Lident var; loc} in
111111

112-
let rec wrap_groups rhs = function
112+
let rec wrap_groups rhs offG = function
113113
| [] -> rhs
114114
| (varG, iG, mustG) :: bs ->
115-
let eG = [%expr Re.Group.get _g [%e Exp.constant (Const.int iG)]] in
115+
let eG =
116+
[%expr Re.Group.get _g [%e Exp.constant (Const.int (offG + iG + 1))]]
117+
in
116118
let eG =
117119
if mustG then eG else
118120
[%expr try Some [%e eG] with Not_found -> None]
119121
in
120122
[%expr
121123
let [%p Pat.var {txt = varG; loc}] = [%e eG] in
122-
[%e wrap_groups rhs bs]]
124+
[%e wrap_groups rhs offG bs]]
123125
in
124-
let rec handle_cases i = function
126+
let rec handle_cases i offG = function
125127
| [] -> [%expr assert false]
126-
| (_, bs, rhs) :: cases ->
128+
| (_, nG, bs, rhs) :: cases ->
127129
let e_i = Exp.constant (Const.int i) in
128130
[%expr
129131
if Re.Mark.test _g (snd [%e e_comp]).([%e e_i]) then
130-
[%e wrap_groups rhs bs]
132+
[%e wrap_groups rhs offG bs]
131133
else
132-
[%e handle_cases (i + 1) cases]]
134+
[%e handle_cases (i + 1) (offG + nG) cases]]
133135
in
134136
let pos = loc.loc_start in
135137
let e0 = Exp.constant (Const.string pos.pos_fname) in
@@ -140,7 +142,7 @@ let transform_cases ~loc e cases =
140142
try Re.exec (fst [%e e_comp]) [%e e] with
141143
Not_found -> raise (Match_failure ([%e e0], [%e e1], [%e e2]))
142144
in
143-
[%e handle_cases 0 cases]]
145+
[%e handle_cases 0 0 cases]]
144146

145147
let rewrite_expr mapper e_ext =
146148
(match e_ext.pexp_desc with

test_ppx_regexp.ml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616

1717
let f =
1818
(function%pcre
19-
| {|^(?<k>.*): *(?<v>.+)?$|} -> Some (k, v)
20-
| _ -> None)
19+
| {|^(?<k>.*): *(?<v>.+)?$|} -> `Attr (k, v)
20+
| {|^# (?<comment>.+)$|} -> `Comment comment
21+
| _ -> `Unknown)
2122

22-
let () = assert (f "x: 1" = Some ("x", Some "1"))
23+
let () =
24+
assert (f "x: 1" = `Attr ("x", Some "1"));
25+
assert (f "# Kommentar" = `Comment "Kommentar")
2326

2427
module F (M : Map.OrderedType) = struct
2528
let f x =

0 commit comments

Comments
 (0)