Welcome to Ostap

Ostap is an OCaml module to provide a set of parser combinators. The name of this library originates from Ostap Bender --- the central character of Ilya Ilf and Eugene Petrov's comedy "The Twelve Chairs". Bender is generally referred to as "The Great Combinator" since the word "combinator" in Russian also means "a swindler", "a sly man" etc.

Additionally to the common set of parser combinators Ostap provides a camlp4 syntax extension pa_ostap.cmo to embed grammar expressions written in BNF-like style into OCaml code. Another feature of pa_ostap is that it allows to consider streams as objects and so makes integration of lexers and parsers simpler. Please have a look at the documentation for details.


Ostap is distributed under the  GNU Lesser General Public License.


Stable version

Get a source tarball: attachment:ostap-0.2.tar.gz Download (release 0.2, revision 40)

Or checkout  Subversion repository:

svn co https://oops.tepkom.ru/svn/ostap/tags/RELEASE-0.2 ostap-0.2

Or browse sources online.

Older releases see below.

Development version

Checkout  Subversion repository:

svn co https://oops.tepkom.ru/svn/ostap/trunk ostap

Or click Browse Source for online source browser.


You should have  Logger and  Typeutil installed in your system to build Ostap.

Make and install

Run configure script that discovers your environment, then make, make check (optional) and make install:

$ ./configure
$ make
$ make check
# make install


We demonstrate the usage of Ostap/pa_ostap by the following small example. Please refer to the complete documentation for details.

open Matcher
open String
open Str
open Ostap 

(* Grammar expression *)
let p = rule <name>=IDENT -"(" (<h>=IDENT <t>=(-"," IDENT)* {h::t}) -")" end

(* Whitespace and identifier regular patterns *)
let ws      = regexp "[ \n\t\r]+"
let ident   = regexp "[a-zA-Z_]\([a-zA-Z_0-9]\)*"

(* Lexer definition *)
class lexer s p coord =
    object (self)
       (* Magic phrase to inherit from predefined matcher *)
       inherit [lexer] matcher (fun s p coord -> new lexer s p coord) s p coord

       (* Skipping whitespaces *)
       method skip =          
          if string_match ws s p
	    let m = matched_string s in
	    (p+length m), (shiftPos coord m 0 (length m))
	  else p, coord

       (* Matching identifiers *)
       method getIDENT = self#get "identifier" ident


(* Stream constructor *)
let ofString s = new lexer s 0 (1, 1)

(* Parsing driver *)
let parse s =
  let module P = View.NamedPair (struct let first = "name" let second = "args" end) (Token) (View.List (Token)) in
  match p (ofString s) with
  | Parsed (x, _) -> Printf.printf "Success: %s\n" (P.toString x)
  | Failed msgs | Error msgs -> Printf.printf "Unsuccess: %s\n" (let module M = View.List (Msg) in M.toString msgs)

(* Entry point *)
let _ =
  parse "a (b, c, d)";
  parse "a"


See auto-generated html pages.