Skip to content

Instantly share code, notes, and snippets.

@arbipher
Last active December 20, 2019 14:38
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 arbipher/11a7620265419606f33f2614756cecfa to your computer and use it in GitHub Desktop.
Save arbipher/11a7620265419606f33f2614756cecfa to your computer and use it in GitHub Desktop.
code on angstrom
(* #require "Angstrom";; *)
open Angstrom
type exp =
| Int of int
| Plus of exp * exp
let (let*) = (>>=)
let ws = skip_while (function
| '\x20' | '\x0a' | '\x0d' | '\x09' -> true
| _ -> false)
let lchar c =
ws *> char c
let parens p = lchar '(' *> p <* lchar ')'
let is_digit =
function '0' .. '9' -> true | _ -> false
let integer =
ws *>
take_while1 is_digit >>| (fun x -> Int (int_of_string x))
let int_plus =
(* parens @@ *)
let* es = (sep_by1 (lchar '+') integer) in
let e1, er = List.hd es, List.tl es in
(return (List.fold_left (fun acc e -> Plus (acc, e)) e1 er))
(* <* (lchar ';') *)
let expr : exp t =
(* parens @@ *)
fix (fun expr ->
let plus =
let* es = (sep_by1 (lchar '+') expr) in
let e1, er = List.hd es, List.tl es in
return (List.fold_left (fun acc e -> Plus (acc, e)) e1 er)
in
ws *>
(* peek_char_fail >>= fun _ -> *)
(choice [integer; plus ]))
(* <* (lchar ';') *)
let eval (s : string) =
match parse_string expr s with
| Ok v -> v
| Error msg -> failwith msg
let ps = parse_string int_plus
let p1 = "1";;
eval p1;;
ps p1;;
let p2 = "1 + 1";;
eval p2;;
ps p2;;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment