Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add (explain) field to (menhir) stanza #9512

Merged
merged 20 commits into from
Dec 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions bin/printenv.ml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ let dump sctx ~dir =
let module Link_flags = Dune_rules.Link_flags in
let module Ocaml_flags = Dune_rules.Ocaml_flags in
let module Js_of_ocaml = Dune_rules.Js_of_ocaml in
let module Menhir_env = Dune_rules.Menhir_env in
let node = Super_context.env_node sctx ~dir in
let open Memo.O in
let ocaml_flags = node >>= Env_node.ocaml_flags in
let foreign_flags = node >>| Env_node.foreign_flags in
let link_flags = node >>= Env_node.link_flags in
let menhir_flags = node >>| Env_node.menhir_flags in
let menhir = node >>= Env_node.menhir in
let coq_flags = node >>= Env_node.coq_flags in
let js_of_ocaml = node >>= Env_node.js_of_ocaml in
let open Action_builder.O in
Expand All @@ -30,8 +31,8 @@ let dump sctx ~dir =
let* link_flags = Action_builder.of_memo link_flags in
Link_flags.dump link_flags
and+ menhir_dump =
let+ flags = Action_builder.of_memo_join menhir_flags in
[ "menhir_flags", flags ] |> List.map ~f:Dune_lang.Encoder.(pair string (list string))
let* env = Action_builder.of_memo menhir in
Menhir_env.dump env
and+ coq_dump = Action_builder.of_memo_join coq_flags >>| Dune_rules.Coq.Coq_flags.dump
and+ jsoo_dump =
let* jsoo = Action_builder.of_memo js_of_ocaml in
Expand Down
6 changes: 6 additions & 0 deletions doc/changes/9512.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- Menhir: generate `.conflicts` file by default. Add new field to the `(menhir)`
stanza to control the generation of this file: `(explain <blang expression>)`.
Introduce `(menhir (flags ...) (explain ...))` field in the `(env)` stanza,
delete `(menhir_flags)` field. All changes are guarded under a new version of
the Menhir extension, 3.0.
(#9512, @nojb)
8 changes: 7 additions & 1 deletion doc/stanzas/env.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@ Fields supported in ``<settings>`` are:
variables to the environment where the build commands are executed and are
used by ``dune exec``.

- ``(menhir_flags <flags>))`` specifies flags for Menhir stanzas.
- ``(menhir_flags <flags>))`` specifies flags for Menhir stanzas. This flag was
replaced by the ``(menhir)`` field (see below) starting in version 3.0 of the
Menhir extension.

- ``(menhir (flags <flags) (explain <blang expression>))`` specifies the Menhir
settings. See `menhir`_ for more details. This field was introduced in version
3.0 of the Menhir extension.

- ``(js_of_ocaml (flags <flags>)(build_runtime <flags>)(link_flags <flags>))``
specifies ``js_of_ocaml`` flags. See `jsoo-field`_ for more details.
Expand Down
10 changes: 10 additions & 0 deletions doc/stanzas/menhir.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,14 @@ Menhir supports writing the grammar and automation to the ``.cmly`` file.
Therefore, if this is flag is passed to Menhir, Dune will know to introduce a
``.cmly`` target for the module.

- ``(explain <blang expression>)`` is used to control the generation of the
``.conflicts`` file explaining conflicts found while generating the
parser. The condition is specified using the
:doc:`reference/boolean-language`. This field was introduced in version 3.0 of
the Menhir extension.

Note that starting in version 3.0 of the Menhir extension, the ``.conflicts``
file is generated by default. If this is not desired, it needs to be disabled
explicitly by using the ``(explain)`` field.

.. _menhir-git: https://gitlab.inria.fr/fpottier/menhir
12 changes: 12 additions & 0 deletions src/dune_lang/blang.ml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ module Ast = struct
let true_ = Const true
let false_ = Const false

let rec equal f t1 t2 =
match t1, t2 with
| Const b1, Const b2 -> Bool.equal b1 b2
| Not t1, Not t2 -> equal f t1 t2
| Expr x1, Expr x2 -> f x1 x2
| And tl1, And tl2 | Or tl1, Or tl2 -> List.equal (equal f) tl1 tl2
| Compare (op1, x1, y1), Compare (op2, x2, y2) ->
Relop.equal op1 op2 && f x1 x2 && f y1 y2
| (Const _ | Not _ | Expr _ | And _ | Or _ | Compare _), _ -> false
;;

let rec to_dyn string_to_dyn =
let open Dyn in
function
Expand Down Expand Up @@ -72,3 +83,4 @@ let false_ = Ast.false_
let to_dyn = Ast.to_dyn String_with_vars.to_dyn
let decode = Ast.decode String_with_vars.decode
let encode = Ast.encode String_with_vars.encode
let equal = Ast.equal String_with_vars.equal
1 change: 1 addition & 0 deletions src/dune_lang/blang.mli
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ val false_ : t
val to_dyn : t -> Dyn.t
val decode : t Decoder.t
val encode : t Encoder.t
val equal : t -> t -> bool

module Ast : sig
type 'string t = 'string ast
Expand Down
39 changes: 28 additions & 11 deletions src/dune_rules/dune_env.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ let foreign_flags ~since =
Foreign_language.Dict.make ~c ~cxx
;;

let menhir_flags ~since =
let menhir_flags ~since ~deleted_in =
let decode =
let decode = Ordered_set_lang.Unexpanded.decode in
match since with
| None -> decode
| Some since -> Dune_lang.Syntax.since Menhir_stanza.syntax since >>> decode
Dune_lang.Syntax.since Menhir_stanza.syntax since
>>> Dune_lang.Syntax.deleted_in
~extra_info:"Use (menhir (flags ...)) instead."
Menhir_stanza.syntax
deleted_in
>>> Ordered_set_lang.Unexpanded.decode
in
field_o "menhir_flags" decode
;;
Expand Down Expand Up @@ -75,7 +77,7 @@ type config =
; env_vars : Env.t
; binaries : File_binding.Unexpanded.t list option
; inline_tests : Inline_tests.t option
; menhir_flags : Ordered_set_lang.Unexpanded.t option
; menhir : Ordered_set_lang.Unexpanded.t Menhir_env.t
; odoc : Odoc.t
; js_of_ocaml : Ordered_set_lang.Unexpanded.t Js_of_ocaml.Env.t
; coq : Coq_env.t
Expand All @@ -97,7 +99,7 @@ let equal_config
; env_vars
; binaries
; inline_tests
; menhir_flags
; menhir
; odoc
; js_of_ocaml
; coq
Expand All @@ -117,7 +119,7 @@ let equal_config
&& Env.equal env_vars t.env_vars
&& Option.equal (List.equal File_binding.Unexpanded.equal) binaries t.binaries
&& Option.equal Inline_tests.equal inline_tests t.inline_tests
&& Option.equal Ordered_set_lang.Unexpanded.equal menhir_flags t.menhir_flags
&& Menhir_env.equal menhir t.menhir
&& Odoc.equal odoc t.odoc
&& Coq_env.equal coq t.coq
&& Option.equal Format_config.equal format_config t.format_config
Expand All @@ -136,7 +138,7 @@ let empty_config =
; env_vars = Env.empty
; binaries = None
; inline_tests = None
; menhir_flags = None
; menhir = Menhir_env.empty
; odoc = Odoc.empty
; js_of_ocaml = Js_of_ocaml.Env.empty
; coq = Coq_env.default
Expand Down Expand Up @@ -209,6 +211,12 @@ let odoc_field =
(Dune_lang.Syntax.since Stanza.syntax (2, 4) >>> Odoc.decode)
;;

let menhir_field ~since =
field_o
"menhir"
(Dune_lang.Syntax.since Menhir_stanza.syntax since >>> Menhir_env.decode)
;;

let js_of_ocaml_field =
field
"js_of_ocaml"
Expand All @@ -229,19 +237,28 @@ let config =
"binaries"
(Dune_lang.Syntax.since Stanza.syntax (1, 6) >>> File_binding.Unexpanded.L.decode)
and+ inline_tests = inline_tests_field
and+ menhir_flags = menhir_flags ~since:(Some (2, 1))
and+ menhir = menhir_field ~since:Menhir_stanza.explain_since
and+ menhir_flags = menhir_flags ~since:(2, 1) ~deleted_in:Menhir_stanza.explain_since
and+ odoc = odoc_field
and+ js_of_ocaml = js_of_ocaml_field
and+ coq = Coq_env.decode
and+ format_config = Format_config.field ~since:(2, 8)
and+ bin_annot = bin_annot in
let menhir =
match menhir_flags, menhir with
| Some flags, None -> { Menhir_env.empty with flags }
| None, Some env -> env
| None, None -> Menhir_env.empty
| Some _, Some _ ->
Code_error.raise "(menhir_flags) and (menhir) cannot both be present" []
in
{ flags
; foreign_flags
; link_flags
; env_vars
; binaries
; inline_tests
; menhir_flags
; menhir
; odoc
; js_of_ocaml
; coq
Expand Down
2 changes: 1 addition & 1 deletion src/dune_rules/dune_env.mli
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type config =
; env_vars : Env.t
; binaries : File_binding.Unexpanded.t list option
; inline_tests : Inline_tests.t option
; menhir_flags : Ordered_set_lang.Unexpanded.t option
; menhir : Ordered_set_lang.Unexpanded.t Menhir_env.t
; odoc : Odoc.t
; js_of_ocaml : Ordered_set_lang.Unexpanded.t Js_of_ocaml.Env.t
; coq : Coq_env.t
Expand Down
1 change: 1 addition & 0 deletions src/dune_rules/dune_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Env_node = Env_node
module Link_flags = Link_flags
module Ocaml_flags = Ocaml_flags
module Js_of_ocaml = Js_of_ocaml
module Menhir_env = Menhir_env
module Super_context = Super_context
module Compilation_context = Compilation_context
module Colors = Colors
Expand Down
25 changes: 13 additions & 12 deletions src/dune_rules/env_node.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ type t =
; link_flags : Link_flags.t Memo.Lazy.t
; external_env : Env.t Memo.Lazy.t
; artifacts : Artifacts.t Memo.Lazy.t
; menhir_flags : string list Action_builder.t Memo.Lazy.t
; menhir : string list Action_builder.t Menhir_env.t Memo.Lazy.t
; js_of_ocaml : string list Action_builder.t Js_of_ocaml.Env.t Memo.Lazy.t
; coq_flags : Coq_flags.t Action_builder.t Memo.Lazy.t
}
Expand All @@ -21,7 +21,7 @@ let link_flags t = Memo.Lazy.force t.link_flags
let external_env t = Memo.Lazy.force t.external_env
let artifacts t = Memo.Lazy.force t.artifacts
let js_of_ocaml t = Memo.Lazy.force t.js_of_ocaml
let menhir_flags t = Memo.Lazy.force t.menhir_flags |> Action_builder.of_memo_join
let menhir t = Memo.Lazy.force t.menhir
let coq_flags t = Memo.Lazy.force t.coq_flags

let expand_str_lazy expander sw =
Expand Down Expand Up @@ -139,16 +139,17 @@ let make
~default:link_flags
~eval:(Expander.expand_and_eval_set expander))
in
let menhir_flags =
let menhir =
inherited
~field:(fun t -> Memo.return (menhir_flags t))
~root:(Action_builder.return [])
(fun flags ->
match config.menhir_flags with
| None -> Memo.return flags
| Some menhir_flags ->
let+ expander = Memo.Lazy.force expander in
Expander.expand_and_eval_set expander menhir_flags ~standard:flags)
~field:menhir
~root:(Menhir_env.map ~f:Action_builder.return Menhir_env.default)
(fun (menhir : _ Action_builder.t Menhir_env.t) ->
let local = config.menhir in
let+ expander = Memo.Lazy.force expander in
let flags =
Expander.expand_and_eval_set expander local.flags ~standard:menhir.flags
in
{ Menhir_env.flags; explain = Option.first_some local.explain menhir.explain })
in
let coq_flags : Coq_flags.t Action_builder.t Memo.Lazy.t =
inherited
Expand Down Expand Up @@ -178,7 +179,7 @@ let make
; artifacts
; local_binaries
; js_of_ocaml
; menhir_flags
; menhir
; coq_flags
}
;;
2 changes: 1 addition & 1 deletion src/dune_rules/env_node.mli
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ val local_binaries : t -> File_binding.Expanded.t list Memo.t

val artifacts : t -> Artifacts.t Memo.t
val coq_flags : t -> Coq_flags.t Action_builder.t Memo.t
val menhir_flags : t -> string list Action_builder.t
val menhir : t -> string list Action_builder.t Menhir_env.t Memo.t
34 changes: 34 additions & 0 deletions src/dune_rules/menhir/menhir_env.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
open Import

type 'a t =
{ flags : 'a
; explain : Blang.t option
}

let map ~f t = { t with flags = f t.flags }

let equal { flags; explain } t =
Ordered_set_lang.Unexpanded.equal flags t.flags
&& Option.equal Blang.equal explain t.explain
;;

let decode =
let open Dune_lang.Decoder in
fields
@@ let+ flags = Ordered_set_lang.Unexpanded.field "flags"
and+ explain = field_o "explain" Blang.decode in
{ flags; explain }
;;

let empty = { flags = Ordered_set_lang.Unexpanded.standard; explain = None }
let default = { flags = []; explain = None }

let dump t =
let open Action_builder.O in
let+ flags = t.flags in
List.map
~f:Dune_lang.Encoder.(pair string Fun.id)
[ "menhir_flags", Dune_lang.Encoder.(list string) flags
; "menhir_explain", Dune_lang.Encoder.option Blang.encode t.explain
]
;;
13 changes: 13 additions & 0 deletions src/dune_rules/menhir/menhir_env.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
open Import

type 'a t =
{ flags : 'a
; explain : Blang.t option
}

val map : f:('a -> 'b) -> 'a t -> 'b t
val equal : Ordered_set_lang.Unexpanded.t t -> Ordered_set_lang.Unexpanded.t t -> bool
val decode : Ordered_set_lang.Unexpanded.t t Dune_lang.Decoder.t
val empty : Ordered_set_lang.Unexpanded.t t
val default : string list t
val dump : string list Action_builder.t t -> Dune_lang.t list Action_builder.t
Loading
Loading