caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* buidlExpressionParser
@ 2005-07-31 13:21 Pietro Abate
  2005-07-31 23:39 ` [Caml-list] buidlExpressionParser skaller
  2005-08-12  7:07 ` Pietro Abate
  0 siblings, 2 replies; 5+ messages in thread
From: Pietro Abate @ 2005-07-31 13:21 UTC (permalink / raw)
  To: ocaml ml

[-- Attachment #1: Type: text/plain, Size: 979 bytes --]

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

[-- Attachment #2: datatype.ml --]
[-- Type: text/plain, Size: 507 bytes --]


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)

[-- Attachment #3: inputParser.ml --]
[-- Type: text/plain, Size: 918 bytes --]

(*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)
;;


[-- Attachment #4: main.ml --]
[-- Type: text/plain, Size: 302 bytes --]


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


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-08-12  7:08 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-31 13:21 buidlExpressionParser Pietro Abate
2005-07-31 23:39 ` [Caml-list] buidlExpressionParser skaller
2005-08-01  1:45   ` Pietro Abate
2005-08-01  8:13     ` skaller
2005-08-12  7:07 ` Pietro Abate

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).