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 7FBC65D5 for ; Thu, 25 Jul 2019 15:21:11 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.64,307,1559512800"; d="scan'208,217";a="393318274" Received: from sympa.inria.fr ([193.51.193.213]) by mail2-relais-roc.national.inria.fr with ESMTP; 25 Jul 2019 17:21:10 +0200 Received: by sympa.inria.fr (Postfix, from userid 20132) id 77AF582716; Thu, 25 Jul 2019 17:21:10 +0200 (CEST) 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 C8726826D8 for ; Thu, 25 Jul 2019 17:20:49 +0200 (CEST) Authentication-Results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=jocelyn.serot@uca.fr; spf=Pass smtp.mailfrom=jocelyn.serot@uca.fr; spf=None smtp.helo=postmaster@mta02.udamail.fr IronPort-PHdr: =?us-ascii?q?9a23=3ADYhdeRYUZ+vuqKSNrZ33cyL/LSx+4OfEezUN459i?= =?us-ascii?q?sYplN5qZr86ybnLW6fgltlLVR4KTs6sC17OM9fC6Ejxcqb+681k6OKRWUBEEjc?= =?us-ascii?q?hE1ycBO+WiTXPBEfjxciYhF95DXlI2t1uyMExSBdqsLwaK+i764jEdAAjwOhRo?= =?us-ascii?q?LerpBIHSk9631+ev8JHPfglEnjWwba5sIBmsrgjdqMYajIhtJ60s1hbHv3xEdv?= =?us-ascii?q?hMy2h1P1yThRH85smx/J5n7Stdvu8q+tBDX6vnYak2VKRUAzs6PW874s3rrgTD?= =?us-ascii?q?QhCU5nQASGUWkwFHDBbD4RrnQ5r+qCr6tu562CmHIc37SK0/VDq+46t3ThLjlT?= =?us-ascii?q?wKPCAl/m7JlsNwjbpboBO/qBx5347Ue5yeOP5ncq/AYd8WWW9NU8BMXCJDH4y8?= =?us-ascii?q?dZMCAPYOMuhFr4fypVUAoxiwBQeyA+3i0SVHimPz3aAg0+QtDQHL0Qo9FNwOqn?= =?us-ascii?q?TUq9D1Ob8WX+Cy0KbH0zHDbvNQ2Tjl9YbPaAohofaQXbltdsfRy04vGB/bgVWU?= =?us-ascii?q?qY3lOSmZ1v8TvGiB6OpgSfmii3M7pA5ruDSvyN0sh5DPi4kIxF7E8iB5z5w0Jd?= =?us-ascii?q?2+UEN7bt+kEIdQtyGHLIR6WN8tQ2ZtuCs817YIuoa7cTAXxJkjyRPTcfOKfoyS?= =?us-ascii?q?7h7+SeqcIy10iGx4dL6nhBu/8lKsxvD9W8S7ylpHqjRJnsPSun0NyxDe7NWMRO?= =?us-ascii?q?Fn8Ue7wzmP0hje6uFaLkAwkqrWM5shwqIqmZYPr0jPBDL2l1jsg6+TbEok++yo?= =?us-ascii?q?5/7pYrX8vpOcNol0hR/iMqk2h8CyBeo1PhIBUmWf4+iwyaDv8E/jTLlUk/E6iq?= =?us-ascii?q?zZv4rbJcQfqK65GQhV0oM75ha9CDepzMoXnX0HLVJDYh6HlJbmO0vJIPDkFvq/?= =?us-ascii?q?nkijny1xy/DIJL3tGo/NIWTbkLf9YbZ97FZRxxYpwtBa45JYE7UBIPPoWk/tr9?= =?us-ascii?q?HYFR84Mwmsw+n9Etl914UeWXiOAqCDKq/Sv0WItaoTJLyjbYUPuTv5Y8Mu5/P0?= =?us-ascii?q?gGVxzVAUd7Oo0J9Rc3u4E+5rOW2WZHPthpEKFmJc7SQkS+m/qlqJXDpCYUGJ3r?= =?us-ascii?q?g7+nlvCoWtAIPSQMa2jaaGwA+mFZQQaHoQWQPEKmvha4jRA6REUymVOMI012Vc?= =?us-ascii?q?DeHwGb9k7gmnsUrB85QiK+PV/iMCspezhsV+7qvdj0NrrGEmP4Gmy2iIClpMsC?= =?us-ascii?q?YISjsxhfAtpFB0kg3FzKRxhvVZEZpd/aERC1toBdvn1+V/TuvKdEfZZN7ZGkut?= =?us-ascii?q?S5OoG2NpQw=3D=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0C/CAAyyDldhxV1McFmHAEBAQQBAQcEA?= =?us-ascii?q?QGBZ4EVgW8DUAEwKo0ZiBeBaiWDZIVwkScJAQMBDCMMAQGEQAKCXhsHAQQ0EwE?= =?us-ascii?q?DAQEEAQECAQMDARMBAQEKCwkIKYUlDII6KQGCZgEBAQECAScZAQE3AQQLCxggD?= =?us-ascii?q?iE2BhODIgGBagMOEwEKrGKBcDOCegEBBYJHgkENgh4DBoE0i2CCFoERJwwTgh4?= =?us-ascii?q?uPoIaLhkCAoIMgxCCJowlnWMtQAcCgTJqhlmIbAVPhBKNN4pVjFuIKYF1iwuDM?= =?us-ascii?q?4EvOEuBLnRMKgGCQT6CBAwOCRSDOoE+iRc+ATGOWwEB?= X-IPAS-Result: =?us-ascii?q?A0C/CAAyyDldhxV1McFmHAEBAQQBAQcEAQGBZ4EVgW8DUAE?= =?us-ascii?q?wKo0ZiBeBaiWDZIVwkScJAQMBDCMMAQGEQAKCXhsHAQQ0EwEDAQEEAQECAQMDA?= =?us-ascii?q?RMBAQEKCwkIKYUlDII6KQGCZgEBAQECAScZAQE3AQQLCxggDiE2BhODIgGBagM?= =?us-ascii?q?OEwEKrGKBcDOCegEBBYJHgkENgh4DBoE0i2CCFoERJwwTgh4uPoIaLhkCAoIMg?= =?us-ascii?q?xCCJowlnWMtQAcCgTJqhlmIbAVPhBKNN4pVjFuIKYF1iwuDM4EvOEuBLnRMKgG?= =?us-ascii?q?CQT6CBAwOCRSDOoE+iRc+ATGOWwEB?= X-IronPort-AV: E=Sophos;i="5.64,307,1559512800"; d="scan'208,217";a="314712156" X-MGA-submission: =?us-ascii?q?MDEPIQT8WPtbfxksd9pu3GH6/dvOQy48FNUWTT?= =?us-ascii?q?/v9NL3zcxE0gIeSNVEoHn0FooYuKMHVYqymAW99Dw/rCoQsa7OMYDpSb?= =?us-ascii?q?7N3D65+luICu6lT7OC0DGVGw44mzA1rshd2aOSy/YLlPAMpSuAmllleg?= =?us-ascii?q?InojuM4tH1vPwdJ4/Ck2LXrA=3D=3D?= Received: from mta02.udamail.fr ([193.49.117.21]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 25 Jul 2019 17:20:48 +0200 Received: from mta02.udamail.fr (localhost.localdomain [127.0.0.1]) by mta02.udamail.fr (Postfix) with ESMTPS id 45vbWd6kQ2zBsDZ; Thu, 25 Jul 2019 17:20:45 +0200 (CEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by mta02.udamail.fr (Postfix) with ESMTP id 45vbWd65hrzBsDX; Thu, 25 Jul 2019 17:20:45 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.10.3 mta02.udamail.fr 45vbWd65hrzBsDX DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uca.fr; s=72FD7F0C-5358-11E8-A3B7-17E0B3BFED1B; t=1564068045; bh=lZFBlwc5fqPwImhQkRGK7j/Y/uA1mFKtcdq1fca1fXc=; h=Mime-Version:From:Date:Message-Id:To; b=Bj4VgBxeDRUDtQy0JYa8CKwalptH8/1lOmi7TFY3bRKOKVk/QrVmIoB00tOCL1/YH QFifVNHeX0K6v+/9DVZjhQV7xpT1VM8C8NxhCdPIL1zmMta8idU6B/e7Ap1ijqcx+o hl4Fv2zUvmD3Sxp55IWxdSJA64+kNocAlhXjmfmo= X-Virus-Scanned: amavisd-new at mta02.udamail.fr Received: from mta02.udamail.fr ([127.0.0.1]) by localhost (mta02.udamail.fr [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id qWIo0eu4feyD; Thu, 25 Jul 2019 17:20:45 +0200 (CEST) Received: from proxy01.udamail.fr (unknown [193.49.117.26]) by mta02.udamail.fr (Postfix) with ESMTPS id 45vbWd4nrGzBsDW; Thu, 25 Jul 2019 17:20:45 +0200 (CEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by proxy01.udamail.fr (Postfix) with ESMTP id 45vbWd49G0zBnBY; Thu, 25 Jul 2019 17:20:45 +0200 (CEST) Received: from proxy01.udamail.fr ([127.0.0.1]) by localhost (proxy01.udamail.fr [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id JQG5OCHGal_Z; Thu, 25 Jul 2019 17:20:44 +0200 (CEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by proxy01.udamail.fr (Postfix) with ESMTP id 45vbWc0WbNzBnBw; Thu, 25 Jul 2019 17:20:44 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.10.3 proxy01.udamail.fr 45vbWc0WbNzBnBw DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uca.fr; s=72FD7F0C-5358-11E8-A3B7-17E0B3BFED1B; t=1564068044; bh=lZFBlwc5fqPwImhQkRGK7j/Y/uA1mFKtcdq1fca1fXc=; h=Mime-Version:From:Date:Message-Id:To; b=bUoA9cNBZbYI2zRleO4zf7+/B8kNgG4ZCge56I7slbqr8tugMpWIR7kEOeCVP0P1+ kVDXn9yM0b5uDpVN5RspPJ8ITk9aV4wjz3wSIYB9zs/bHZQwgxlZq40HxH596zwK7Q WSlXGfbWWAFQDbQ7w9szaOx58wVeSGJ/03f+4Iq4= X-Virus-Scanned: amavisd-new at proxy01.udamail.fr Received: from proxy01.udamail.fr ([127.0.0.1]) by localhost (proxy01.udamail.fr [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id qehD0mgr_3eK; Thu, 25 Jul 2019 17:20:43 +0200 (CEST) Received: from [192.168.0.38] (lav63-2-88-164-92-250.fbx.proxad.net [88.164.92.250]) by proxy01.udamail.fr (Postfix) with ESMTPSA id 45vbWb24xjzBnBY; Thu, 25 Jul 2019 17:20:43 +0200 (CEST) Content-Type: multipart/alternative; boundary="Apple-Mail=_1B82EDD0-E023-4DF1-AF8F-DBF3BA409BB3" Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.6\)) From: =?iso-8859-1?Q?Jocelyn_S=E9rot?= In-Reply-To: Date: Thu, 25 Jul 2019 17:20:42 +0200 Cc: caml users Message-Id: <9D191A05-C9B7-4462-A7BB-BE705AF9E434@uca.fr> References: <6300BCD6-A188-46E1-BA13-D9ACBE80FD49@uca.fr> To: Gabriel Scherer X-Mailer: Apple Mail (2.1878.6) X-Validation-by: jocelyn.serot@uca.fr Subject: Re: [Caml-list] Camlp4-free implementation of stream parsers (was camlp4 & OCaml 4.08) Reply-To: =?iso-8859-1?Q?Jocelyn_S=E9rot?= X-Loop: caml-list@inria.fr X-Sequence: 17708 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: --Apple-Mail=_1B82EDD0-E023-4DF1-AF8F-DBF3BA409BB3 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=windows-1252 Thanks for the suggestion, Gabriel. It is indeed less tiresome that i had imagined. I attach the corresponding full code (with original camlp4 formulation = in comment). Handling of the minus operator is here handled before parsing; this is = not a problem since such a parser is supposed to be called on very small = strings in practice. Jocelyn ps : i=92m still wondering whether some library and/or ppx-based = generic (afap) implementation of Camlp4 stream parsers is possible.. 8<=97=97 Stream-based parser for simple arithmetic expressions (with = non-negative integers) type ident =3D string=20 type value =3D int=20 type t =3D=20 EConst of value (** Constants *) =20 | EVar of ident (** Input, output or local variable *) | EBinop of string * t * t (** Binary operation *) let keywords =3D ["+"; "-"; "*"; "/"; "("; ")"] let mk_binary_minus s =3D s |> String.split_on_char '-' |> String.concat = " - " =20 let lexer s =3D s |> mk_binary_minus |> Stream.of_string |> = Genlex.make_lexer keywords=20 open Genlex (* let rec p_exp0 =3D parser * | [< 'Int n >] -> EConst n * | [< 'Ident i >] -> EVar i * | [< 'Kwd "("; e=3Dp_exp ; 'Kwd ")" >] -> e *) let rec p_exp0 s =3D match Stream.next s with | Int n -> EConst n | Ident i -> EVar i | Kwd "(" -> let e =3D p_exp s in begin match Stream.peek s with | Some (Kwd ")") -> Stream.junk s; e | _ -> raise Stream.Failure end | _ -> raise Stream.Failure (* and p_exp1 =3D parser * | [< e1=3Dp_exp0 ; rest >] -> p_exp2 e1 rest *) and p_exp1 s =3D let e1 =3D p_exp0 s in p_exp2 e1 s =20 (* and p_exp2 e1 =3D parser * | [< 'Kwd "*"; e2=3Dp_exp1 >] -> EBinop("*", e1, e2) * | [< 'Kwd "/"; e2=3Dp_exp1 >] -> EBinop("/", e1, e2) * | [< >] -> e1 *) and p_exp2 e1 s =3D match Stream.peek s with | Some (Kwd "*") -> Stream.junk s; let e2 =3D p_exp1 s in EBinop("*", = e1, e2) | Some (Kwd "/") -> Stream.junk s; let e2 =3D p_exp1 s in EBinop("/", = e1, e2) | _ -> e1 =20 (* and p_exp =3D parser * | [< e1=3Dp_exp1 ; rest >] -> p_exp3 e1 rest *) and p_exp s =3D let e1 =3D p_exp1 s in p_exp3 e1 s =20 (* and p_exp3 e1 =3D parser * | [< 'Kwd "+"; e2=3Dp_exp >] -> EBinop("+", e1, e2) * | [< 'Kwd "-"; e2=3Dp_exp >] -> EBinop("-", e1, e2) * | [< >] -> e1 *) and p_exp3 e1 s =3D match Stream.peek s with | Some (Kwd "+") -> Stream.junk s; let e2 =3D p_exp s in EBinop("+", = e1, e2) | Some (Kwd "-") -> Stream.junk s; let e2 =3D p_exp s in EBinop("-", = e1, e2) | _ -> e1 let parse s =3D s |> lexer |> p_exp Le 25 juil. 2019 =E0 13:42, Gabriel Scherer = a =E9crit : > Hi, >=20 > The parser from = https://github.com/jserot/lascar/blob/master/src/lib/fsm_expr.ml seems = fairly trivial, have you considered just rewriting it to use the = functions of the Stream primitives directly? >=20 > For example, roughly (I have not tried to type-check or test the = code), >=20 > let rec aux =3D parser > | [< 'Int n when n<0; t=3Daux >] -> [< 'Kwd "-"; 'Int (-n); t >] > | [< 'h; t=3Daux >] -> [< 'h; t >] > | [< >] -> [< >] in >=20 > would become >=20 > let aux s =3D > let next =3D ref [] in > Stream.from @@ fun _ -> > match !next with > | tok::toks -> next :=3D toks; Some tok > | [] -> match Stream.next with > | exception Stream.Failure -> None > | Int n when n < 0 -> > next :=3D [Int (-n)]; > Some (Kwd "-") > | tok -> Some tok > =20 > and >=20 > let rec p_exp0 =3D parser > | [< 'Int n >] -> EConst n > | [< 'Ident i >] -> EVar i > | [< 'Kwd "("; e=3Dp_exp ; 'Kwd ")" >] -> e =20 >=20 > becomes >=20 > let rec p_exp0 s =3D match Stream.next s with > | Int n -> EConst n > | Ident i -> EVar i > | Kwd "(" -> > let e =3D p_exp s in > match Stream.peek s with > | Some (Kwd ")") -> Stream.junk s; e > | _ -> raise Stream.Failure >=20 > This is not exactly exciting code to write, but it's not a lot of work = either for such a simple grammar. >=20 > On Thu, Jul 25, 2019 at 12:28 PM Jocelyn S=E9rot = wrote: > HI Daniil, >=20 > Thanks for the example. It clearly shows how to embed a = Menhir-specified parser into an existing program. >=20 > I still think, however that using Menhir for parsing arithmetic = expressions is a bit overkill. >=20 > I=92m having a look at Angstrom (and all the other parser combinator = libs cited on the corresp. page). > It seems simpler.=20 >=20 > Jocelyn >=20 > Le 24 juil. 2019 =E0 17:31, Daniil Baturin a = =E9crit : >=20 > > Hi Jocelyn, > >=20 > > I've completed the first version of my project, so now I can start > > looking into this again! > >=20 > > There's a third option: parser combinators like angstrom. > > My experience with Menhir is very positive though. After initial > > struggle, I came to like its new incremental API and declarative = error > > reporting. > >=20 > > Here's my parser for an extended BNF: > > Menhir grammar: > > https://github.com/dmbaturin/bnfgen/blob/master/src/bnf_parser.mly > > Parser driver that feeds it tokens: > > https://github.com/dmbaturin/bnfgen/blob/master/src/parse_bnf.ml > > Error messages: > > = https://github.com/dmbaturin/bnfgen/blob/master/src/bnf_parser.messages > > Error message module build: > > https://github.com/dmbaturin/bnfgen/blob/master/src/dune#L6-L8 > >=20 > > On 7/24/19 10:10 PM, Jocelyn S=E9rot wrote: > >> Hi Daniil (and everyone interested by the subject), > >>=20 > >> Did you have a closer look at this ?=20 > >>=20 > >> I=92m still hesitating between these three approaches for replacing = the implementation of the small arithm expression parser used in Lascar = [1] : > >>=20 > >> i. rewrite it using the basic fns provided by the Stream library = (pro: no additionnal dependency, cons: not so trivial..) > >>=20 > >> ii. replace camlp4 by camlp5 (pro: straightforward, cons: long term = maintainability of camlp5 (?))=20 > >>=20 > >> iii. rewrite it using ocamlex/menhir and embed it in the main code = (pro: =AB standard =BB soon; cons: a bit heavy) > >>=20 > >> Jocelyn > >>=20 > >> [1] = https://github.com/jserot/lascar/blob/master/src/lib/fsm_expr.ml, lines = 70=96112 > >>=20 > >> Le 2 juil. 2019 =E0 11:25, Daniil Baturin a = =E9crit : > >>=20 > >>> Hi Jocelyn, > >>> Camlp5 is still sort of maintained, but I don't think it's going = to be > >>> developed beyond compatibility updates. > >>> For syntax extensions, everyone is switching to PPX. > >>>=20 > >>> =46rom a quick look, it seems like the only bit of camlp4 you use = is > >>> stream expressions. > >>> This is one of the things PPX can't do (on purpose, since it = doesn't > >>> allow _arbitrary_ extensions), > >>> but I don't think just using streams directly is going to make = code much > >>> longer. > >>>=20 > >>> Or I missed some other camlp4 bits? > >>>=20 > >>> I'm ready to work on a patch if you are open to it. > >>>=20 > >>> On 7/2/19 1:44 PM, Jocelyn S=E9rot wrote: > >>>> Le 29 juin 2019 =E0 17:15, Daniil Baturin a = =E9crit : > >>>>=20 > >>>>> Perhaps we should make some coordinated effort to help them. > >>>>> I've just sent a pull request to the ocamldot maintainer that = enables > >>>>> the graphviz files parsing and printing modules > >>>>> to build and work with 4.08. The GTK parts have their own = issues. > >>>>> Next I'm going to look into LASCAR/RFSM (packages that interest = me first ;). > >>>>>=20 > >>>> Hi Daniil, > >>>>=20 > >>>> I=92ve been been thinking of removing the dependency of Lascar = and RFSM on camlp4 for a while. > >>>> Is switching to CamlP5 a good alternative ?=20 > >>>>=20 > >>>> Jocelyn > >>>>=20 > >>>>=20 > >>>=20 > >=20 > >=20 >=20 >=20 --Apple-Mail=_1B82EDD0-E023-4DF1-AF8F-DBF3BA409BB3 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=windows-1252 Thanks = for the suggestion, Gabriel.

It is indeed less = tiresome that i had imagined.

I attach the = corresponding full code (with original camlp4 formulation in = comment).
Handling of the minus operator is here handled = before parsing; this is not a problem since such a parser is supposed to = be called on very small strings in = practice.

Jocelyn

ps : = i=92m still wondering whether some library and/or ppx-based =  generic (afap) implementation of Camlp4 stream parsers is = possible..

8<=97=97 Stream-based parser for simple = arithmetic expressions (with non-negative = integers)

type ident =3D = string 

type value =3D int 

type t = =3D 
  EConst of value         =      (** Constants *)   
| EVar of ident   =              (** Input, output or = local variable *)
| EBinop of string * t * t     (** Binary = operation *)

let keywords =3D ["+"; "-"; "*"; "/"; "("; = ")"]

let mk_binary_minus s =3D s |> String.split_on_char = '-' |> String.concat " - "
            =           
let lexer s =3D s = |> mk_binary_minus |> Stream.of_string |> Genlex.make_lexer = keywords 

open Genlex

(* let rec p_exp0  =3D = parser
 *             =     | [< 'Int n >] -> EConst n
 *     =             | [< 'Ident i >] -> = EVar i
 *             =     | [< 'Kwd "("; e=3Dp_exp ; 'Kwd ")" >] -> e = *)

let rec p_exp0 s =3D
  match Stream.next s = with
    | Int n -> EConst n
    | Ident = i -> EVar i
    | Kwd "(" ->
      =  let e =3D p_exp s in
       begin match = Stream.peek s with
       | Some (Kwd ")") -> = Stream.junk s; e
       | _ -> raise = Stream.Failure
       end
    | _ = -> raise Stream.Failure

(* and p_exp1  =3D = parser
 *             | = [< e1=3Dp_exp0 ; rest >] -> p_exp2  e1 rest = *)

and p_exp1 s =3D
  let e1 =3D p_exp0 s = in
  p_exp2 e1 s
  
(* and p_exp2  e1 = =3D parser
 *             =    | [< 'Kwd "*"; e2=3Dp_exp1  >] -> EBinop("*", = e1, e2)
 *             =    | [< 'Kwd "/"; e2=3Dp_exp1  >] -> EBinop("/", = e1, e2)
 *             =    | [< >] -> e1 *)

and p_exp2 e1 s = =3D
  match Stream.peek s with
  | Some (Kwd = "*") -> Stream.junk s; let e2 =3D p_exp1 s in EBinop("*", e1, = e2)
  | Some (Kwd "/") -> Stream.junk s; let e2 =3D = p_exp1 s in EBinop("/", e1, e2)
  | _ -> e1
  
(* and p_exp  =3D = parser
 *            | = [< e1=3Dp_exp1 ; rest >] -> p_exp3  e1 rest = *)

and p_exp s =3D
  let e1 =3D p_exp1 s in p_exp3 e1 = s
                =      
(* and p_exp3  e1 =3D parser
 *     =            | [< 'Kwd "+"; e2=3Dp_exp =  >] -> EBinop("+", e1, e2)
 *         =        | [< 'Kwd "-"; e2=3Dp_exp  >] = -> EBinop("-", e1, e2)
 *           =      | [< >] -> e1 *)

and p_exp3 e1 s = =3D
  match Stream.peek s with
  | Some (Kwd = "+") -> Stream.junk s; let e2 =3D p_exp s in EBinop("+", e1, = e2)
  | Some (Kwd "-") -> Stream.junk s; let e2 =3D = p_exp s in EBinop("-", e1, e2)
  | _ -> e1

let parse s =3D s = |> lexer |> = p_exp


Le 25 juil. = 2019 =E0 13:42, Gabriel Scherer <gabriel.scherer@gmail.com>= ; a =E9crit :

Hi,

The = parser from = https://github.com/jserot/lascar/blob/master/src/lib/fsm_expr.ml = seems fairly trivial, have you considered just rewriting it to use the = functions of the Stream primitives = directly?

For example, roughly (I have not = tried to type-check or test the code),
=
    let rec aux =3D = parser
    | [< 'Int n when n<0; t=3Daux >] -> = [< 'Kwd "-"; 'Int (-n); t >]
    | [< 'h; t=3Daux = >] -> [< 'h; t >]
    | [< >] -> [< = >] in

would = become

    let aux s = =3D
      let next =3D ref [] in
    =   Stream.from @@ fun _ ->
        match = !next with
        | tok::toks -> next :=3D = toks; Some tok
        | [] -> match = Stream.next with
              =   | exception Stream.Failure -> None
      =           | Int n when n < 0 ->
  =                 next :=3D [Int = (-n)];
                  = Some (Kwd "-")
              =   | tok -> Some tok
 
and

    let rec p_exp0  =3D = parser
    | [< 'Int n >] -> EConst n
  =   | [< 'Ident i >] -> EVar i
    | [< 'Kwd = "("; e=3Dp_exp ; 'Kwd ")" >] -> e       =  

becomes

    let rec p_exp0 s =3D match = Stream.next s with
    | Int n -> EConst n
  =   | Ident i -> EVar i
    | Kwd "(" ->
  =     let e =3D p_exp s in
      match = Stream.peek s with
      | Some (Kwd ")") -> = Stream.junk s; e
      | _ -> raise = Stream.Failure

This is not exactly exciting = code to write, but it's not a lot of work either for such a simple = grammar.

On Thu, Jul 25, 2019 at 12:28 PM Jocelyn S=E9rot = <jocelyn.serot@uca.fr> = wrote:
HI Daniil,

Thanks for the example. It clearly shows how to embed a Menhir-specified = parser into an existing program.

I still think, however that using Menhir for parsing arithmetic = expressions is a bit overkill.

I=92m having a look at Angstrom (and all the other parser combinator = libs cited on the corresp. page).
It seems simpler.

Jocelyn

Le 24 juil. 2019 =E0 17:31, Daniil Baturin <daniil@baturin.org> a =E9crit :

> Hi Jocelyn,
>
> I've completed the first version of my project, so now I can = start
> looking into this again!
>
> There's a third option: parser combinators like angstrom.
> My experience with Menhir is very positive though. After = initial
> struggle, I came to like its new incremental API and declarative = error
> reporting.
>
> Here's my parser for an extended BNF:
> Menhir grammar:
> https://github.com/dmbaturin/bnfgen/blob/master/src/bnf_= parser.mly
> Parser driver that feeds it tokens:
> https://github.com/dmbaturin/bnfgen/blob/master/src/pars= e_bnf.ml
> Error messages:
> https://github.com/dmbaturin/bnfgen/blob/master/src/bnf_= parser.messages
> Error message module build:
> https://github.com/dmbaturin/bnfgen/blob/master/src/dune= #L6-L8
>
> On 7/24/19 10:10 PM, Jocelyn S=E9rot wrote:
>> Hi Daniil (and everyone interested by the subject),
>>
>> Did you have a closer look at this ?
>>
>> I=92m still hesitating between these three approaches for = replacing the implementation of the small arithm expression parser used = in Lascar [1] :
>>
>> i. rewrite it using the basic fns provided by the Stream = library (pro: no additionnal dependency, cons: not so trivial..)
>>
>> ii. replace camlp4 by camlp5 (pro: straightforward, cons: long = term maintainability of camlp5 (?))
>>
>> iii. rewrite it using ocamlex/menhir and embed it in the main = code (pro: =AB standard =BB soon; cons: a bit heavy)
>>
>> Jocelyn
>>
>> [1] https://github.com/jserot/lascar/blob/master/src/lib/fsm= _expr.ml, lines 70=96112
>>
>> Le 2 juil. 2019 =E0 11:25, Daniil Baturin <daniil@baturin.org> a =E9crit :
>>
>>> Hi Jocelyn,
>>> Camlp5 is still sort of maintained, but I don't think it's = going to be
>>> developed beyond compatibility updates.
>>> For syntax extensions, everyone is switching to PPX.
>>>
>>> =46rom a quick look, it seems like the only bit of camlp4 = you use is
>>> stream expressions.
>>> This is one of the things PPX can't do (on purpose, since = it doesn't
>>> allow _arbitrary_ extensions),
>>> but I don't think just using streams directly is going to = make code much
>>> longer.
>>>
>>> Or I missed some other camlp4 bits?
>>>
>>> I'm ready to work on a patch if you are open to it.
>>>
>>> On 7/2/19 1:44 PM, Jocelyn S=E9rot wrote:
>>>> Le 29 juin 2019 =E0 17:15, Daniil Baturin <daniil@baturin.org> a =E9crit :
>>>>
>>>>> Perhaps we should make some coordinated effort to = help them.
>>>>> I've just sent a pull request to the ocamldot = maintainer that enables
>>>>> the graphviz files parsing and printing modules
>>>>> to build and work with 4.08. The GTK parts have = their own issues.
>>>>> Next I'm going to look into LASCAR/RFSM (packages = that interest me first ;).
>>>>>
>>>> Hi Daniil,
>>>>
>>>> I=92ve been been thinking of removing the dependency of = Lascar and RFSM on camlp4 for a while.
>>>> Is switching to CamlP5 a good alternative ?
>>>>
>>>> Jocelyn
>>>>
>>>>
>>>
>
>



= --Apple-Mail=_1B82EDD0-E023-4DF1-AF8F-DBF3BA409BB3--