OCaml parser combinator that compiles to direct recursive descent
5

Configure Feed

Select the types of activity you want to include in your feed.

specialised fast paths for common patterns (many/some with token, satisfy, any)

+84 -19
+84 -19
src/codegen.ml
··· 179 179 | Error _ -> Ok ((), saved)] 180 180 181 181 | Many { p; loc } -> 182 - let p_code = compile ~loc env p in 183 - [%expr 184 - let rec loop acc input = 185 - match [%e p_code] with 186 - | Ok (x, inp) -> loop (x :: acc) inp 187 - | Error _ -> Ok (List.rev acc, input) 188 - in 189 - loop [] input] 182 + (match p with 183 + | Token { tok; _ } -> 184 + [%expr 185 + let rec loop acc input = 186 + match I.peek input with 187 + | Some t when t = [%e tok] -> loop (t :: acc) (I.advance input) 188 + | _ -> Ok (List.rev acc, input) 189 + in 190 + loop [] input] 191 + | Satisfy { pred; _ } -> 192 + [%expr 193 + let rec loop acc input = 194 + match I.peek input with 195 + | Some t when [%e pred] t -> loop (t :: acc) (I.advance input) 196 + | _ -> Ok (List.rev acc, input) 197 + in 198 + loop [] input] 199 + | Any _ -> 200 + [%expr 201 + let rec loop acc input = 202 + match I.peek input with 203 + | Some t -> loop (t :: acc) (I.advance input) 204 + | None -> Ok (List.rev acc, input) 205 + in 206 + loop [] input] 207 + | _ -> 208 + let p_code = compile ~loc env p in 209 + [%expr 210 + let rec loop acc input = 211 + match [%e p_code] with 212 + | Ok (x, inp) -> loop (x :: acc) inp 213 + | Error _ -> Ok (List.rev acc, input) 214 + in 215 + loop [] input]) 190 216 191 217 | Some_ { p; loc } -> 192 - let p_code = compile ~loc env p in 193 - [%expr 194 - match [%e p_code] with 195 - | Ok (x, inp) -> 196 - let rec loop acc input = 197 - match [%e p_code] with 198 - | Ok (y, inp2) -> loop (y :: acc) inp2 199 - | Error _ -> Ok (List.rev acc, input) 200 - in 201 - loop [x] inp 202 - | Error e -> Error e] 218 + (match p with 219 + | Token { tok; _ } -> 220 + [%expr 221 + match I.peek input with 222 + | Some t when t = [%e tok] -> 223 + let rec loop acc input = 224 + match I.peek input with 225 + | Some t when t = [%e tok] -> loop (t :: acc) (I.advance input) 226 + | _ -> Ok (List.rev acc, input) 227 + in 228 + loop [t] (I.advance input) 229 + | _ -> [%e error_expr ~loc [%expr [I.show_token [%e tok]]]]] 230 + | Satisfy { pred; label; _ } -> 231 + let expected = match label with 232 + | Some l -> elist ~loc [estring ~loc l] 233 + | None -> [%expr ["<satisfy>"]] 234 + in 235 + [%expr 236 + match I.peek input with 237 + | Some t when [%e pred] t -> 238 + let rec loop acc input = 239 + match I.peek input with 240 + | Some t when [%e pred] t -> loop (t :: acc) (I.advance input) 241 + | _ -> Ok (List.rev acc, input) 242 + in 243 + loop [t] (I.advance input) 244 + | _ -> [%e error_expr ~loc expected]] 245 + | Any _ -> 246 + [%expr 247 + match I.peek input with 248 + | Some t -> 249 + let rec loop acc input = 250 + match I.peek input with 251 + | Some t -> loop (t :: acc) (I.advance input) 252 + | None -> Ok (List.rev acc, input) 253 + in 254 + loop [t] (I.advance input) 255 + | None -> [%e error_expr ~loc (elist ~loc [estring ~loc "<any>"])]] 256 + | _ -> 257 + let p_code = compile ~loc env p in 258 + [%expr 259 + match [%e p_code] with 260 + | Ok (x, inp) -> 261 + let rec loop acc input = 262 + match [%e p_code] with 263 + | Ok (y, inp2) -> loop (y :: acc) inp2 264 + | Error _ -> Ok (List.rev acc, input) 265 + in 266 + loop [x] inp 267 + | Error e -> Error e]) 203 268 204 269 | Optional { p; loc } -> 205 270 let p_code = compile ~loc env p in