# package reparse

Recursive descent parsing library for ocaml

## Sources

reparse-v3.1.0.tbz
`sha256=60e57fdac0ae0b68b41a0cb5bd50327c84b306d40f74e9c21925c08049703e1d`
`sha512=329be459bbf3f354119298fcf4ac22c1a400b9acd213267e732b76bcf2add81eb80c713aec2b007ba9a47ace075a67467c10e305fad7fd2a63a5456f668b35ab`

## Description

Monadic, recursive descent based, parser construction library for ocaml. Comprehensively documented and tested

## Published: 14 Jul 2021

### Reparse

Reparse is a monadic, recursive descent based, comprehensive parser construction library for ocaml.

Reparse Documentation

### Getting Started

``````\$ opam install reparse
``````

Add `reparse` to dune,

``````(executable # or library
(name hello_world)
(public_name hello_world)
(libraries reparse))
``````

### Example - Calculator

A calculator is the `hello world` of parsers. Here is an implementation in `Reparse` which supports `+,-,*` and `/` operations.

``````# #require "reparse";;
``````
``````open Reparse.String

type expr =
| Int of int
| Add of expr * expr
| Sub of expr * expr
| Mult of expr * expr
| Div of expr * expr

let skip_spaces = skip space

let binop : 'a t -> char -> 'b t -> ('a -> 'b -> 'c) -> 'c t =
fun exp1 op exp2 f ->
(exp1, skip_spaces *> char op <* skip_spaces, exp2)
<\$\$\$> fun e1 _ e2 -> f e1 e2

let integer : expr t =
let+ d = skip_spaces *> digits <* skip_spaces in
Int (int_of_string d)

let factor : expr t -> expr t =
fun expr ->
any [ char '(' *> skip_spaces *> expr <* skip_spaces <* char ')'; integer ]

let term : expr t -> expr t =
fun factor ->
recur (fun term ->
let mult = binop factor '*' term (fun e1 e2 -> Mult (e1, e2)) in
let div = binop factor '/' term (fun e1 e2 -> Div (e1, e2)) in
mult <|> div <|> factor)

let expr : expr t =
recur (fun expr ->
let factor = factor expr in
let term = term factor in
let add = binop term '+' expr (fun e1 e2 -> Add (e1, e2)) in
let sub = binop term '-' expr (fun e1 e2 -> Sub (e1, e2)) in
any [ add; sub; term ] <?> "expr")

let rec eval : expr -> int = function
| Int i -> i
| Add (e1, e2) -> eval e1 + eval e2
| Sub (e1, e2) -> eval e1 - eval e2
| Mult (e1, e2) -> eval e1 * eval e2
| Div (e1, e2) -> eval e1 / eval e2
``````
``````# let ast = parse (create_input_from_string "1*2-4+3") expr ;;
val ast : (expr * int, string) result =
Ok (Sub (Mult (Int 1, Int 2), Add (Int 4, Int 3)), 7)

# eval @@ Result.get_ok (parse (create_input_from_string "12+1*10") expr);;
Line 1, characters 9-72:
Error: This expression has type expr * int
but an expression was expected of type expr
``````

## Dependencies (3)

1. cstruct `>= "6.0.0"`
2. ocaml `>= "4.10.0"`
3. dune `>= "2.9"`

## Dev Dependencies (5)

1. odoc `with-doc`
2. ppx_deriving `with-test`
3. ppx_deriving_popper `with-test`
4. popper `with-test`
5. mdx `with-test`

## Used by (2)

1. reparse-lwt `!= "3.0.1"`
2. reparse-lwt-unix `!= "3.0.1"`

None