FliPpr: A Prettier Invertible Printer
=====================================

What is it?
-----------

When we implement a programming language, we usually have to write
 parser and a pretty-printer. However, manually writing both programs
 is not only tedious but also error-prone; it may happen that a
 pretty-printed result is not correctly parsed.

FliPpr, which is a program transformation system that uses program
inversion to produce a CFG parser from a pretty-printer, will solve
the problem. Thanks to the program inversion, the consistency between
a given pretty-printer and the derived parser is guaranteed.  The
advantages of our system are: 

  * we can write a program that traverses on structured ASTs
    (pretty-printer) rather than structure-less strings (parser),

  * as a result, we have fine-grained control on pretty-printing,

  * and we can reuse existing efficient implementations of
    pretty-printers and parsers.


How to Install?
---------------

### Requirements

FliPpr requires GHC, alex and happy. These programs will be installed if
you install [Haskell Platform](http://www.haskell.org/platform/).

We have tested GHC 7.4.1, alex 3.0.1, and happy 1.18.9. 

### Install

  1. Download the tarball of [FliPpr](http://www-kb.is.s.u-tokyo.ac.jp/~kztk/FliPpr/FliPpr-0.0.2.tar.gz).
  2. Expand the downloaded tarball.
  3. Move to the generated directory.
  4. Type `make`

How to Use?
------------

    $ ./FliPpr INPUTFILE > OUTPUTFILE

The OUTPUTFILE contains a definition of a pretty-printer copied from
INPUTFILE and a parser. For a pretty-printing function `f`, which must
be declared in topmost line, a parsing function `parse_f` is
generated.

(Examples)[./Examples] directory contains a few examples. 
For example, the example `Examples/minus.txt` defines a pretty-printer 
for a small expression language consists of the constant one, 
the subtraction and the division. You can construct a parser for 
the language by:

    $ ./FliPpr Examples/minus.txt -m "Examples.Defs" > t.hs 

The obtained file `t.hs` contains the corresponding parser. 
In addition, it contains a Haskell-version copy of the original pretty-printer.

Now you can test the obtained parser and pretty-printer.

    $ ghci t.hs 
    ...
    *Main> :t pprMain 
    pprMain :: Examples.Defs.E -> Doc
    *Main> :t parse_pprMain 
    parse_pprMain
      :: (Functor m, Control.Monad.MonadPlus m) =>
         [Char] -> m Examples.Defs.E
    *Main> pprMain (Minus (Minus One One) One)
    1 - 1 - 1
    *Main> parse_pprMain "1 - 1 - 1"
    Minus (Minus One One) One
    *Main> pprMain (Minus One (Minus One One))
    1 - (1 - 1)
    *Main> parse_pprMain "1 - ( 1 - 1)"
    Minus One (Minus One One)
    *Main> pprMain (Minus One (Div One One))
    1 - 1 / 1
    *Main> parse_pprMain "1 - 1 / 1"
    Minus One (Div One One)

Disclaimer 
----------

The current implement is prototype. It needs much more effort to be a
practical tool, especially, in the following points.
   
   * Currently, it generates parsers only for Haskell.  Although it
     has a potential power to produce parsers for other languages like
     ocaml, some Haskell-specific code is hard-wired.

   * The source code itself is not well structured;)

   * There may be a lot of bugs!
