1                                                            -*- Autoconf -*-
2
3# D language support for Bison
4
5# Copyright (C) 2018-2021 Free Software Foundation, Inc.
6
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
20
21# _b4_comment(TEXT, OPEN, CONTINUE, END)
22# --------------------------------------
23# Put TEXT in comment.  Avoid trailing spaces: don't indent empty lines.
24# Avoid adding indentation to the first line, as the indentation comes
25# from OPEN.  That's why we don't patsubst([$1], [^\(.\)], [   \1]).
26#
27# Prefix all the output lines with PREFIX.
28m4_define([_b4_comment],
29[$2[]m4_bpatsubst(m4_expand([[$1]]), [
30\(.\)], [
31$3\1])$4])
32
33
34# b4_comment(TEXT, [PREFIX])
35# --------------------------
36# Put TEXT in comment.  Prefix all the output lines with PREFIX.
37m4_define([b4_comment],
38[_b4_comment([$1], [$2/* ], [$2   ], [  */])])
39
40
41# b4_sync_start(LINE, FILE)
42# -------------------------
43m4_define([b4_sync_start], [[#]line $1 $2])
44
45
46# b4_list2(LIST1, LIST2)
47# ----------------------
48# Join two lists with a comma if necessary.
49m4_define([b4_list2],
50          [$1[]m4_ifval(m4_quote($1), [m4_ifval(m4_quote($2), [[, ]])])[]$2])
51
52
53# b4_percent_define_get3(DEF, PRE, POST, NOT)
54# -------------------------------------------
55# Expand to the value of DEF surrounded by PRE and POST if it's %define'ed,
56# otherwise NOT.
57m4_define([b4_percent_define_get3],
58          [m4_ifval(m4_quote(b4_percent_define_get([$1])),
59                [$2[]b4_percent_define_get([$1])[]$3], [$4])])
60
61
62# b4_flag_value(BOOLEAN-FLAG)
63# ---------------------------
64m4_define([b4_flag_value], [b4_flag_if([$1], [true], [false])])
65
66
67# b4_parser_class_declaration
68# ---------------------------
69# The declaration of the parser class ("class YYParser"), with all its
70# qualifiers/annotations.
71b4_percent_define_default([[api.parser.abstract]], [[false]])
72b4_percent_define_default([[api.parser.final]],    [[false]])
73b4_percent_define_default([[api.parser.public]],   [[false]])
74
75m4_define([b4_parser_class_declaration],
76[b4_percent_define_get3([api.parser.annotations], [], [ ])dnl
77b4_percent_define_flag_if([api.parser.public],   [public ])dnl
78b4_percent_define_flag_if([api.parser.abstract], [abstract ])dnl
79b4_percent_define_flag_if([api.parser.final],    [final ])dnl
80[class ]b4_parser_class[]dnl
81b4_percent_define_get3([api.parser.extends], [ extends ])dnl
82b4_percent_define_get3([api.parser.implements], [ implements ])])
83
84
85# b4_lexer_if(TRUE, FALSE)
86# ------------------------
87m4_define([b4_lexer_if],
88[b4_percent_code_ifdef([[lexer]], [$1], [$2])])
89
90
91# b4_position_type_if(TRUE, FALSE)
92# --------------------------------
93m4_define([b4_position_type_if],
94[b4_percent_define_ifdef([[position_type]], [$1], [$2])])
95
96
97# b4_location_type_if(TRUE, FALSE)
98# --------------------------------
99m4_define([b4_location_type_if],
100[b4_percent_define_ifdef([[location_type]], [$1], [$2])])
101
102
103# b4_identification
104# -----------------
105m4_define([b4_identification],
106[[/** Version number for the Bison executable that generated this parser.  */
107  public static immutable string yy_bison_version = "]b4_version_string[";
108
109  /** Name of the skeleton that generated this parser.  */
110  public static immutable string yy_bison_skeleton = ]b4_skeleton[;
111]])
112
113
114## ------------ ##
115## Data types.  ##
116## ------------ ##
117
118# b4_int_type(MIN, MAX)
119# ---------------------
120# Return the smallest int type able to handle numbers ranging from
121# MIN to MAX (included).
122m4_define([b4_int_type],
123[m4_if(b4_ints_in($@,   [-128],   [127]), [1], [byte],
124       b4_ints_in($@, [-32768], [32767]), [1], [short],
125                                               [int])])
126
127# b4_int_type_for(NAME)
128# ---------------------
129# Return the smallest int type able to handle numbers ranging from
130# `NAME_min' to `NAME_max' (included).
131m4_define([b4_int_type_for],
132[b4_int_type($1_min, $1_max)])
133
134# b4_null
135# -------
136m4_define([b4_null], [null])
137
138
139# b4_integral_parser_table_define(NAME, DATA, COMMENT)
140#-----------------------------------------------------
141# Define "yy<TABLE-NAME>" whose contents is CONTENT.
142m4_define([b4_integral_parser_table_define],
143[m4_ifvaln([$3], [b4_comment([$3], [  ])])dnl
144private static immutable b4_int_type_for([$2])[[]] yy$1_ =
145@{
146  $2
147@};dnl
148])
149
150
151## ------------- ##
152## Token kinds.  ##
153## ------------- ##
154
155m4_define([b4_symbol(-2, id)],  [[YYEMPTY]])
156
157# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
158# ---------------------------------------
159# Output the definition of this token as an enum.
160m4_define([b4_token_enum],
161[b4_token_format([  %s = %s,
162], [$1])])
163
164# b4_token_enums
165# --------------
166# Output the definition of the tokens as enums.
167m4_define([b4_token_enums],
168[/* Token kinds.  */
169public enum TokenKind {
170  ]b4_symbol_kind([-2])[ = -2,
171b4_symbol_foreach([b4_token_enum])dnl
172}
173])
174
175
176
177## -------------- ##
178## Symbol kinds.  ##
179## -------------- ##
180
181b4_percent_define_default([[api.symbol.prefix]], [[S_]])
182
183# b4_symbol_kind(NUM)
184# -------------------
185m4_define([b4_symbol_kind],
186[SymbolKind.b4_symbol_kind_base($@)])
187
188
189# b4_symbol_enum(SYMBOL-NUM)
190# --------------------------
191# Output the definition of this symbol as an enum.
192m4_define([b4_symbol_enum],
193[m4_format([    %-30s %s],
194           m4_format([[%s = %s,]],
195                     b4_symbol([$1], [kind_base]),
196                     [$1]),
197           [b4_symbol_tag_comment([$1])])])
198
199
200# b4_declare_symbol_enum
201# ----------------------
202# The definition of the symbol internal numbers as an enum.
203# Defining YYEMPTY here is important: it forces the compiler
204# to use a signed type, which matters for yytoken.
205m4_define([b4_declare_symbol_enum],
206[[  /* Symbol kinds.  */
207  public enum SymbolKind
208  {
209    ]b4_symbol(-2, kind_base)[ = -2,  /* No symbol.  */
210]b4_symbol_foreach([b4_symbol_enum])dnl
211[  };
212]])])
213
214
215
216# b4-case(ID, CODE, [COMMENTS])
217# -----------------------------
218m4_define([b4_case], [    case $1:m4_ifval([$3], [ b4_comment([$3])])
219$2
220      break;])
221
222
223## ---------------- ##
224## Default values.  ##
225## ---------------- ##
226
227m4_define([b4_yystype], [b4_percent_define_get([[stype]])])
228b4_percent_define_default([[stype]], [[YYSemanticType]])])
229
230# %name-prefix
231m4_define_default([b4_prefix], [[YY]])
232
233b4_percent_define_default([[api.parser.class]], [b4_prefix[]Parser])])
234m4_define([b4_parser_class], [b4_percent_define_get([[api.parser.class]])])
235
236#b4_percent_define_default([[location_type]], [Location])])
237m4_define([b4_location_type], b4_percent_define_ifdef([[location_type]],[b4_percent_define_get([[location_type]])],[YYLocation]))
238
239#b4_percent_define_default([[position_type]], [Position])])
240m4_define([b4_position_type], b4_percent_define_ifdef([[position_type]],[b4_percent_define_get([[position_type]])],[YYPosition]))
241
242
243## ----------------- ##
244## Semantic Values.  ##
245## ----------------- ##
246
247
248# b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])
249# ----------------------------------------------
250# See README.  FIXME: factor in c-like?
251m4_define([b4_symbol_value],
252[m4_ifval([$3],
253          [($1.$3)],
254          [m4_ifval([$2],
255                    [b4_symbol_if([$2], [has_type],
256                                  [($1.b4_symbol([$2], [type]))],
257                                  [$1])],
258                    [$1])])])
259
260# b4_lhs_value(SYMBOL-NUM, [TYPE])
261# --------------------------------
262# See README.
263m4_define([b4_lhs_value],
264[b4_symbol_value([yyval], [$1], [$2])])
265
266
267# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
268# --------------------------------------------------
269# See README.
270#
271# In this simple implementation, %token and %type have class names
272# between the angle brackets.
273m4_define([b4_rhs_value],
274[b4_symbol_value([(yystack.valueAt (b4_subtract([$1], [$2])))], [$3], [$4])])
275
276
277# b4_lhs_location()
278# -----------------
279# Expansion of @$.
280m4_define([b4_lhs_location],
281[(yyloc)])
282
283
284# b4_rhs_location(RULE-LENGTH, POS)
285# ---------------------------------
286# Expansion of @POS, where the current rule has RULE-LENGTH symbols
287# on RHS.
288m4_define([b4_rhs_location],
289[yystack.locationAt ([$1], [$2])])
290
291
292# b4_lex_param
293# b4_parse_param
294# --------------
295# If defined, b4_lex_param arrives double quoted, but below we prefer
296# it to be single quoted.  Same for b4_parse_param.
297
298# TODO: should be in bison.m4
299m4_define_default([b4_lex_param], [[]]))
300m4_define([b4_lex_param], b4_lex_param))
301m4_define([b4_parse_param], b4_parse_param))
302
303# b4_lex_param_decl
304# -------------------
305# Extra formal arguments of the constructor.
306m4_define([b4_lex_param_decl],
307[m4_ifset([b4_lex_param],
308          [b4_remove_comma([$1],
309                           b4_param_decls(b4_lex_param))],
310          [$1])])
311
312m4_define([b4_param_decls],
313          [m4_map([b4_param_decl], [$@])])
314m4_define([b4_param_decl], [, $1])
315
316m4_define([b4_remove_comma], [m4_ifval(m4_quote($1), [$1, ], [])m4_shift2($@)])
317
318
319
320# b4_parse_param_decl
321# -------------------
322# Extra formal arguments of the constructor.
323m4_define([b4_parse_param_decl],
324[m4_ifset([b4_parse_param],
325          [b4_remove_comma([$1],
326                           b4_param_decls(b4_parse_param))],
327          [$1])])
328
329
330
331# b4_lex_param_call
332# -------------------
333# Delegating the lexer parameters to the lexer constructor.
334m4_define([b4_lex_param_call],
335          [m4_ifset([b4_lex_param],
336                    [b4_remove_comma([$1],
337                                     b4_param_calls(b4_lex_param))],
338                    [$1])])
339m4_define([b4_param_calls],
340          [m4_map([b4_param_call], [$@])])
341m4_define([b4_param_call], [, $2])
342
343
344
345# b4_parse_param_cons
346# -------------------
347# Extra initialisations of the constructor.
348m4_define([b4_parse_param_cons],
349          [m4_ifset([b4_parse_param],
350                    [b4_constructor_calls(b4_parse_param)])])
351
352m4_define([b4_constructor_calls],
353          [m4_map([b4_constructor_call], [$@])])
354m4_define([b4_constructor_call],
355          [this.$2 = $2;
356          ])
357
358
359
360# b4_parse_param_vars
361# -------------------
362# Extra instance variables.
363m4_define([b4_parse_param_vars],
364          [m4_ifset([b4_parse_param],
365                    [
366    /* User arguments.  */
367b4_var_decls(b4_parse_param)])])
368
369m4_define([b4_var_decls],
370          [m4_map_sep([b4_var_decl], [
371], [$@])])
372m4_define([b4_var_decl],
373          [    protected $1;])
374