summaryrefslogtreecommitdiff
path: root/Makefile.menhir
blob: c2068d235f30b3b84b0c94e5b305a9e9204b54a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#**************************************************************************
#*                                                                        *
#*                                 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 \