let matchit p s =
let sl = String.length s in
let rec loop xs pos acc delta =
match xs with
| [] -> if pos = sl then acc else raise No_solution
| A prefix :: xs -> loop xs (match_prefix s pos prefix) acc 0
| V(var, patt) :: A s2 :: xs' ->
begin match String.contains_string s (pos + delta) s2 with
| Some(pos') ->
let matched = String.sub s pos (pos' - pos) in
if Glob.eval patt matched
then
try loop xs' (pos' + String.length s2) ((var, matched) :: acc) 0
with No_solution -> loop xs pos acc (pos' - pos + 1)
else loop xs pos acc (pos' - pos + 1)
| None -> raise No_solution
end
| [V(var, patt)] ->
let matched = String.sub s pos (sl - pos) in
if Glob.eval patt matched then (var, matched) :: acc else raise No_solution
| V _ :: _ -> assert false
in
try Some (loop p 0 [] 0)
with No_solution -> None