From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by c5ff346549e7 (Postfix) with ESMTPS id C86715D5 for ; Tue, 21 Jan 2020 06:48:51 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.70,345,1574118000"; d="scan'208";a="432304373" Received: from sympa.inria.fr ([193.51.193.213]) by mail2-relais-roc.national.inria.fr with ESMTP; 21 Jan 2020 07:48:50 +0100 Received: by sympa.inria.fr (Postfix, from userid 20132) id BB6477F3D7; Tue, 21 Jan 2020 07:48:50 +0100 (CET) Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 85D177F30F for ; Tue, 21 Jan 2020 07:48:47 +0100 (CET) Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=rich@annexia.org; spf=Pass smtp.mailfrom=rich@annexia.org; spf=None smtp.helo=postmaster@mail.annexia.org IronPort-PHdr: =?us-ascii?q?9a23=3A8ogR4REgDr5ukoZ3omQOpp1GYnF86YWxBRYc798d?= =?us-ascii?q?s5kLTJ7yrs2wAkXT6L1XgUPTWs2DsrQY0raQ6v+rCDJIoc7Y9ixbK9oUD15NoP?= =?us-ascii?q?5VtjRoONSCB0z/IayiRA0BN+MGamVY+WqmO1NeAsf0ag6aiHSz6TkPBke3blIt?= =?us-ascii?q?daz6FYHIksu4yf259YHNbAVUnjq9Zq55IAmroQnLucQanIRvJrwsxhbLrXdFf+?= =?us-ascii?q?Vbzn5sKV6Pghrw/Mi98INt/ihKp/4t68tMWrjmcqolSrBVEC4oOH0v6s3xshnD?= =?us-ascii?q?QwqP5n8CXWgTjxFFHQvL4gzkU5noqif1ufZz1yecPc3tULA7Qi+i4LtxSB/pky?= =?us-ascii?q?gIKTg0+3zKh8NqjaJbpBWhpwFjw4PRfYqYOuZycr/bcNgHQmVPQ9tRVzdZAoyi?= =?us-ascii?q?c4QPE+QPPeFdr4bnplsOqwa1CQ2jCe7rzzNFgGL9068n3OQ7CQzI0gwuEcwTvn?= =?us-ascii?q?rXo9r6KLodXu6uwanU0TnOde9a1Svn5YTWdB0qvPGCXah3ccrU0UQjGR/LjlSM?= =?us-ascii?q?pozlJTyVzPkCuHWb4OZ6UuyjkXMspQV2ojip2MgskYfFjZ8Sx1De9CV23IY1KM?= =?us-ascii?q?aiR059Z96rDpRRtyCAOIdsRcMiWW5otT88x7Ybt5C7ey0Kx44mxx7Zc/GHfI+I?= =?us-ascii?q?4hXsVOaVPzh0nm5qeLW6hxu07EOuyfX8W9G33VpXtCZJj9rBu3IX2xHQ5MWLUO?= =?us-ascii?q?Vx80m91TuJygvd8PtLIVoumqreM5MhwqA/lp4UsUnbGy/5gkT2jKuMeko+/Oio?= =?us-ascii?q?7froY7rnppCGLYN0jRv+Mqs2lsy+B+Q3LBQOUnCY9OihzrHv4E70TbdQgvA1nK?= =?us-ascii?q?TVqo7WKMoHqqKhBg9ayIcj6xKxDze819QYmGEKLEhEeB2bj4jkIEvBIPb+Dfih?= =?us-ascii?q?jFWskS1ky+rBPr37DZXBNmLDn6v5fbZh905czxI+zd5H55JTFrEBPPPzVVHrtN?= =?us-ascii?q?HDDx45Mgm0zP39CNpnzI8eWGSPArWYMKzIq1OI6PgvKfGWZIAJoDb9N+Ql5/n2?= =?us-ascii?q?gH8jh1Adcqip3YAYaHC5BPtrOESYYXvpgtgaC2cFpBAyTO3siF2YUD5cfWy+X6?= =?us-ascii?q?wm5jsjEoKpEZ/DRpyxgLyGxCq0AodZZmVCClyVFXfodp6EW+sXZSKJIs5hlyQE?= =?us-ascii?q?WqK7R48g0xGurg76xKB9Iura4C1L/a7kgdN84umWkRAp6RR1Cd6c2ieDVSU8sH?= =?us-ascii?q?kBQTQx3bs5mUth1laOy4B5heZZHJpd/bcBYw48M9jmwuN7EJXdWwvHd8yhSVC8?= =?us-ascii?q?Q9zgDytiYMg2xopEWUd2G9y4glj8mQ/sS50SkbGQTtRg6KPX31D4IcBw23fPkq?= =?us-ascii?q?47gA91EYN0KWS6i/snpEDoDInTnhDFxv/2J5RZ5zbE8SK49UTLpFtRCVUiWKPD?= =?us-ascii?q?UGAebw3Rt9urvhqTHY/rMqwuN0568eDHL6JLbtPzilAfH6XqPtLTc2O43WCqCk?= =?us-ascii?q?TRn+7eXM/RY2wYmR7lJg0EngQUpCbUMAE/AmGopWTTHD1nU1X1bBG0/A=3D=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0BpDAAHniZe/+ZTu1FlHgELHIQkbFQhE?= =?us-ascii?q?iqDSolLhhMBUwacFwNUCQEDAQwjDAEBhk4fBwEENBMCEAEBBAEBAQIBAgMEAWy?= =?us-ascii?q?Ea0wMgjsMg0UTHF8TIQUYDSWDOYJWKQusVzOKMwaBOIwoBnk+SYFHhX8CAoctI?= =?us-ascii?q?gSvUgcDgjmHPY5oDBuCR4xOi2KEX4l/iGGSTYFpIjeBIX0IO4JtTxgNiA0Xg1C?= =?us-ascii?q?KU0QyjW4BAQ?= X-IPAS-Result: =?us-ascii?q?A0BpDAAHniZe/+ZTu1FlHgELHIQkbFQhEiqDSolLhhMBUwa?= =?us-ascii?q?cFwNUCQEDAQwjDAEBhk4fBwEENBMCEAEBBAEBAQIBAgMEAWyEa0wMgjsMg0UTH?= =?us-ascii?q?F8TIQUYDSWDOYJWKQusVzOKMwaBOIwoBnk+SYFHhX8CAoctIgSvUgcDgjmHPY5?= =?us-ascii?q?oDBuCR4xOi2KEX4l/iGGSTYFpIjeBIX0IO4JtTxgNiA0Xg1CKU0QyjW4BAQ?= X-IronPort-AV: E=Sophos;i="5.70,345,1574118000"; d="scan'208";a="432304366" X-MGA-submission: =?us-ascii?q?MDEvfopWdemWui8cePgARpjyx2VnlxTRqWlJi+?= =?us-ascii?q?pRJ+surgMPTtRl2rFD/vmctylwQfssCsnBLUq+V+0plZE3h48+xSxZEN?= =?us-ascii?q?aXDTdZNTHa4kvaJtsBtyP4RUlhcgD00nggisY+ELZIVxvMr4acwOdnkS?= =?us-ascii?q?DJnKkCJ656C/OvbGgcoyVL2w=3D=3D?= Received: from 230.83.187.81.in-addr.arpa (HELO mail.annexia.org) ([81.187.83.230]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Jan 2020 07:48:46 +0100 Received: by mail.annexia.org (Postfix, from userid 1000) id 3D309AC000F8; Tue, 21 Jan 2020 06:48:45 +0000 (GMT) Date: Tue, 21 Jan 2020 06:48:45 +0000 From: "Richard W.M. Jones" To: caml-list@inria.fr, Francois.Pottier@inria.fr, Yann.Regis-Gianas@inria.fr Message-ID: <20200121064845.GM27889@rich.annexia.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) Subject: [Caml-list] Implementing include "file" statement in menhir Reply-To: "Richard W.M. Jones" X-Loop: caml-list@inria.fr X-Sequence: 17959 Errors-to: caml-list-owner@inria.fr Precedence: list Precedence: bulk Sender: caml-list-request@inria.fr X-no-archive: yes List-Id: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: [Resend, apologies if you get this twice, but I sent it earlier and that seems to have disappeared.] I'm writing a parser which needs to have a C-like include directive. There's an old thread on this describing a rather complicated way to do this for ocamllex: https://groups.google.com/forum/#!topic/fa.caml/_v_k4WTQV_Q I thought I'd have a go at writing an include statement in menhir, and I did come up with something which works but it's quite a large hack. What I did is documented below, but I wonder if someone can think of a simpler way to do this? Also two related questions: How do you pass extra parameters to menhir's generated parser functions? Is there a nice way to export values into menhir's generated parser.mli file? ---- The concept behind my include statement uses the following grammar: %token INCLUDE %token STRING %start file %% file: list(stmt) ; stmt: | INCLUDE STRING { let filename = $2 in let fp = open_in filename in let lexbuf = Lexing.from_channel fp in lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = filename }; (* Recursively call Parser.file: *) file Lexer.read lexbuf; close_in fp; } | ... other statements ... ; Unfortunately as written the above code cannot work because it introduces a circular dependency between the Parser and the Lexer modules (normally the Lexer module depends on the Parser, and so the Parser cannot use any functions from the Lexer module). To break the cycle we have to add: %{ let lexer_read = ref None %} and replace Lexer.read with: let reader = match !lexer_read with None -> assert false | Some r -> r in file reader lexbuf; Then to initialize lexer_read, we have to export it by doing this hack: menhir parser.mly echo 'val lexer_read : (Lexing.lexbuf -> token) option ref' >> parser.mli and we can set it from the main program. Rich.