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=0.0 required=5.0 tests=none autolearn=disabled version=3.1.3 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 728E5BC6F; Thu, 3 May 2007 03:18:06 +0200 (CEST) Received: from ipmail01.adl2.internode.on.net (ipmail01.adl2.internode.on.net [203.16.214.140]) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id l431I3Ci006586; Thu, 3 May 2007 03:18:05 +0200 X-IronPort-AV: E=Sophos;i="4.14,482,1170595800"; d="scan'208";a="122621817" Received: from ppp8-148.lns1.syd7.internode.on.net (HELO [192.168.1.201]) ([59.167.8.148]) by ipmail01.adl2.internode.on.net with ESMTP; 03 May 2007 10:47:55 +0930 Subject: Re: [Caml-list] Re: [Menhir-list] There's an elephant in the room: Solution to sharing a symbol table From: skaller To: Francois.Pottier@inria.fr Cc: Caml List , menhir-list@yquem.inria.fr In-Reply-To: <20070502183020.GA17473@yquem.inria.fr> References: <1EE80473-541D-478D-97F8-06A1B5F65F79@gmail.com> <20070502054411.GB726@yquem.inria.fr> <8C011A98-CE76-4A83-B24C-BA37B66DF15D@gmail.com> <1178096690.13660.80.camel@rosella.wigram> <20070502115635.GA21560@yquem.inria.fr> <1178122046.6486.31.camel@rosella.wigram> <20070502183020.GA17473@yquem.inria.fr> Content-Type: text/plain Date: Thu, 03 May 2007 11:17:52 +1000 Message-Id: <1178155073.7026.14.camel@rosella.wigram> Mime-Version: 1.0 X-Mailer: Evolution 2.10.1 Content-Transfer-Encoding: 7bit X-Miltered: at concorde with ID 4639384B.001 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; 0200,:01 trivial:01 bool:01 mutable:01 unacceptable:01 parser:01 parsing:01 parser:01 abstracted:01 functors:01 typedefs:01 lexbuf:01 lexing:01 struct:01 lexbuf:01 On Wed, 2007-05-02 at 20:30 +0200, Francois Pottier wrote: > Hi, > > On Thu, May 03, 2007 at 02:07:26AM +1000, skaller wrote: > > State must be maintained in function arguments. > > This is a trivial example, but: > > let x = ref 0 > let f () : bool = incr x; x / 2 = 0 Yes, but I rule out global mutable state as unacceptable by requiring reentrancy. > Here, f exploits an internal state, even though it is not explicitly > parameterized over a piece of state. Similarly, a parser can have internal > state, even if the parsing functions are not explicitly parameterized over a > piece of state. It is sufficient for the entire parser either to refer to a > global variable or to abstracted over a piece of state (which functors allow). As above, if that state is global the result isn't re-entrant and isn't acceptable. > I don't see why this is so. In fact, nothing in your example seems to require > any kind of state -- you only need the parser to be able to recursively invoke > itself. Or am I missing something? I didn't show the full parser of course. In fact, Felix grammar is user extensible, so there has to be somewhere to hold the extensions. Similarly, a C parser requires a symbol table for typedefs, and Felix allows embedded C. In fact, Felix can call the FrontC/CIL parser on fragments of C code -- and CIL uses global variables so isn't re-entrant. In fact Joel explained the 'elephant' technique: let parser str = let tab = .. in let lexbuf = Lexing.from_string str in let module P = EasyParser.Make (struct let tab = tab end) in P.program (token tab) lexbuf which uses a local module to turn a global variable into a function local one. That's pretty clever, the function 'parser' here is reentrant (even though P.program is not). To support recursion you'd need: let module P = EasyParser.Make (struct let tab = tab let parser = parser (* pass fun for recursion *) end) in Quite a clever use of a local modules and functors therefore, allows %parameter to suffice, without further changes to Menhir .. though it would still be much easier if you could just do it like Ocamllex, I have to agree this does work. -- John Skaller Felix, successor to C++: http://felix.sf.net