ocamlgrep is a command-line tool written at LexiFi to perform structural search of OCaml code.
The code is released as-is in case it is of interest to the community. The present code is extracted from a version used internally at LexiFi and we do not pretend that it is ready for public consumption, but we are making the code available to publicize the approach.
dune buildThe tool requires OCaml 5.2 (since it depends on compiler-libs, compilation aginst other versions of OCaml will require some adjustments).
This produces an executable _build/install/bin/ocamlgrep.exe which can be run from the command line.
ocamlgrep PATTERNThe tool assumes that it is executed within a Dune workspace, as it has a number of heuristics that will not work otherwise. The tool will search the files under the current directory subtree.
You will need to run dune build @check in your project to ensure all .cmt files are up-to-date before using ocamlgrep.
PATTERN: The pattern to search for. This should be a valid OCaml expression.
__ matches any expression or any record field.__1, __2, ... matches any expression or record field and enforce strict equality of all the matching occurrences for the same number.For function applications, it is allowed to omit in the pattern any argument of the actual function call; special forms are recognized to enforce that a given optional argument present or missing:
foo ?arg:PRESENT
foo ?arg:MISSING(... : typexpr) matches any expression matching ... and whose type is equal to typexpr.try..with/match..with/functions expressions, the order of clauses doesn't matter. A single clause of the searched expression can match several clauses of the code. Same set-semantics for record expressions.e1.lid1 matches e2.lid2 <- e3 if e1 matches e2 and the label lid1 matches lid2.__.id matches any pattern of the form {...; P.id; ...} for any prefix P. This rule was added so that grepping for __.foo will return every "get" and "set" of the record field foo, including reads in patterns.ocamlgrep 'List.filter'
ocamlgrep '(__ (__ : floatarray): float array)'
ocamlgrep 'List.rev __ @ __'
ocamlgrep 'match __ with None -> __ | Some __1 -> Some __1'
ocamlgrep 'List.fold_left __ __ (List.map __ __)'
ocamlgrep 'Stdlib.max (__:float) __'