164 lines
6.2 KiB
Makefile
164 lines
6.2 KiB
Makefile
#**************************************************************************
|
|
#* *
|
|
#* OCaml *
|
|
#* *
|
|
#* Gabriel Scherer, projet Parsifal, INRIA Saclay *
|
|
#* *
|
|
#* Copyright 2018 Institut National de Recherche en Informatique et *
|
|
#* en Automatique. *
|
|
#* *
|
|
#* All rights reserved. This file is distributed under the terms of *
|
|
#* the GNU Lesser General Public License version 2.1, with the *
|
|
#* special exception on linking described in the file LICENSE. *
|
|
#* *
|
|
#**************************************************************************
|
|
|
|
# The rules in this Makefile use Menhir to rebuild the OCaml compiler
|
|
# parser. They are included in the main Makefile, so should be invoked
|
|
# directly, for example 'make promote-menhir'. They must be called
|
|
# after any modification to parsing/parser.mly, for the modification
|
|
# to affect the parser linked in the produced compiler:
|
|
#
|
|
# - promote-menhir builds the parser from parser.mly and stores it in
|
|
# the boot/ directory, so that future builds of the compiler use the
|
|
# updated result. Use it to make permanent changes to the compiler
|
|
# parser.
|
|
#
|
|
# - demote-menhir undoes the effect of promote-menhir. The files in
|
|
# the boot/ directory that are affected by promote-menhir and are
|
|
# under version control are restored to their normal state (HEAD).
|
|
#
|
|
# - test-menhir builds the parser from parser.mly without storing it
|
|
# in the boot/ directory, and only checks that the generated parser
|
|
# builds correctly. Use it to quickly check if a parser.mly change
|
|
# breaks the build. If you want to test a compiler produced with
|
|
# the new parser, you must use promote-menhir instead.
|
|
# (Using this rule requires a partial compiler build as obtained
|
|
# by 'make core' or 'make world'.)
|
|
#
|
|
# - clean-menhir removes the files generated by Menhir from parsing/,
|
|
# keeping only the reference sources for the grammar.
|
|
#
|
|
# - depend-menhir updates the dependency information for the
|
|
# Menhir-generated parser, which is versioned in the OCaml repository
|
|
# like all other .depend files. It should be used when the dependencies
|
|
# (of the OCaml code in the grammar semantic actions) change.
|
|
|
|
MENHIR ?= menhir
|
|
|
|
## Unused tokens
|
|
|
|
# tokens COMMENT, DOCSTRING and EOL are produced by special lexer
|
|
# modes used by other consumers than the parser.
|
|
|
|
# GREATERBRACKET ">]" was added by the parser by symmetry with "[<"
|
|
# (which is used in polymorphic variant), but is not currently used by
|
|
# the grammar.
|
|
|
|
unused_tokens := COMMENT DOCSTRING EOL GREATERRBRACKET
|
|
|
|
## Menhir compilation flags
|
|
|
|
MENHIRFLAGS := --explain --dump --ocamlc "$(CAMLC) $(COMPFLAGS)" --infer \
|
|
--lalr --strict --table -lg 1 -la 1 \
|
|
$(addprefix --unused-token ,$(unused_tokens)) --fixed-exception
|
|
|
|
## promote-menhir
|
|
|
|
.PHONY: promote-menhir
|
|
promote-menhir: parsing/parser.mly
|
|
@ $(MAKE) import-menhirLib
|
|
$(MENHIR) $(MENHIRFLAGS) parsing/parser.mly
|
|
# The generated parser.ml may contain lexer directives containing
|
|
# the absolute path to Menhir's standard library on the promoter's machine.
|
|
# This is benign but will generate pointless churn if another developer
|
|
# rebuilds the same grammar (from the same Menhir version).
|
|
@ for f in $(addprefix parser.,ml mli) ; do \
|
|
sed \
|
|
's,^#\(.*\)"[^"]*/menhir/standard.mly",#\1"menhir/standard.mly",g' \
|
|
parsing/$$f \
|
|
> boot/menhir/$$f; \
|
|
rm parsing/$$f; \
|
|
done
|
|
|
|
# The import-menhirLib invocation in promote-menhir ensures that each
|
|
# update of the boot/ parser is paired with an update of the imported
|
|
# menhirLib; otherwise it would be easy to generate a parser and keep
|
|
# an incompatible version of menhirLib, which would fail at
|
|
# compile-time.
|
|
|
|
.PHONY: import-menhirLib
|
|
import-menhirLib:
|
|
@ mkdir -p boot/menhir
|
|
@ cp \
|
|
$(addprefix `$(MENHIR) --suggest-menhirLib`/menhirLib.,ml mli) \
|
|
boot/menhir
|
|
|
|
|
|
## demote-menhir
|
|
|
|
DEMOTE:=menhirLib.ml menhirLib.mli parser.ml parser.mli
|
|
|
|
.PHONY: demote-menhir
|
|
demote-menhir:
|
|
git checkout HEAD -- $(addprefix boot/menhir/,$(DEMOTE))
|
|
|
|
## test-menhir
|
|
|
|
# This rule assumes that the `parsing/` sources and its dependencies
|
|
# have already been compiled; 'make core' suffices to be in that
|
|
# state. We don't make 'core' an explicit dependency, as building
|
|
# 'test-menhir' repeatedly would rebuild the compiler each time
|
|
# (parser.ml has changed), without actually taking the changes from
|
|
# parser.mly into account ('core' uses the parser from boot/).
|
|
|
|
# The test-menhir target does not read or write the boot directory,
|
|
# it directly builds the parser in parsing/. In particular, it must
|
|
# duplicate the MenhirLib->CamlinternalMenhirlib renaming usually
|
|
# performed by the parsing/parser.ml import rule in the main
|
|
# Makefile.
|
|
.PHONY: test-menhir
|
|
test-menhir: parsing/parser.mly
|
|
$(MENHIR) $(MENHIRFLAGS) parsing/parser.mly
|
|
for f in $(addprefix parsing/parser.,ml mli) ; do \
|
|
cat $$f | sed "s/MenhirLib/CamlinternalMenhirLib/g" > $$f.tmp && \
|
|
mv $$f.tmp $$f ; \
|
|
done
|
|
$(MAKE) parsing/parser.cmo
|
|
|
|
|
|
## clean-menhir
|
|
|
|
partialclean-menhir::
|
|
rm -f \
|
|
$(addprefix parsing/parser.,ml mli) \
|
|
$(addprefix parsing/camlinternalMenhirLib.,ml mli)
|
|
|
|
clean-menhir: partialclean-menhir
|
|
|
|
|
|
## depend-menhir
|
|
|
|
.PHONY: depend-menhir
|
|
depend-menhir:
|
|
$(MENHIR) --depend --ocamldep "$(CAMLDEP) $(DEPFLAGS) $(DEPINCLUDES)" \
|
|
parsing/parser.mly > .depend.menhir
|
|
# this rule depends on the variables CAMLDEP, DEPFLAGS, DEPINCLUDES
|
|
# defined in Makefile, so it can only be invoked from the main Makefile
|
|
|
|
include .depend.menhir
|
|
|
|
## interpret-menhir
|
|
|
|
# This rule runs Menhir in interactive mode.
|
|
# The user can enter sentences, such as:
|
|
# implementation: TYPE LIDENT EQUAL LIDENT EOF
|
|
# and see how Menhir interprets them.
|
|
|
|
interpret-menhir:
|
|
@ echo "Please wait, I am building the LALR automaton..."
|
|
@ $(MENHIR) $(MENHIRFLAGS) parsing/parser.mly \
|
|
--interpret \
|
|
--interpret-show-cst \
|
|
--trace \
|