MParser tutorial
Introduction
string parsing have two step
- build a parser
- parse string use that parser
parse a float number
there is alreay a token (parser) we can use,
utop # #require "mparser";;
utop # MParser.parse_string MParser.Tokens.float "12.5" ();;
- : float MParser.result = MParser.Success 12.5
parse a list of float
let list_of_float = let open MParser in
sep_by Tokens.float (char ';');;
utop # MParser.parse_string list_of_float "1.24;1.45;1.23" ();;
- : float MParser.result = MParser.Success 1.24
parse float in brackets
let float_between_brackets = let open MParser in
between ( char '[') ( char ']') Tokens.float;;
utop # MParser.parse_string float_between_brackets "[1.24]" ();;
- : float MParser.result = MParser.Success 1.24
let float_between_brackets = let open MParser in
Tokens.squares Tokens.float;;
utop # MParser.parse_string float_between_brackets "[1.24]" ();;
- : float MParser.result = MParser.Success 1.24
parse a list of float in bracket
parsing string data
utop # MParser.parse_string MParser.(many (char 'a' <|> char 'b')) "abba" ();;
- : char list MParser.result = MParser.Success [a; b; b; a]
parse a list of float
Final version
open Core.Std;;
(* define ocaml type *)
type product =
| Mouse
| Keyboard
| Monitor
| Speakers ;;
let product_of_string = function
| "mouse" -> Mouse
| "keyboard" -> Keyboard
| "monitor" -> Monitor
| "speakers" -> Speakers
| _ -> failwith "wrong input";;
type log_entry = { entry_time : Time.t;
entry_ip : UnixLabels.inet_addr;
entry_product: product
};;
let log_entry_time_to_string entry = Time.to_string entry.entry_time;;
(* parse rule *)
let date_rule = let open MParser in
many_chars_until any_char (char ' ');;
let time_rule = let open MParser in
many_chars_until any_char (char ' ');;
let ip_rule = let open MParser in
many_chars_until any_char (char ' ');;
let product_rule = let open MParser in
(MParser.string "mouse") <|>
(MParser.string "keyboard") <|>
(MParser.string "monitor") <|>
(MParser.string "speakers");;
let log_rule = let open MParser in
pipe4 date_rule time_rule ip_rule product_rule
(fun date time ip prod -> { entry_time = Time.of_string (date ^ " " ^ time) ;
entry_ip = UnixLabels.inet_addr_of_string ip;
entry_product = product_of_string prod
}
);;
let logs_rule = let open MParser in
end_by log_rule newline;;
(* extract the time of each one *)
let extract_parser_result presult =
match presult with
| MParser.Success(result) -> String.concat ~sep:"\n" @@
List.map result ~f:log_entry_time_to_string
| MParser.Failed(error_msg, _) -> error_msg;;
let () =
let txt = String.drop_suffix (In_channel.read_all "log.txt") 1 in
MParser.parse_string logs_rule txt () |> extract_parser_result |> print_string;;