From: Pietro Abate <Pietro.Abate@anu.edu.au>
To: ocaml ml <caml-list@inria.fr>
Subject: buidlExpressionParser
Date: Sun, 31 Jul 2005 23:21:19 +1000 [thread overview]
Message-ID: <20050731132119.GA368@pulp.anu.edu.au> (raw)
[-- 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
next reply other threads:[~2005-07-31 13:21 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-07-31 13:21 Pietro Abate [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050731132119.GA368@pulp.anu.edu.au \
--to=pietro.abate@anu.edu.au \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox