-
Notifications
You must be signed in to change notification settings - Fork 50
/
Makefile
155 lines (138 loc) · 6.09 KB
/
Makefile
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
# Copyright 2014 The Cockroach Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing
# permissions and limitations under the License.
GO ?= go
## Update the git hooks and install commands from dependencies whenever they
## change.
bin/.bootstrap: bin/.submodules-initialized
echo "skip"
touch $@
## Note how the actions for this rule are *not* using $(GIT_DIR) which
## is otherwise defined in defs.mk above. This is because submodules
## are used in the process of definining the .mk files included by the
## Makefile, so it is not yet defined by the time
## `.submodules-initialized` is needed during a fresh build after a
## checkout.
.SECONDARY: bin/.submodules-initialized
bin/.submodules-initialized:
gitdir=$$(git rev-parse --git-dir 2>/dev/null || true); \
if test -n "$$gitdir"; then \
git submodule update --init --recursive; \
fi
mkdir -p $(@D)
touch $@
# Tell Make to delete the target if its recipe fails. Otherwise, if a recipe
# modifies its target before failing, the target's timestamp will make it appear
# up-to-date on the next invocation of Make, even though it is likely corrupt.
# See: https://www.gnu.org/software/make/manual/html_node/Errors.html#Errors
.DELETE_ON_ERROR:
# Targets that name a real file that must be rebuilt on every Make invocation
# should depend on .ALWAYS_REBUILD. (.PHONY should only be used on targets that
# don't name a real file because .DELETE_ON_ERROR does not apply to .PHONY
# targets.)
.ALWAYS_REBUILD:
.PHONY: .ALWAYS_REBUILD
SQLPARSER_TARGETS = \
pkg/sql/parser/sql.go \
pkg/sql/parser/helpmap_test.go \
pkg/sql/parser/help_messages.go \
pkg/sql/lex/tokens.go \
pkg/sql/lex/keywords.go \
pkg/sql/lex/reserved_keywords.go
go-targets := generate
$(go-targets): $(SQLPARSER_TARGETS)
.PHONY: clean
clean:
rm $(SQLPARSER_TARGETS)
.SECONDARY: pkg/sql/parser/gen/sql.go.tmp
pkg/sql/parser/gen/sql.go.tmp: pkg/sql/parser/gen/sql-gen.y bin/.bootstrap
set -euo pipefail; \
ret=$$(cd pkg/sql/parser/gen && goyacc -p sql -o sql.go.tmp sql-gen.y); \
if expr "$$ret" : ".*conflicts" >/dev/null; then \
echo "$$ret"; exit 1; \
fi
# The lex package needs to know about all tokens, because the encode
# functions and lexing predicates need to know about keywords, and
# keywords map to the token constants. Therefore, generate the
# constant tokens in the lex package primarily.
pkg/sql/lex/tokens.go: pkg/sql/parser/gen/sql.go.tmp
(echo "// Code generated by make. DO NOT EDIT."; \
echo "// GENERATED FILE DO NOT EDIT"; \
echo; \
echo "package lex"; \
echo; \
grep '^const [A-Z][_A-Z0-9]* ' $^) > $@.tmp || rm $@.tmp
mv -f $@.tmp $@
# The lex package is now the primary source for the token constant
# definitions. Modify the code generated by goyacc here to refer to
# the definitions in the lex package.
pkg/sql/parser/sql.go: pkg/sql/parser/gen/sql.go.tmp | bin/.bootstrap
(echo "// Code generated by goyacc. DO NOT EDIT."; \
echo "// GENERATED FILE DO NOT EDIT"; \
cat $^ | \
sed -E 's/^const ([A-Z][_A-Z0-9]*) =.*$$/const \1 = lex.\1/g') > $@.tmp || rm $@.tmp
mv -f $@.tmp $@
goimports -w $@
# This modifies the grammar to:
# - improve the types used by the generated parser for non-terminals
# - expand the help rules.
#
# For types:
# Determine the types that will be migrated to union types by looking
# at the accessors of sqlSymUnion. The first step in this pipeline
# prints every return type of a sqlSymUnion accessor on a separate line.
# The next step regular expression escapes these types. The third
# (prepending) and the fourth (appending) steps build regular expressions
# for each of the types and store them in the file. (We make multiple
# regular expressions because we ran into a limit of characters for a
# single regex executed by sed.)
# Then translate the original syntax file, with the types determined
# above being replaced with the union type in their type declarations.
.SECONDARY: pkg/sql/parser/gen/sql-gen.y
pkg/sql/parser/gen/sql-gen.y: pkg/sql/parser/sql.y pkg/sql/parser/replace_help_rules.awk
mkdir -p pkg/sql/parser/gen
set -euo pipefail; \
awk '/func.*sqlSymUnion/ {print $$(NF - 1)}' pkg/sql/parser/sql.y | \
sed -e 's/[]\/$$*.^|[]/\\&/g' | \
sed -e "s/^/s_(type|token) <(/" | \
awk '{print $$0")>_\\1 <union> /* <\\2> */_"}' > pkg/sql/parser/gen/types_regex.tmp; \
sed -E -f pkg/sql/parser/gen/types_regex.tmp < pkg/sql/parser/sql.y | \
awk -f pkg/sql/parser/replace_help_rules.awk | \
sed -Ee 's,//.*$$,,g;s,/[*]([^*]|[*][^/])*[*]/, ,g;s/ +$$//g' > $@.tmp || rm $@.tmp
mv -f $@.tmp $@
rm pkg/sql/parser/gen/types_regex.tmp
pkg/sql/lex/reserved_keywords.go: pkg/sql/parser/sql.y pkg/sql/parser/reserved_keywords.awk | bin/.bootstrap
awk -f pkg/sql/parser/reserved_keywords.awk < $< > $@.tmp || rm $@.tmp
mv -f $@.tmp $@
gofmt -s -w $@
pkg/sql/lex/keywords.go: pkg/sql/parser/sql.y pkg/sql/lex/all_keywords.go | bin/.bootstrap
go run -tags all_keywords pkg/sql/lex/all_keywords.go < $< > $@.tmp || rm $@.tmp
mv -f $@.tmp $@
gofmt -s -w $@
# This target will print unreserved_keywords which are not actually
# used in the grammar.
.PHONY: sqlparser-unused-unreserved-keywords
sqlparser-unused-unreserved-keywords: pkg/sql/parser/sql.y pkg/sql/parser/unreserved_keywords.awk
@for kw in $$(awk -f pkg/sql/parser/unreserved_keywords.awk < $<); do \
if [ $$(grep -c $${kw} $<) -le 2 ]; then \
echo $${kw}; \
fi \
done
pkg/sql/parser/helpmap_test.go: pkg/sql/parser/gen/sql-gen.y pkg/sql/parser/help_gen_test.sh | bin/.bootstrap
@pkg/sql/parser/help_gen_test.sh < $< >$@.tmp || rm $@.tmp
mv -f $@.tmp $@
gofmt -s -w $@
pkg/sql/parser/help_messages.go: pkg/sql/parser/sql.y pkg/sql/parser/help.awk | bin/.bootstrap
awk -f pkg/sql/parser/help.awk < $< > $@.tmp || rm $@.tmp
mv -f $@.tmp $@
gofmt -s -w $@