Last active
December 20, 2019 14:38
-
-
Save arbipher/11a7620265419606f33f2614756cecfa to your computer and use it in GitHub Desktop.
code on angstrom
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* #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