From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: * X-Spam-Status: No, score=1.6 required=5.0 tests=AWL,DNS_FROM_RFC_POST, SPF_NEUTRAL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id C6A97BB84 for ; Wed, 28 Jan 2009 21:52:11 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvcBALlUgEnRVdsQimdsb2JhbACTTz8BAQEKCQwHDwWpAIEFjhQBAwEDhUQG X-IronPort-AV: E=Sophos;i="4.37,339,1231110000"; d="scan'208";a="34411225" Received: from mail-ew0-f16.google.com ([209.85.219.16]) by mail4-smtp-sop.national.inria.fr with ESMTP; 28 Jan 2009 21:51:36 +0100 Received: by ewy9 with SMTP id 9so3618410ewy.3 for ; Wed, 28 Jan 2009 12:51:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:content-type:cc:subject:from :to:references:in-reply-to:date:message-id:user-agent; bh=G6XsFxdNwHdmlTmH3t5QdCSPUOP49FFqSmJDEEmyi3U=; b=Ua8vmCsosUmNDdC/f8bRpFRgCnjPFsLBZ6aq0zggdTAWLUpS03BQz3nJOWz0rIjgj9 ejtiH+5n44KE6tX4nltwleZNe6D4m5bIgYa6NNsaSTNT9kWONOrvda6pSx3ywQKSuBas wi+70aEIxFM1yZLZUSNTh0SswBmhu/gdQ1hgE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=content-type:cc:subject:from:to:references:in-reply-to:date :message-id:user-agent; b=fNWmGi7iq1yKv9ew/VjQXz+ewLqHASHnoLgOD3Asxt7Dazg0A+J58fcdjrucGXYETk wsA/0z5qF8ian5tP6lBJ4kUaEscVjoPOJFrnrZwKMrb+IoTM8VqHacXnJRSEVdFolkgB PINEhWKkM9VYHDmBcNax2PVW9zpijeQao7Bsw= Received: by 10.86.4.2 with SMTP id 2mr184196fgd.49.1233175700673; Wed, 28 Jan 2009 12:48:20 -0800 (PST) Received: from localhost (home.feydakins.org [82.229.164.236]) by mx.google.com with ESMTPS id l12sm284881fgb.48.2009.01.28.12.48.19 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 28 Jan 2009 12:48:19 -0800 (PST) Content-Type: text/plain; charset=UTF-8 Cc: "caml-list@yquem.inria.fr" Subject: Re: [Caml-list] Ampersand in camlp4 grammar extension From: Nicolas Pouillard To: Paul Steckler References: <2EB36A07AAE8C44BBB1986425E7A22D0034D5BEF2D@atp-mbx1.in.nicta.com.au> In-Reply-To: <2EB36A07AAE8C44BBB1986425E7A22D0034D5BEF2D@atp-mbx1.in.nicta.com.au> Date: Wed, 28 Jan 2009 21:47:15 +0100 Message-Id: <1233174458-sup-6393@ausone.local> User-Agent: Sup/git X-Spam: no; 0.00; camlp:01 camlp:01 ocaml:01 preprocessed:01 infix:01 lexer:01 parser:01 lexer:01 ocaml:01 parser:01 syntax:01 expr:01 expr:01 cmo:01 inlined:01 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