Skip to content

Instantly share code, notes, and snippets.

@lindig
Created December 17, 2019 11:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lindig/edaf9f646e00ed7a8f56eb3967827268 to your computer and use it in GitHub Desktop.
Save lindig/edaf9f646e00ed7a8f56eb3967827268 to your computer and use it in GitHub Desktop.
(*
* ocamllex bible.mll && ocamlopt -o bible bible.ml
* ./bible < bible.txt
*)
{
module L = Lexing
let get = L.lexeme
let sprintf = Printf.sprintf
let position lexbuf =
let p = lexbuf.L.lex_curr_p in
sprintf "%s:%d:%d"
p.L.pos_fname p.L.pos_lnum (p.L.pos_cnum - p.L.pos_bol)
let set_filename (fname:string) (lexbuf:L.lexbuf) =
( lexbuf.L.lex_curr_p <-
{ lexbuf.L.lex_curr_p with L.pos_fname = fname }
; lexbuf
)
exception Error of string
let error lexbuf fmt =
Printf.kprintf (fun msg ->
raise (Error ((position lexbuf)^" "^msg))) fmt
}
let ws = [' ' '\t']
let nl = ['\n']
let digit = ['0'-'9']
let id = digit+ ':' digit+ ws
rule token = parse
| id { let buf = Buffer.create 500 in
let () = Buffer.add_string buf (get lexbuf) in
Some(phrase buf lexbuf)
}
| _ { token lexbuf }
| eof { None }
and phrase buf = parse
| nl nl { Buffer.contents buf }
| nl { Buffer.add_string buf (get lexbuf); phrase buf lexbuf }
| [^'\n']+ { Buffer.add_string buf (get lexbuf); phrase buf lexbuf }
| eof { Buffer.contents buf }
{
let main () =
let lexbuf = set_filename "stdin" @@ L.from_channel stdin in
let rec loop acc = function
| None -> acc |> List.rev
| Some x -> loop (x :: acc) (token lexbuf)
in
loop [] (token lexbuf)
|> String.concat "\n%\n"
|> print_endline
let () = main () (* call main function on startup *)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment