MParser, a simple monadic parser combinator library
This library implements a rather complete and efficient monadic parser combinator library similar to the Parsec library for Haskell by Daan Leijen and the FParsec library for FSharp by Stephan Tolksdorf.
See the file LICENSE.txt for copying conditions.
Home page: https://github.com/cakeplus/mparser
MParser used to be a part of ocaml-base, a collection of useful OCaml libraries by Holger Arnold [1].
The monadic interface of MParser is compatible with pa_monad [2].
Dependencies
In order to compile this package, you will need:
- ocaml (>= 3.11).
- findlib [3].
- optional dependency: pcre-ocaml [4] for
mparser.pcre. - optional dependency: re [5] for
mparser.re.
Installing
- Uncompress the source archive and go to the root of the package.
- Run
ocaml setup.ml -configure. Optional flags:--enable-pcre-- support for PCRE-based regular expressions (MParser_PCREmodule,mparser.pcrefindlib package).--enable-re-- support for RE-based regular expressions (MParser_REmodule,mparser.refindlib package).
- Run
ocaml setup.ml -build. - Run
ocaml setup.ml -install. - Optionally, run
ocaml setup.ml -docto produce an HTML API reference.
Uninstalling
- Go to the root of the package
- Run
ocaml setup.ml -uninstall
Usage example
Let's implement a simple expression evaluator.
To save the typing effort, it is often handy to open the MParser module:
open MParserFirst, we define a parsing combinator expr, which handles expression
parsing, taking care of the operator precedence issues:
let infix p op =
Infix (p |>> (fun _ a b -> (`Binop (op, a, b))), Assoc_left)
let operators =
[
[
infix (char '*') `Mul;
infix (char '/') `Div;
];
[
infix (char '+') `Add;
infix (char '-') `Sub;
];
]
let decimal =
many1_chars digit |>> int_of_string
let expr =
expression operators (decimal |>> fun i -> `Int i)Next, we implement an interpreter for our expression tree:
let rec calc = function
| `Int i -> i
| `Binop (op, a, b) ->
match op with
| `Add -> calc a + calc b
| `Sub -> calc a - calc b
| `Mul -> calc a * calc b
| `Div -> calc a / calc bThe evaluator function:
let eval (s: string) : int =
match MParser.parse_string expr s () with
| Success e ->
calc e
| Failed (msg, e) ->
failwith msgUsing it:
eval "4*4+10/2" -> 21Have fun!
References
| [1] | http://www.holgerarnold.net/software |
| [2] | http://www.cas.mcmaster.ca/~carette/pa_monad |
| [3] | http://projects.camlcity.org/projects/findlib.html |
| [4] | https://bitbucket.org/mmottl/pcre-ocaml |
| [5] | https://github.com/ocaml/ocaml-re |