caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: WEIL Daniel <Daniel.WEIL@3ds.com>
To: "caml-list@inria.fr" <caml-list@inria.fr>
Subject: [Caml-list] menhir and ocamlbuild :some small issues and correction proposal
Date: Fri, 29 Jul 2011 15:13:41 +0000	[thread overview]
Message-ID: <BB79AD1BA99F364E9AAB6645B73029AD3677A92A@EU-DCC-MBX01.dsone.3ds.com> (raw)

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

Hello,


I'm using ocamlbuild and menhir to compile my project. I was faced with some small issues and decided to try some small patches on the menhir source code, which I explain below.


1)      Error found with --infer options have bad location
When ocamlbuild invoke menhir to file which is in a sub-directory, ie launch the command "menhir --infer MyDir/MyParser.mly", if I have a type error in my parser, I get the message

File "MyParser.mly", line 32, characters 41-42: ...

Instead of

File "MyDir/MyParser.mly", line 32, characters 41-42: ...

I understand this is because in the generated file MyDir/MyParser.ml, the #line directives are written
                # 239 " MyParser.mly "
instead of
                # 239 "MyDir/MyParser.mly "

So I try to make a little change in menhir's source files. In file error.ml, I commented out the "Filename.basename" :
let set_filename name =
  basename := Some ((* Filename.basename  *)name);
  filemark := Mark.fresh()

and idem in back.ml :
let write program =
  let module P = Printer.Make (struct
    let filename = Settings.base ^ ".ml"
    let f = open_out filename
    let locate_stretches =
      if Settings.infer then
      (* Typechecking should not fail at this stage. Omit #line directives. *)
      None
      else
      Some ((* Filename.basename *) filename)
    let raw_stretch_action = false
  end) in
  P.program program

This is correct the issue but I do not know if it is the good correction. At least, this seems the way ocamlyacc works.


2)      Ocamlbuild, menhir and the -table option

Ocamlbuild fails is menhir is used with "-table" option because it does'nt link with the MenhirLib library (--table option is required when grammar becomes large). So I changed the two menhir's makefiles to generate .cma and .cmxa and create the following ocamlbuild's plugin:
open Ocamlbuild_plugin;;
open Command;;

let menhirLibDir () =
  Command.execute( Cmd (Sh "menhir --suggest-comp-flags --table > tmp.txt"));
  let path = match string_list_of_file ( "tmp.txt") with
    | [_;path] -> path
    | _ -> assert false in
  rm_f "tmp.txt";
  path
;;

dispatch begin function
| After_rules ->
  let menhirLibDir = menhirLibDir () in
  ocaml_lib ~extern:true ~dir:menhirLibDir ~tag_name:"use_menhir_table" "menhirLib";
  flag [ "ocaml" ; "menhir";"use_menhir_table" ] (S[A "--table"]);
| _ -> ()
end;;

and with the following _tags flag, it compiles:
<**/*.ml>: use_menhir_table
<**/*.mly>: explain, use_menhir_table
true: use_menhir
<**/*.{byte,native}>: use_menhir_table

Maybe could this changes be integrated in the official myocamlbuild source files ?



3)      Menhir (like ocamlyacc) only raise a warning when it finds  a shift/reduce or reduce/reduce conflict.

I propose to add an option "--conflict-is-error" which make menhir fail if it finds conflicts. Changes are very small in menhir source code. I have added the option in Setting.ml and change the "report statistic" code from


let () =
  if !shift_reduce = 1 then
    Error.warning "one state has shift/reduce conflicts."
  else if !shift_reduce > 1 then
    Error.warning (Printf.sprintf "%d states have shift/reduce conflicts." !shift_reduce);
  if !reduce_reduce = 1 then
    Error.warning "one state has reduce/reduce conflicts."
  else if !reduce_reduce > 1 then
    Error.warning (Printf.sprintf "%d states have reduce/reduce conflicts." !reduce_reduce)



to


let () =
  let print = if !Settings.conflict_is_error then (fun s -> Error.signalN [] ("Error: "^s)) else Error.warning in
  if !shift_reduce = 1 then
    print "one state has shift/reduce conflicts."
  else if !shift_reduce > 1 then
    print (Printf.sprintf "%d states have shift/reduce conflicts." !shift_reduce);
  if !reduce_reduce = 1 then
    print "one state has reduce/reduce conflicts."
  else if !reduce_reduce > 1 then
    print (Printf.sprintf "%d states have reduce/reduce conflicts." !reduce_reduce)


Could these patches be integrated in Menhir next release ?

Daniel Weil

PS : as the menhir-list doesn't seems to work, I'm using the caml-list.




This email and any attachments are intended solely for the use of the individual or entity to whom it is addressed and may be confidential and/or privileged.

If you are not one of the named recipients or have received this email in error,

(i) you should not read, disclose, or copy it,

(ii) please notify sender of your receipt by reply email and delete this email and all attachments,

(iii) Dassault Systemes does not accept or assume any liability or responsibility for any use of or reliance on this email.

For other languages, go to http://www.3ds.com/terms/email-disclaimer

[-- Attachment #2: Type: text/html, Size: 20568 bytes --]

                 reply	other threads:[~2011-07-29 15:14 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=BB79AD1BA99F364E9AAB6645B73029AD3677A92A@EU-DCC-MBX01.dsone.3ds.com \
    --to=daniel.weil@3ds.com \
    --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;
as well as URLs for NNTP newsgroup(s).