lec 10
This commit is contained in:
3 files changed
+87
No files matched your search
@@ -0,0 +1,41 @@
|
|||||||
|
(*
|
||||||
|
org(123,BCIT)
|
||||||
|
org(345,Hell Holdings\, Ltd)
|
||||||
|
person(666,name(monty,burns))
|
||||||
|
org(456,Ocaml \(LLC\))
|
||||||
|
*)
|
||||||
|
open Angstrom
|
||||||
|
|
||||||
|
type name = Name of string * string
|
||||||
|
type client = Person of int * name | Org of int * string
|
||||||
|
|
||||||
|
let name first last = Name (first, last)
|
||||||
|
let person id name = Person (id, name)
|
||||||
|
let org id name = Org (id, name)
|
||||||
|
|
||||||
|
let a_char =
|
||||||
|
(string "\\(" *> return '(') <|>
|
||||||
|
(string "\\)" *> return ')') <|>
|
||||||
|
(string "\\," *> return ',') <|>
|
||||||
|
(string "\\n" *> return '\n') <|>
|
||||||
|
satisfy (fun c -> c <> '(' && c <> ')' && c <> ',' && c <> '\n')
|
||||||
|
|
||||||
|
let a_string =
|
||||||
|
many1 a_char >>| fun l -> l |> List.to_seq |> String.of_seq
|
||||||
|
|
||||||
|
|
||||||
|
let uint = take_while1 (function | '0'..'9' -> true | _ -> false) >>| int_of_string
|
||||||
|
|
||||||
|
let a_name = name <$> string "name(" *> a_string <* char ',' <*> a_string <* char ')'
|
||||||
|
|
||||||
|
let a_person = person <$> string "person(" *> uint <* char ',' <*> a_name <* char ')'
|
||||||
|
|
||||||
|
let an_org = org <$> string "org(" *> uint <* char ',' <*> a_string <* char ')'
|
||||||
|
|
||||||
|
let a_client = a_person <|> an_org
|
||||||
|
|
||||||
|
let parse file =
|
||||||
|
let ic = open_in file in
|
||||||
|
let content = really_input_string ic (in_channel_length ic) in
|
||||||
|
parse_string ~consume:All (many (a_client <* end_of_line)) content
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
org(123,BCIT)
|
||||||
|
org(345,Hell Holdings\, Ltd)
|
||||||
|
person(666,name(monty,burns))
|
||||||
|
org(456,Ocaml \(LLC\))
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
open Angstrom
|
||||||
|
|
||||||
|
let is_digit = function | '0'..'9' -> true | _ -> false
|
||||||
|
|
||||||
|
let is_space = function | ' ' | '\t' -> true | _ -> false
|
||||||
|
|
||||||
|
let ws = take_while is_space
|
||||||
|
|
||||||
|
let ws1 = take_while1 is_space
|
||||||
|
|
||||||
|
let uint_str = take_while1 is_digit
|
||||||
|
|
||||||
|
let uint_num = uint_str >>| int_of_string
|
||||||
|
|
||||||
|
let sign =
|
||||||
|
peek_char >>= function
|
||||||
|
| Some '+' -> advance 1 >>| fun () -> "+"
|
||||||
|
| Some '-' -> advance 1 >>| fun () -> "-"
|
||||||
|
| Some c when is_digit c -> return "+"
|
||||||
|
| _ -> fail "digit or sign expected"
|
||||||
|
|
||||||
|
let int_str =
|
||||||
|
let* s = sign in
|
||||||
|
let* n = uint_str in
|
||||||
|
return (s ^ n)
|
||||||
|
|
||||||
|
let int_num = int_str >>| int_of_string
|
||||||
|
|
||||||
|
let dot =
|
||||||
|
peek_char >>= function
|
||||||
|
| Some '.' -> advance 1 >>| fun () -> true
|
||||||
|
| _ -> return false
|
||||||
|
|
||||||
|
let float_str =
|
||||||
|
let* n = int_str in
|
||||||
|
let* is_dot = dot in
|
||||||
|
if is_dot then
|
||||||
|
let* f = uint_str in return (n ^ "." ^ f)
|
||||||
|
else
|
||||||
|
return n
|
||||||
|
|
||||||
|
let float_num = float_str >>| float_of_string
|
||||||
Reference in new issue
Block a user