Skip to content

Instantly share code, notes, and snippets.

@takscape
Created September 13, 2014 02:52
Show Gist options
  • Save takscape/df9925d0f18b2942feb2 to your computer and use it in GitHub Desktop.
Save takscape/df9925d0f18b2942feb2 to your computer and use it in GitHub Desktop.
Parsing with Sedlex and BatParserCo
#!/usr/bin/env ocamlscript
Ocaml.ocamlflags := ["-g"; "-thread"];
Ocaml.use_camlp4 := false;
Ocaml.packs := ["batteries"; "sedlex"]
--
open Batteries
(* Sedlex lexer definitions *)
type token =
| Number of int
| Op_plus
let digit = [%sedlex.regexp? '0'..'9']
let number = [%sedlex.regexp? Plus digit]
let op_plus = [%sedlex.regexp? '+']
(* Lexer function *)
let rec token buf =
match%sedlex buf with
| number ->
let n = int_of_string (Sedlexing.Utf8.lexeme buf) in
Some (Number n, buf)
| op_plus ->
Some (Op_plus, buf)
| Plus xml_blank ->
token buf
| eof ->
None
| _ ->
assert false
(* BatParserCo parser definitions *)
let pnumber =
let open ParserCo in
satisfy (function
| Number v -> true
| _ -> false) |> label "number"
let pplus =
let open ParserCo in
exactly Op_plus |> label "op_plus"
let rec expr =
let open ParserCo in
pnumber >>> zero_plus (pplus >>> pnumber) >>> eof
let () =
let buf = Sedlexing.Utf8.from_string "100 + 200" in
let tokens = Enum.unfold buf token in
let source = ParserCo.Source.of_enum tokens () (fun _ state -> state) in
ParserCo.debug_mode := true;
ParserCo.run expr source |> ignore
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment