Search code examples
parsingocaml

Parsing file into Hashtable in OCaml


I'm trying to learn functional programming and having difficulty expressing a file parsing task functionally. Let's say I have a text file with the following format:

val_0:       <--- "header"
key_0_0      <--- these keys should be set to the "header" or val0
key_0_1
key_0_2
...
...
val_n:     
...
key_n_m

How can I end up with a hash table with all keys set to their associated value?

EDIT: My solution. Can anyone improve it?

open Core.Std

let contains s1 s2 =
        let re = Str.regexp_string s2 in
        try ignore (Str.search_forward re s1 0); true
        with Not_found -> false


let read_db f = 
        let tbl = Caml.Hashtbl.create 123456 in
        let lines = In_channel.read_lines f in
        let src = ref "" in
        List.iter ~f:(fun g -> if contains g ":" then src := else Caml.Hashtbl.add tbl g !src) lines;
        tbl

Solution

  • Here's my solution, just for comparison.

    let line_opt ic =
        try Some (input_line ic) with End_of_file -> None
    
    let fold_lines_in f init fn =
        let ic = open_in fn in
        let rec go accum =
            match line_opt ic with
            | None -> accum
            | Some line -> go (f accum line)
        in
        let res = go init in
        close_in ic;
        res
    
    let hashtable_of_file fn =
        let ht = Hashtbl.create 16 in
        let itab label line =
            let len = String.length line in
            if line.[len - 1] = ':' then
                String.sub line 0 (len - 1)
            else
                let () = Hashtbl.add ht line label in
                label
        in
        let _ = fold_lines_in itab "" fn in
        ht
    

    Update

    (Fixed non-tail-recursive fold implementation, sorry.)