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 9E8155D5 for ; Tue, 21 Jan 2020 07:15:51 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.70,345,1574118000"; d="scan'208";a="432308206" Received: from sympa.inria.fr ([193.51.193.213]) by mail2-relais-roc.national.inria.fr with ESMTP; 21 Jan 2020 08:15:50 +0100 Received: by sympa.inria.fr (Postfix, from userid 20132) id AC68F7F3CD; Tue, 21 Jan 2020 08:15:50 +0100 (CET) Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 876EA7F30F for ; Tue, 21 Jan 2020 08:15:45 +0100 (CET) Authentication-Results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=yrg@irif.fr; spf=Pass smtp.mailfrom=yrg@irif.fr; spf=None smtp.helo=postmaster@korolev.univ-paris7.fr IronPort-PHdr: =?us-ascii?q?9a23=3AJdgrpx2SMYm1BijismDT+DRfVm0co7zxezQtwd8Z?= =?us-ascii?q?seMSI/ad9pjvdHbS+e9qxAeQG9mCt7Qd1KGP6/moGTRZp8rY6zZaKN0EfiRGoP?= =?us-ascii?q?1epxYnDs+BBB+zB9/RRAt+Iv5/UkR49WqwK0lfFZW2TVTTpnqv8WxaQU2nZkJ6?= =?us-ascii?q?KevvB4Hdkdm82fys9J3PeQVIgye2ba9vIBmsogjdq8YbjZF/JqszxRfFv2dEd/?= =?us-ascii?q?lLzm9sOV6fggzw68it8JNt6Shcp+4t+8tdWqjmYqo0SqBVAi47OG4v/s3rshfD?= =?us-ascii?q?TQqL5nQCV2gdjwRFDQvY4hzkR5n9qiT1uPZz1ymcJs32UKs7WS++4KdxSR/nkz?= =?us-ascii?q?kIOjgk+2zKkMNwjaZboBW8pxxjxoPffY+YOOZicq7bYNgXXnRKUNpPWCNdA4O8?= =?us-ascii?q?d4oPAPQHPeZEtIn2ul8CoQKjCQWwGO/jzzlFiXjr060nyOQhCR/J0xA8H9wAt3?= =?us-ascii?q?TUqc/6NKYUUeuoyKXFwjHOY/ZQ1Dzg6obHbwohrOmDUrJ+c8XfyUchGQDYgFuO?= =?us-ascii?q?tYPoJC+V2vgXvmSH8+ZsSeCihmg6oA9xuDivwcIsh5HLiY0PzFDE8zhyzpovIt?= =?us-ascii?q?23SU57eseoHppRty6AMYt5WNgiSHxvtSc60L0GtoW2fCkQyJQmyR7TcfKHc5KR?= =?us-ascii?q?7x/lSe2fLzB4hHd/d7K+gRa/6Uegyur7Vsm71FZFsDBJncXLtnAI0RHY98uJSu?= =?us-ascii?q?Nl80u83TuC2Brf5v9ELE07j6bWKoMtzqQtmpcdsknPBjH6lFnygaOMdUgp+vKk?= =?us-ascii?q?5/r5brn7vJOQKo15hw/4P68zgMKwG/44PRILX2WD+eSzyrnj/UrhTbVJif02iK?= =?us-ascii?q?7ZsJTEKsQFvKK5HglV0oc96xqmFzepys4YnXgcLF9HYh6HgZLpN0nPIPD+E/i/?= =?us-ascii?q?n0yhnCpvyv3JJLHtHJXAI3fZnLrgYLpx8VNQxQQwwNxH4pJbELABIPb9Wk/rs9?= =?us-ascii?q?zYCwc0Mgyuw+boE9h915keWWOBAqODPqPSq0eE5vgzLOmUeI8VpDH9JuA56PH0?= =?us-ascii?q?iH85nUYRfa2o3ZsMdHC1Be9mIkWcYXr0mNgNC2YKvgwkTOzrklKOSzBTZ2yqVa?= =?us-ascii?q?Im+j47EJ6mDZvERo21jryBxCC7HoFKZmBHFF+MC2zldoSFW/cJcy2SONVuniYF?= =?us-ascii?q?VbinUY8h1AuhuBX0y7p9faLo/XhSj5Po1NFv66Xs0zR0vR5zCcmGmSnZVWB/nk?= =?us-ascii?q?sBQTk7zKF250tnxQHQ/7J/hqlpHNpVr8nIXQYhcLHdxupzEJimSxjOVtaTSVjg?= =?us-ascii?q?TM/wUmJ5dc4439JbOxU1IN6llB2WmnfzWuJHp/mwHJUxt5nk8T3xKsJ6kSqU16?= =?us-ascii?q?47iF0rXI1SM2y4w7Z27QnIWMjHiRfBzvf4ReEnxCfIsVy74y+LtUBcXhR3VPSX?= =?us-ascii?q?XGoeaA3Yt4agvx+Qf/qVEb0idzB554uaMKIbONzzjFsASu2xYNk=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0DNBQBZpCZeh4o9/sJlHAEBAQEBBwEBE?= =?us-ascii?q?QEEBAEBgXuBeIEdVjEqhBKJA4YSghEPikyQBQNUCQEDAQwjCQECAQGEQAKCDxw?= =?us-ascii?q?HAQQ0EwIQAQEEAQEBAgECAwQBEwEBAQgNCQgbDoU+DII7KYJ7AQEBAxIRBFIQC?= =?us-ascii?q?wsNAgImAgIiEgEFARwGEyKDBAGCewQLnnaBBD2LJ38ziTF/BoEOKoUbhnkaggC?= =?us-ascii?q?BR4JdPoJkAgKEcYI8IgSvUoFIe4c9jnQbgkeMTotihF+LSIcYkj4PI4EOOFmBI?= =?us-ascii?q?U0nETsxBoI1UBgNiA0OCYNQilRBATECgQQBAYxoAQE?= X-IPAS-Result: =?us-ascii?q?A0DNBQBZpCZeh4o9/sJlHAEBAQEBBwEBEQEEBAEBgXuBeIE?= =?us-ascii?q?dVjEqhBKJA4YSghEPikyQBQNUCQEDAQwjCQECAQGEQAKCDxwHAQQ0EwIQAQEEA?= =?us-ascii?q?QEBAgECAwQBEwEBAQgNCQgbDoU+DII7KYJ7AQEBAxIRBFIQCwsNAgImAgIiEgE?= =?us-ascii?q?FARwGEyKDBAGCewQLnnaBBD2LJ38ziTF/BoEOKoUbhnkaggCBR4JdPoJkAgKEc?= =?us-ascii?q?YI8IgSvUoFIe4c9jnQbgkeMTotihF+LSIcYkj4PI4EOOFmBIU0nETsxBoI1UBg?= =?us-ascii?q?NiA0OCYNQilRBATECgQQBAYxoAQE?= X-IronPort-AV: E=Sophos;i="5.70,345,1574118000"; d="scan'208";a="336485752" X-MGA-submission: =?us-ascii?q?MDFxCaYaKfRcrC5txOwS3khiDWUB+UI899ZSkK?= =?us-ascii?q?yqPYDEHQJuQSPze7GUoMBC+wA2e1m57xT2MuvOczNsld037vowFxhqUp?= =?us-ascii?q?/xh9U4l5R2d2TFlWOadUBdYqA9mV25QRDQEWUQcq6q09lO+IgOXUgQVX?= =?us-ascii?q?mM6A2Ldw8mA8IdlMbamPRZkA=3D=3D?= Received: from korolev.univ-paris7.fr ([194.254.61.138]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 21 Jan 2020 08:15:44 +0100 Received: from mailhub.math.univ-paris-diderot.fr (mailhub.math.univ-paris-diderot.fr [81.194.30.253]) by korolev.univ-paris7.fr (8.14.4/8.14.4/relay1/82085) with ESMTP id 00L7FfdB019513; Tue, 21 Jan 2020 08:15:41 +0100 Received: from mailhub.math.univ-paris-diderot.fr (localhost [127.0.0.1]) by mailhub.math.univ-paris-diderot.fr (Postfix) with ESMTP id 306DDB4128; Tue, 21 Jan 2020 08:15:44 +0100 (CET) X-Virus-Scanned: amavisd-new at math.univ-paris-diderot.fr Received: from mailhub.math.univ-paris-diderot.fr ([127.0.0.1]) by mailhub.math.univ-paris-diderot.fr (mailhub.math.univ-paris-diderot.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id 1CZsDmA1iZP9; Tue, 21 Jan 2020 08:15:42 +0100 (CET) Received: from mail-vk1-f173.google.com (mail-vk1-f173.google.com [209.85.221.173]) (Authenticated sender: yrg) by mailhub.math.univ-paris-diderot.fr (Postfix) with ESMTPSA id 4F256B4123; Tue, 21 Jan 2020 08:15:42 +0100 (CET) Received: by mail-vk1-f173.google.com with SMTP id b129so600895vka.4; Mon, 20 Jan 2020 23:15:42 -0800 (PST) X-Gm-Message-State: APjAAAWkep/5zQFSuclbFVpNQK2x18KiywDPrg83ABvwAJx1yO+4ZZVj LjcXi9bR8uqpbtoKxLQNPVbBZi62ziqO6dUkatA= X-Google-Smtp-Source: APXvYqyfdMEwe2ee2oUklFb18AIoA1NCM9ZhOkA90H6ud59kHxsEXhuP7ZTbNZUoJDWzJ03wtiL/W1N/wi3RUZuqo20= X-Received: by 2002:a1f:6005:: with SMTP id u5mr2061930vkb.35.1579590941283; Mon, 20 Jan 2020 23:15:41 -0800 (PST) MIME-Version: 1.0 References: <20200121064845.GM27889@rich.annexia.org> In-Reply-To: <20200121064845.GM27889@rich.annexia.org> From: =?UTF-8?B?WWFubiBSw6lnaXMtR2lhbmFz?= Date: Tue, 21 Jan 2020 08:15:34 +0100 X-Gmail-Original-Message-ID: Message-ID: To: "Richard W.M. Jones" Cc: Ocaml Mailing List , "Francois.Pottier@inria.fr" Content-Type: text/plain; charset="UTF-8" X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.2.7 (korolev.univ-paris7.fr [194.254.61.138]); Tue, 21 Jan 2020 08:15:41 +0100 (CET) X-Miltered: at korolev with ID 5E26A51D.004 by Joe's j-chkmail (http : // j-chkmail dot ensmp dot fr)! X-j-chkmail-Enveloppe: 5E26A51D.004 from mailhub.math.univ-paris-diderot.fr/mailhub.math.univ-paris-diderot.fr/null/mailhub.math.univ-paris-diderot.fr/ X-j-chkmail-Score: MSGID : 5E26A51D.004 on korolev.univ-paris7.fr : j-chkmail score : . : R=. U=. O=. B=0.000 -> S=0.000 X-j-chkmail-Status: Ham Subject: Re: [Caml-list] Implementing include "file" statement in menhir Reply-To: =?UTF-8?B?WWFubiBSw6lnaXMtR2lhbmFz?= X-Loop: caml-list@inria.fr X-Sequence: 17960 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: Hello Richard, if I had to do that, I would use the incremental mode of Menhir: indeed, this mode allows you to manage complex lexing without interfering with the parser. In that mode, Menhir produces a function that executes parsing step-by-step and between each step, you can easily update the state of the lexer. Besides, that technique solves the circular dependency problem since the interaction between the lexer and the parser is to be implemented in a third module, which only depends on the lexer and the parser. More precisely, I think that you could intercept the reduction of the production related to your include directive and enrich your lexer buffer with the content of the included file on-the-fly. Cheers, On Tue, Jan 21, 2020 at 7:48 AM Richard W.M. Jones wrote: > > [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.