From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of jocelyn.serot@uca.fr) identity=pra; client-ip=193.49.117.21; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="jocelyn.serot@uca.fr"; x-sender="jocelyn.serot@uca.fr"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of jocelyn.serot@uca.fr designates 193.49.117.21 as permitted sender) identity=mailfrom; client-ip=193.49.117.21; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="jocelyn.serot@uca.fr"; x-sender="jocelyn.serot@uca.fr"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mta02.udamail.fr) identity=helo; client-ip=193.49.117.21; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="jocelyn.serot@uca.fr"; x-sender="postmaster@mta02.udamail.fr"; x-conformance=sidf_compatible 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) --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 c= omment). 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 string= s 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-ne= gative integers) type ident =3D string=20 type value =3D int=20 type t =3D=20 EConst of value (** Constants *)=20=20=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=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20 let lexer s =3D s |> mk_binary_minus |> Stream.of_string |> Genlex.make_lex= er 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=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=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=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=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=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=20=20=20=20=20=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 ei= ther for such a simple grammar. >=20 > On Thu, Jul 25, 2019 at 12:28 PM Jocelyn S=E9rot w= rote: > 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 expressio= ns 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 th= e 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 ma= intainability of camlp5 (?))=20 > >>=20 > >> iii. rewrite it using ocamlex/menhir and embed it in the main code (pr= o: =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 =E9cr= it : > >>=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 > >>> From 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 m= uch > >>> 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 =E9= crit : > >>>>=20 > >>>>> Perhaps we should make some coordinated effort to help them. > >>>>> I've just sent a pull request to the ocamldot maintainer that enabl= es > >>>>> 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 R= FSM 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 suggest= ion, Gabriel.

It is indeed less tiresome that i had imag= ined.

I attach the corresponding full code (with o= riginal camlp4 formulation in comment).
Handling of the minus ope= rator is here handled before parsing; this is not a problem since such a pa= rser 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 o= f Camlp4 stream parsers is possible..

8<=97=97 Stream-based p= arser for simple arithmetic expressions (with non-negative integers)=
<= br>
type ident =3D string 

type value =3D int 

type t =3D 
  EConst of va= lue              (** Constants *)  =  
|= EVar of ident                (** I= nput, output or local variable *)
| EBinop of string * t * t     (** Bina= ry operation *)

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

let mk_binary_minus s =3D s |>= String.split_on_char '-' |> String.concat " - "
        &n= bsp;             
let lexer s =3D s |> mk_bin= ary_minus |> Stream.of_string |> Genlex.make_lexer keywords 

=
open Genlex

(* let rec p_= exp0  =3D parser
 *               &nbs= p; | [< 'Int n >] -> EConst n
 *           &= nbsp;     | [< 'Ident i >] -> EVar i
 *      = ;           | [< 'Kwd "("; e=3Dp_exp ; 'Kwd ")"= >] -> e *)

let rec p_exp0 s =3D
  match Stream.next s with
    | Int n -> EC= onst n
&= nbsp;   | Ident i -> EVar i
    | Kwd "(" ->
      &nbs= p;let e =3D p_exp s in
       begin match Stream.peek s with
  &nb= sp;    | Some (Kwd ")") -> Stream.junk s; e
       = ;| _ -> raise Stream.Failure
       end
    | _ -> rais= e Stream.Failure

(* and p_exp1  =3D parser
 *           &nb= sp; | [< 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 &n= bsp;>] -> EBinop("*", e1, e2)
 *           &nbs= p;    | [< 'Kwd "/"; e2=3Dp_exp1  >] -> EBinop("/",= e1, e2)
 *                | [< >= ;] -> e1 *)

and p_exp2 e1 s =3D
  match Stream.peek s with
  | Some (Kwd "*") -> Strea= m.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
  <= /font>
(* 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
                  &nb= sp;  
(* and p_exp3  e1 =3D parser
 *           &nb= sp;    | [< 'Kwd "+"; e2=3Dp_exp  >] -> EBinop("+",= e1, e2)
 *                | [< 'Kw= d "-"; e2=3Dp_exp  >] -> EBinop("-", e1, e2)
 *      = ;          | [< >] -> e1 *)
<= div style=3D"font-size: 11px;">
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,

<= /div>
The parser from https://github.com/jserot/lascar/blob/master/sr= c/lib/fsm_expr.ml seems fairly trivial, have you considered just rewrit= ing it to use the functions of the Stream primitives directly?
For example, roughly (I have not tried to type-check or test t= he code),
<= /table>

  &= nbsp; let rec aux =3D parser
    | [< 'Int n when n<0; t= =3Daux >] -> [< 'Kwd "-"; 'Int (-n); t >]
    | [&= lt; 'h; t=3Daux >] -> [< 'h; t >]
    | [< >= ] -> [< >] in
<= div>
would become

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

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

becomes
<= /span>

    let rec p_exp0 s =3D match Stream.next s wi= th
    | 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 e= xciting 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 pa= rser 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 c= ited 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/bn= fgen/blob/master/src/parse_bnf.ml
> Error messages:
> https://github.com/dmbat= urin/bnfgen/blob/master/src/bnf_parser.messages
> Error message module build:
> https://github.com/dmbaturin/bnfg= en/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 replacin= g 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 ter= m 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/jser= ot/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 :<= br> >>
>>> Hi Jocelyn,
>>> Camlp5 is still sort of maintained, but I don't think it's goi= ng to be
>>> developed beyond compatibility updates.
>>> For syntax extensions, everyone is switching to PPX.
>>>
>>> From a quick look, it seems like the only bit of camlp4 you us= e is
>>> stream expressions.
>>> This is one of the things PPX can't do (on purpose, since it d= oesn'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 maintain= er 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 La= scar and RFSM on camlp4 for a while.
>>>> Is switching to CamlP5 a good alternative ?
>>>>
>>>> Jocelyn
>>>>
>>>>
>>>
>
>



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