From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by yquem.inria.fr (Postfix) with ESMTP id C0A37BB9C for ; Mon, 5 Dec 2005 06:35:37 +0100 (CET) Received: from ash25e.internode.on.net (ash25e.internode.on.net [203.16.214.182]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id jB55ZZXJ026008 for ; Mon, 5 Dec 2005 06:35:36 +0100 Received: from rosella (ppp33-4.lns1.syd2.internode.on.net [59.167.33.4] (may be forged)) by ash25e.internode.on.net (8.12.9/8.12.6) with ESMTP id jB55ZYXa089720 for ; Mon, 5 Dec 2005 16:05:34 +1030 (CST) (envelope-from skaller@users.sourceforge.net) Subject: Another nasty with ocamlyacc: magic needed? From: skaller To: caml-list@yquem.inria.fr Content-Type: text/plain Date: Mon, 05 Dec 2005 16:35:33 +1100 Message-Id: <1133760933.8957.125.camel@rosella> Mime-Version: 1.0 X-Mailer: Evolution 2.4.1 Content-Transfer-Encoding: 7bit X-Miltered: at nez-perce with ID 4393D1A7.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; ocamlyacc:01 showstopper:01 parsers:01 tokens:01 ocamlyacc:01 tokens:01 parser:01 mli:01 parser:01 token:01 mli:01 token:01 recursive:01 dependencies:01 ocaml:01 X-Spam-Checker-Version: SpamAssassin 3.0.3 (2005-04-27) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.0.3 I have what looks like a showstopper (meaning black magic seems to be the only solution). I need two *distinct* parsers which use the same set of tokens. This is currently impossible AFAICS without magic (distinct -- in a different module entirely) Roughly, the problem is that Ocamlyacc generates the tokens, and they go in the parser.mli file. So any second parser has to depend on it. However the only way to *invoke* the parser is to pass it inside a token. the interface for that parser must be defined AFTER the parser.mli since it needs to know the token types. But it has to be known INSIDE the actual parser, to invoke it. There is no way to extend the interface Ocamlyacc generates for a parser (you can add extra helper functions but they don't go in the interface). Thus -- it is impossible. IMHO the traditional yacc style design is poor, but it works fine for C because there is no problem with recursive dependencies in interfaces (header files). In Ocaml, there is such a problem, and so the yacc design basically fails -- it isn't suitable for Ocaml. But i need to work around this somehow, does anyone have any smart ideas how to fix the problem, without abandoning Ocamlyacc? If I could abstract the type of the secondary parser so it didn't need to expose the knowledge of tokens, it would fix the problem I think -- then the type could be defined BEFORE the ocamlyacc parser, but the implementation defined AFTER it (using Ocaml classes and class types). Just to be clear the situation is: user_statement: | USER_KEYWORD { let srt, kw = $1 in let sr = slift srt in print_endline ("USER KEYWORD " ^ kw); `AST_nop (sr,kw) } Instead of `AST_nop I need to call a function which parses more of the input, probably passing it the current lexbuf as well. The lexer knows this information and could put it into the USER_KEYWORD token .. if it were possible to define the type of the attribute of the USER_KEYWORD token.. but that can only be done in one place .. prior to the parser mli file. So I think I may have to use Obj.magic .. or completely replace Ocamlyacc. -- John Skaller Felix, successor to C++: http://felix.sf.net