caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Daniel de Rauglaudre <daniel.de_rauglaudre@inria.fr>
To: caml-list@inria.fr
Subject: Grammars and pretty print
Date: Sun, 7 Dec 1997 16:30:54 +0100 (MET)	[thread overview]
Message-ID: <199712071530.QAA25753@jaune.inria.fr> (raw)
In-Reply-To: <348402F1.D25@lri.fr> from Emmanuel Engel at "Dec 2, 97 01:45:37 pm"

About grammars and pretty print...

I have implemented something for Camlp4. It is a syntax extension,
interpreting the statement extend as doing the entries extensions
and defining pretty printing functions. It is a prototype but you
can download it at address:
   ftp://ftp.inria.fr/INRIA/Projects/cristal/Daniel.de_Rauglaudre/
files:
   pa_extprint.cmo
   pa_extprint.ml (the source)

You must define a function named "print_token" taking a value of type
Token.t (camlp4 library) and printing it.

Example of use. File "foo.ml":
==================================================================
type ast =
    Plus of ast * ast
  | Minus of ast * ast
  | Mult of ast * ast
  | Div of ast * ast
  | Exp of ast * ast
  | Int of string
;;

let gram = Grammar.create (Plexer.make ());;
let test = Grammar.Entry.create gram "test";;
let expr = Grammar.Entry.create gram "expr";;

let print_token =
  function
    Token.Tterm x -> print_string x
  | Token.Tint x -> print_string x
  | _ -> ()
;;

EXTEND
  test: [[ x = expr; EOI -> x ]];
  expr:
    [ "plus" LEFTA
      [ x = expr; "+"; y = expr -> Plus (x, y)
      | x = expr; "-"; y = expr -> Minus (x, y) ]
    | "mult" LEFTA
      [ x = expr; "*"; y = expr -> Mult (x, y)
      | x = expr; "/"; y = expr -> Div (x, y) ]
    | "exp" RIGHTA
      [ x = expr; "^"; y = expr -> Exp (x, y) ]
    | "simple"
      [ i = INT -> Int i
      | "("; x = expr; ")" -> x ] ]
   ;
END;;
==================================================================

Result of
    camlp4o ./pa_extprint.cmo pr_o.cmo pr_extend.cmo gram.ml

==================================================================
type ast =
    Plus of ast * ast
  | Minus of ast * ast
  | Mult of ast * ast
  | Div of ast * ast
  | Exp of ast * ast
  | Int of string
;;

let gram = Grammar.create (Plexer.make ());;
let test = Grammar.Entry.create gram "test";;
let expr = Grammar.Entry.create gram "expr";;

let print_token =
  function
    Token.Tterm x -> print_string x
  | Token.Tint x -> print_string x
  | _ -> ()
;;

let rec pr_test x = pr_expr x; print_token Token.Teoi; ()
and pr_expr x =
  let rec p0 =
    function
      Plus (x, y) -> pr_expr x; print_token (Token.Tterm "+"); pr_expr y; ()
    | Minus (x, y) -> pr_expr x; print_token (Token.Tterm "-"); pr_expr y; ()
    | x -> p1 x
  and p1 =
    function
      Mult (x, y) -> pr_expr x; print_token (Token.Tterm "*"); pr_expr y; ()
    | Div (x, y) -> pr_expr x; print_token (Token.Tterm "/"); pr_expr y; ()
    | x -> p2 x
  and p2 =
    function
      Exp (x, y) -> pr_expr x; print_token (Token.Tterm "^"); pr_expr y; ()
    | x -> p3 x
  and p3 =
    function
      Int i -> print_token (Token.Tint i); ()
    | x ->
        print_token (Token.Tterm "(");
        pr_expr x;
        print_token (Token.Tterm ")");
        ()
  in
  p0 x
;;
EXTEND
  test:
    [ [ x = expr; EOI -> x ] ]
  ;
  expr:
    [ "plus" LEFTA
      [ x = SELF; "+"; y = SELF -> Plus (x, y)
      | x = SELF; "-"; y = SELF -> Minus (x, y) ]
    | "mult" LEFTA
      [ x = SELF; "*"; y = SELF -> Mult (x, y)
      | x = SELF; "/"; y = SELF -> Div (x, y) ]
    | "exp" RIGHTA
      [ x = SELF; "^"; y = SELF -> Exp (x, y) ]
    | "simple"
      [ i = INT -> Int i | "("; x = SELF; ")" -> x ] ]
  ;
END;;
==================================================================

Remark: if you have a version of camlp4 (camlp4 -v) anterior to
1.06+2, the previous command will display it with an incorrect
"declare" statement. It is just a pretty print bug that is fixed.
Take the patch in the ftp directory.

--------------------------------------------------------------------------
 Daniel de RAUGLAUDRE

 Projet Cristal - INRIA Rocquencourt
 Tel: +33 (01) 39 63 53 51
 Email: daniel.de_rauglaudre@inria.fr
 Web: http://pauillac.inria.fr/~ddr/
--------------------------------------------------------------------------





      parent reply	other threads:[~1997-12-07 15:47 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-12-02 12:45 Grammaires et " Emmanuel Engel
1997-12-02 20:58 ` Daniel de Rauglaudre
1997-12-03 17:38   ` Pierre Weis
1997-12-07 15:30 ` Daniel de Rauglaudre [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=199712071530.QAA25753@jaune.inria.fr \
    --to=daniel.de_rauglaudre@inria.fr \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).