lexdep.mll 1.09 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
(* This code analyzes the output of [ocamldep] and returns the list
   of [.cmi] files that the [.cmo] file depends on. *)

{

  open Lexing

  exception Error of string

  let fail lexbuf =
    raise (Error
      (Printf.sprintf
	 "failed to make sense of ocamldep's output (character %d).\n"
	 lexbuf.lex_curr_p.pos_cnum)
    )

}

let newline = ('\n' | '\r' | "\r\n")

let whitespace = ( ' ' | '\t' | ('\\' newline) )

let entrychar = [^ '\n' '\r' '\t' ' ' '\\' ':' ]

let entry = ((entrychar+ as basename) ".cm" ('i' | 'o' | 'x') as filename)

(* [main] recognizes a sequence of lines, where a line consists of an
   entry, followed by a colon, followed by a list of entries. *)

rule main = parse
| eof
    { [] }
| entry whitespace* ":"
    { let bfs = collect [] lexbuf in
      ((basename, filename), bfs) :: main lexbuf }
| _
    { fail lexbuf }

(* [collect] recognizes a list of entries, separated with spaces and
   ending in a newline. *)

and collect bfs = parse
| whitespace+ entry
    { collect ((basename, filename) :: bfs) lexbuf }
| whitespace* newline
    { bfs }
| _
| eof
    { fail lexbuf }