;; Build the stage2 version of Menhir. During this stage, Menhir's parser
;; is generated by the stage1 Menhir executable.
;; -----------------------------------------------------------------------------
;; The flags that are passed to every invocation of Menhir in the rules below
;; are set in the file "menhir_flags". Any flags that affect the construction
;; of the automaton, such as --canonical, *must* be listed there.
;; We need these flags in "s-expression" format in order to use them in the
;; "menhir" stanza below. The following rule generates a file in this format
;; by wrapping the list of arguments in parentheses.
(rule
(with-stdout-to menhir_flags.sexp
(progn
(echo "(")
(cat %{dep:menhir_flags})
(echo ")")
)
)
)
;; -----------------------------------------------------------------------------
;; Bind the name "menhir" to "../stage1/main.exe" within the present scope.
;; This is so that the "menhir" stanza below will use *that* executable
;; instead of whatever "menhir" executable (if any) is available on the
;; developer's machine.
(env
(_ (binaries ../stage1/main.exe (../stage1/main.exe as menhir)))
)
;; Menhir's parser is generated by Menhir.
;; We include the flags found in the file "menhir_flags" plus extra flags
;; specified here.
(menhir
(flags
(:include menhir_flags.sexp)
-lg 1 -la 1 -lc 1
-v
)
(modules parser)
)
;; -----------------------------------------------------------------------------
;; As dune cannot use the same OCaml module in two different libraries or
;; executables, we must copy the source files to the present directory.
(copy_files# ../*.{ml,mli})
;; -----------------------------------------------------------------------------
;; The stage2 version of Menhir. The stanza is identical to that used for the
;; stage1 version, but the [Driver] and [Parser] modules are different.
;; The link_deps field requires running the completeness check.
(executable
(name main)
(libraries
unix
vendored_fix
vendored_pprint
menhirLib menhirSdk
)
(flags :standard -open MenhirSdk)
(link_deps parserMessages.check)
)
;; -----------------------------------------------------------------------------
;; Install the Menhir executable under the "menhir" name. This would usually
;; be achieved by adding a "public_name" field in the "executable" stanza
;; above. However, we cannot do that here, because the public name "menhir"
;; would clash with the binding of this name to the stage1 version of Menhir
;; at the top of this file. Thus, we explicitly request its installation as
;; follows.
(install
(section bin)
(package menhir)
(files (./main.exe as menhir))
)
;; -----------------------------------------------------------------------------
;; This section deals with the .messages file.
;; The module [ParserMessages] is generated by Menhir based on the source file
;; "parserMessages.messages". The completeness check is performed first.
(rule
(deps parserMessages.check)
(action (with-stdout-to parserMessages.ml
(run menhir
%{read-lines:menhir_flags}
%{dep:parser.mly}
--compile-errors %{dep:parserMessages.messages}
)
))
)
;; In order to perform the completeness check, we must first generate a file
;; "parserMessages.auto.messages" that contains a list of all error states.
(rule
(with-stdout-to parserMessages.auto.messages
(run menhir
%{read-lines:menhir_flags}
%{dep:parser.mly}
--list-errors
)
)
)
;; The completeness check verifies that all error messages are listed in the
;; ".messages" file. It compares the ".messages" file with that generated by
;; Menhir using the above rule.
(rule
(with-stdout-to parserMessages.check
(run menhir
%{read-lines:menhir_flags}
%{dep:parser.mly}
--compare-errors %{dep:parserMessages.auto.messages}
--compare-errors %{dep:parserMessages.messages}
))
)
;; -----------------------------------------------------------------------------
;; The following rule is used under the programmer's manual control,
;; after the grammar in [src/stage2/parser.mly] has been modified.
;; This rule updates the file [parserMessages.messages] with new
;; auto-generated comments for all error states.
;; It is invoked by running [make update] in the directory src/.
(rule
(with-stdout-to parserMessages.messages.updated
(run menhir
%{read-lines:menhir_flags}
--update-errors %{dep:parserMessages.messages}
%{dep:parser.mly}
)
)
)