package reparse
Recursive descent parsing library for ocaml
Install
Dune Dependency
Authors
Maintainers
Sources
reparse-unix-v2.1.0.tbz
sha256=51f7bb7087679e7e8dabf237a2e080094391bc626476c4c614515a14a3da6919
sha512=b886a2261131b7ccf5d38def08a57724a8eb1a8b95d299f452659b874f7d186aa1e25e77aebfa921b269804f1d9895c0e124c31bbd5d204af9c5dd9b1c720ebf
Description
Monadic, recursive descent based, parser construction library for ocaml. Comprehensively documented and tested.
Published: 07 Apr 2021
README
Reparse
Reparse is a monadic, recursive descent based, comprehensive parser construction library for ocaml.
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.
open Reparse
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 (ignore_m space)
let binop : 'a t -> char -> 'b t -> ('a -> 'b -> 'c) -> 'c t =
fun exp1 op exp2 f ->
map3 exp1 (skip_spaces *> char op <* skip_spaces) exp2 ~f:(fun e1 _ e2 -> f e1 e2)
;;
let integer : expr t =
let+ d = digits in
Int (int_of_string d)
;;
let factor : expr t -> expr t =
fun expr ->
any
[ char '(' *> skip_spaces *> expr <* skip_spaces <* char ')'
; skip_spaces *> integer <* skip_spaces
]
;;
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 ])
;;
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
;;
(* Test AST *)
let r =
let actual = parse_string expr "1*2-4+3" in
let expected = Sub (Mult (Int 1, Int 2), Add (Int 4, Int 3)) in
Bool.equal (expected = actual) true
;;
(* Run and test the evaluator. *)
let exp_result =
let v = eval (parse_string expr "12+1*10") in
Int.equal 22 v
;;
The expression grammar is defined by the following BNF grammar:
<expr> ::= <term> "+" <expr>
| <term>
<term> ::= <factor> "*" <term>
| <factor>
<factor> ::= "(" <expr> ")"
| integer
More Examples
Credits
https://github.com/MLton/mlton/blob/master/lib/mlton/basic/parse.sig
https://github.com/c-cube/ocaml-containers/blob/master/src/core/CCParse.mli
Used by (2)
-
http-multipart-formdata
= "1.1.0"
-
reparse-unix
>= "2.1.0"
Conflicts
None
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
On This Page