From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by yquem.inria.fr (Postfix) with ESMTP id 43AD8D176 for ; Sun, 31 Jul 2005 15:21:31 +0200 (CEST) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id j6VDLUCZ010943 for ; Sun, 31 Jul 2005 15:21:30 +0200 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id PAA19268 for ; Sun, 31 Jul 2005 15:21:29 +0200 (MET DST) Received: from mail.rsise.anu.edu.au (mail.rsise.anu.edu.au [150.203.208.4]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id j6VDLPxm030163 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO) for ; Sun, 31 Jul 2005 15:21:28 +0200 Received: from localhost (localhost [127.0.0.1]) by mail.rsise.anu.edu.au (Postfix) with ESMTP id A986B1EB4E for ; Sun, 31 Jul 2005 23:21:22 +1000 (EST) Received: from mail.rsise.anu.edu.au ([150.203.208.4]) by localhost (mail [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 02159-02 for ; Sun, 31 Jul 2005 23:21:22 +1000 (EST) Received: from pulp.rsise.anu.edu.au (pulp.rsise.anu.edu.au [150.203.208.49]) by mail.rsise.anu.edu.au (Postfix) with ESMTP id 871121E31D for ; Sun, 31 Jul 2005 23:21:21 +1000 (EST) Received: by pulp.rsise.anu.edu.au (Postfix, from userid 1560) id 4B5AD295F32; Sun, 31 Jul 2005 23:21:19 +1000 (EST) Date: Sun, 31 Jul 2005 23:21:19 +1000 From: Pietro Abate To: ocaml ml Subject: buidlExpressionParser Message-ID: <20050731132119.GA368@pulp.anu.edu.au> Mail-Followup-To: Pietro Abate , ocaml ml Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="T4sUOijqQbZv57TR" Content-Disposition: inline X-Operating-System: GNU/Linux X-Organization: Research School of Information Science and Engineering (Australian National University) User-Agent: Mutt/1.5.9i X-Virus-Scanned: by amavisd-new-20030616-p10 (Debian) at mail.rsise.anu.edu.au X-j-chkmail-Score: MSGID : 42ECD05A.000 on nez-perce : j-chkmail score : X : 0/20 1 X-j-chkmail-Score: MSGID : 42ECD055.002 on concorde : j-chkmail score : X : 0/20 1 X-Miltered: at nez-perce with ID 42ECD05A.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at concorde with ID 42ECD055.002 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; anu:01 parser:01 grammar:01 plexer:01 gmake:01 lexer:01 restrictive:01 tokens:01 lexer:01 ocamlfind:01 ocamlc:01 -pp:01 cmo:01 mlast:01 cmo:01 X-Attachments: name="datatype.ml" name="inputParser.ml" name="main.ml" 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 --T4sUOijqQbZv57TR Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi all, I'm trying to write a generic parser similar to the buidlExpressionParser in the haskel library (without using external libraries). I came up with a kind of hack that uses the grammar extension mechanism (attached). Is there a better way of doing this ? And an other question: at the moment I'm using ( Plexer.gmake () ) as a lexer, but I don't need it (too restrictive and doesn't lex tokens like "[]" ). Does anybody have an example on how to write a simple lexer that I can use instead ? :) p compile with: ocamlfind ocamlc -c -pp "camlp4o -I . pa_extend.cmo q_MLast.cmo " -I /usr/lib/ocaml/3.08.3/camlp4 datatype.ml inputParser.ml ocamlc /usr/lib/ocaml/3.08.3/camlp4/gramlib.cma datatype.cmo inputParser.cmo main.ml -- ++ Blog: http://blog.rsise.anu.edu.au/?q=pietro ++ ++ "All great truths begin as blasphemies." -George Bernard Shaw ++ Please avoid sending me Word or PowerPoint attachments. See http://www.fsf.org/philosophy/no-word-attachments.html --T4sUOijqQbZv57TR Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="datatype.ml" type t = Atom of string | And of t * t | Or of t * t | Not of t let rec string_of_formula = function |And(f1,f2) -> Printf.sprintf "(%s And %s)" (string_of_formula f1) (string_of_formula f2) |Or(f1,f2) -> Printf.sprintf "(%s Or %s)" (string_of_formula f1) (string_of_formula f2) |Not(f) -> Printf.sprintf "(Not %s)" (string_of_formula f) |Atom(s) -> s ;; let print s = print_endline (string_of_formula s) --T4sUOijqQbZv57TR Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="inputParser.ml" (*pp camlp4o -I . pa_extend.cmo q_MLast.cmo *) open Genlex let gram = Grammar.gcreate (Plexer.gmake ());; let expr_term = Grammar.Entry.create gram "expr_term";; let add_uconn op co = EXTEND expr_term: LEVEL "Simple" [[ $op$; x = expr_term -> co [x] ]]; END ;; let add_biconn lev op co = EXTEND expr_term: LEVEL $lev$ [[ x = expr_term; $op$; y = expr_term -> co [x;y] ]]; END ;; EXTEND GLOBAL : expr_term; expr_term: [ "One" LEFTA [ ] | "Two" RIGHTA [ ] | "Simple" NONA [ x = LIDENT -> Datatype.Atom x | "("; p = expr_term; ")" -> p ] ]; END let buildParser table = List.iter(function |"Simple",op,co -> add_uconn op co |lev,op,co -> add_biconn lev op co ) table; let loc = Token.dummy_loc in let _ = Grammar.Entry.print expr_term in fun s -> Grammar.Entry.parse expr_term (Stream.of_string s) ;; --T4sUOijqQbZv57TR Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="main.ml" open Datatype let inputparser = InputParser.buildParser [ ("Simple","~",(fun l -> Not(List.hd l)) ); ("One","&",(fun l -> And(List.hd l, List.hd(List.tl l))) ); ("One","v",(fun l -> Or(List.hd l, List.hd(List.tl l))) ); ] ;; let a = inputparser "a & ( c v ~ d)" in Datatype.print a --T4sUOijqQbZv57TR--