Version française
Home     About     Download     Resources     Contact us    
Browse thread
Ampersand in camlp4 grammar extension
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Nicolas Pouillard <nicolas.pouillard@g...>
Subject: Re: [Caml-list] Ampersand in camlp4 grammar extension
Excerpts from Paul Steckler's message of Wed Jan 28 10:39:16 +0100 2009:
> I'm writing a camlp4 grammar extension for OCaml that tries to match
> ampersands and rewrite expressions containing them.  That wouldn't
> be a good idea if my code contained ordinary ampersands used for conjunctions.
> But the code doesn't.
> 
> I'm struggling how to match the ampersands in my expression rewrite rules.
> I've tried "&" and SYMBOL "&", which don't work -- the preprocessed file contains
> the original ampersands.  OTOH, I've written rules which use things like "->" and
> work fine.

The answer depends on what you want to achieve, if you want to give to "&"
another syntactic form (no longer infix, or change the priorities), then I
would recommend you to just use "&" in your grammar rules. It will declares it
as a keyword (add it into a table of keywords) and then the token filter
between (between the lexer and the parser) will transform it from SYMBOL to
KEYWORD.

In fact, I've just looked at the lexer and the '&' token is *at the beginning*
emitted using the SYMBOL constructor, however by looking at the OCaml parser
files, one can see that "&" is already used literally, so already declared as
a keyword and so already transformed as a KEYWORD "&". Conclusion use "&" to
match it.

However I can guess in your question that you don't really want to change the
syntax of the binary operator "&", but rather to change it's meaning. In
camlp4 there is a much more sane and easier way to do this using filters.
By the way there is an example in the camlp4 sources that does exactly this.

$ cd camlp4/examples
$ cat apply_operator.ml
open Camlp4.PreCast;
AstFilters.register_str_item_filter
  (Ast.map_expr
    (fun
     [ <:expr@loc< $e1$ & $e2$ >> -> <:expr@loc< $e1$ $e2$ >>
     | e -> e ]))#str_item;
$ ocamlbuild -tags camlp4rf,use_camlp4 apply_operator.cmo
$ cat apply_operator_test.ml
(* To force it to be inlined. If not it's not well typed. *)
let ( & ) = ();;

fun f g h x -> f & g & h x
$ camlp4o ./_build/apply_operator.cmo apply_operator_test.ml
(* To force it to be inlined. If not it's not well typed. *)
let ( & ) = ()
    
let _ = fun f g h x -> f (g (h x))

Best regards,

-- 
Nicolas Pouillard