glr2.cc: get rid of the macros wrapping the lookahead
[bison.git] / data / skeletons / d.m4
blob331c06a885a77621b263e590e4de40a78637cd88
1                                                             -*- Autoconf -*-
3 # D language support for Bison
5 # Copyright (C) 2018-2020 Free Software Foundation, Inc.
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.
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.
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
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]).
27 # Prefix all the output lines with PREFIX.
28 m4_define([_b4_comment],
29 [$2[]m4_bpatsubst(m4_expand([[$1]]), [
30 \(.\)], [
31 $3\1])$4])
34 # b4_comment(TEXT, [PREFIX])
35 # --------------------------
36 # Put TEXT in comment.  Prefix all the output lines with PREFIX.
37 m4_define([b4_comment],
38 [_b4_comment([$1], [$2/* ], [$2   ], [  */])])
41 # b4_sync_start(LINE, FILE)
42 # -------------------------
43 m4_define([b4_sync_start], [[#]line $1 $2])
46 # b4_list2(LIST1, LIST2)
47 # ----------------------
48 # Join two lists with a comma if necessary.
49 m4_define([b4_list2],
50           [$1[]m4_ifval(m4_quote($1), [m4_ifval(m4_quote($2), [[, ]])])[]$2])
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.
57 m4_define([b4_percent_define_get3],
58           [m4_ifval(m4_quote(b4_percent_define_get([$1])),
59                 [$2[]b4_percent_define_get([$1])[]$3], [$4])])
61 # b4_percent_define_if_get2(ARG1, ARG2, DEF, NOT)
62 # -----------------------------------------------
63 # Expand to the value of DEF if ARG1 or ARG2 are %define'ed,
64 # otherwise NOT.
65 m4_define([b4_percent_define_if_get2],
66           [m4_ifval(m4_quote(b4_percent_define_get([$1])),
67                 [$3], [m4_ifval(m4_quote(b4_percent_define_get([$2])),
68                       [$3], [$4])])])
70 # b4_percent_define_class_before_interface(CLASS, INTERFACE)
71 # ----------------------------------------------------------
72 # Expand to a ', ' if both a class and an interface have been %define'ed
73 m4_define([b4_percent_define_class_before_interface],
74           [m4_ifval(m4_quote(b4_percent_define_get([$1])),
75                 [m4_ifval(m4_quote(b4_percent_define_get([$2])),
76                       [, ])])])
79 # b4_flag_value(BOOLEAN-FLAG)
80 # ---------------------------
81 m4_define([b4_flag_value], [b4_flag_if([$1], [true], [false])])
84 # b4_parser_class_declaration
85 # ---------------------------
86 # The declaration of the parser class ("class YYParser"), with all its
87 # qualifiers/annotations.
88 b4_percent_define_default([[api.parser.abstract]], [[false]])
89 b4_percent_define_default([[api.parser.final]],    [[false]])
90 b4_percent_define_default([[api.parser.public]],   [[false]])
92 m4_define([b4_parser_class_declaration],
93 [b4_percent_define_get3([api.parser.annotations], [], [ ])dnl
94 b4_percent_define_flag_if([api.parser.public],   [public ])dnl
95 b4_percent_define_flag_if([api.parser.abstract], [abstract ])dnl
96 b4_percent_define_flag_if([api.parser.final],    [final ])dnl
97 [class ]b4_parser_class[]dnl
98 b4_percent_define_if_get2([api.parser.extends], [api.parser.implements], [ : ])dnl
99 b4_percent_define_get([api.parser.extends])dnl
100 b4_percent_define_class_before_interface([api.parser.extends], [api.parser.implements])dnl
101 b4_percent_define_get([api.parser.implements])])
104 # b4_lexer_if(TRUE, FALSE)
105 # ------------------------
106 m4_define([b4_lexer_if],
107 [b4_percent_code_ifdef([[lexer]], [$1], [$2])])
110 # b4_position_type_if(TRUE, FALSE)
111 # --------------------------------
112 m4_define([b4_position_type_if],
113 [b4_percent_define_ifdef([[position_type]], [$1], [$2])])
116 # b4_location_type_if(TRUE, FALSE)
117 # --------------------------------
118 m4_define([b4_location_type_if],
119 [b4_percent_define_ifdef([[location_type]], [$1], [$2])])
122 # b4_identification
123 # -----------------
124 m4_define([b4_identification],
125 [[/** Version number for the Bison executable that generated this parser.  */
126   public static immutable string yy_bison_version = "]b4_version_string[";
128   /** Name of the skeleton that generated this parser.  */
129   public static immutable string yy_bison_skeleton = ]b4_skeleton[;
133 ## ------------ ##
134 ## Data types.  ##
135 ## ------------ ##
137 # b4_int_type(MIN, MAX)
138 # ---------------------
139 # Return the smallest int type able to handle numbers ranging from
140 # MIN to MAX (included).
141 m4_define([b4_int_type],
142 [m4_if(b4_ints_in($@,   [-128],   [127]), [1], [byte],
143        b4_ints_in($@, [-32768], [32767]), [1], [short],
144                                                [int])])
146 # b4_int_type_for(NAME)
147 # ---------------------
148 # Return the smallest int type able to handle numbers ranging from
149 # `NAME_min' to `NAME_max' (included).
150 m4_define([b4_int_type_for],
151 [b4_int_type($1_min, $1_max)])
153 # b4_null
154 # -------
155 m4_define([b4_null], [null])
158 # b4_integral_parser_table_define(NAME, DATA, COMMENT)
159 #-----------------------------------------------------
160 # Define "yy<TABLE-NAME>" whose contents is CONTENT.
161 m4_define([b4_integral_parser_table_define],
162 [m4_ifvaln([$3], [b4_comment([$3], [  ])])dnl
163 private static immutable b4_int_type_for([$2])[[]] yy$1_ =
165   $2
166 @};dnl
170 ## ------------- ##
171 ## Token kinds.  ##
172 ## ------------- ##
174 m4_define([b4_symbol(-2, id)],  [[YYEMPTY]])
175 b4_percent_define_default([[api.token.raw]], [[true]])
177 # b4_token_enum(TOKEN-NAME, TOKEN-NUMBER)
178 # ---------------------------------------
179 # Output the definition of this token as an enum.
180 m4_define([b4_token_enum],
181 [b4_token_format([  %s = %s,
182 ], [$1])])
184 # b4_token_enums
185 # --------------
186 # Output the definition of the tokens as enums.
187 m4_define([b4_token_enums],
188 [/* Token kinds.  */
189 public enum TokenKind {
190   ]b4_symbol(empty, id)[ = -2,
191 b4_symbol_foreach([b4_token_enum])dnl
197 ## -------------- ##
198 ## Symbol kinds.  ##
199 ## -------------- ##
201 # b4_symbol_kind(NUM)
202 # -------------------
203 m4_define([b4_symbol_kind],
204 [SymbolKind.b4_symbol_kind_base($@)])
207 # b4_symbol_enum(SYMBOL-NUM)
208 # --------------------------
209 # Output the definition of this symbol as an enum.
210 m4_define([b4_symbol_enum],
211 [m4_format([    %-30s %s],
212            m4_format([[%s = %s,]],
213                      b4_symbol([$1], [kind_base]),
214                      [$1]),
215            [b4_symbol_tag_comment([$1])])])
218 # b4_declare_symbol_enum
219 # ----------------------
220 # The definition of the symbol internal numbers as an enum.
221 # Defining YYEMPTY here is important: it forces the compiler
222 # to use a signed type, which matters for yytoken.
223 m4_define([b4_declare_symbol_enum],
224 [[  /* Symbol kinds.  */
225   struct SymbolKind
226   {
227     enum
228     {
229     ]b4_symbol(empty, kind_base)[ = -2,  /* No symbol.  */
230 ]b4_symbol_foreach([b4_symbol_enum])dnl
231 [    }
233     private int yycode_;
234     alias yycode_ this;
236     this(int code)
237     {
238       yycode_ = code;
239     }
241     /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
242        First, the terminals, then, starting at \a YYNTOKENS_, nonterminals.  */
243     static immutable string[] yytname_ = @{
244   ]b4_tname[
245     @};
247     /* Return YYSTR after stripping away unnecessary quotes and
248      backslashes, so that it's suitable for yyerror.  The heuristic is
249      that double-quoting is unnecessary unless the string contains an
250      apostrophe, a comma, or backslash (other than backslash-backslash).
251      YYSTR is taken from yytname.  */
252     final void toString(W)(W sink) const
253     if (isOutputRange!(W, char))
254     {
255       string yystr = yytname_[yycode_];
257       if (yystr[0] == '"')
258         {
259         strip_quotes:
260           for (int i = 1; i < yystr.length; i++)
261             switch (yystr[i])
262               {
263               case '\'':
264               case ',':
265                 break strip_quotes;
267               case '\\':
268                 if (yystr[++i] != '\\')
269                   break strip_quotes;
270                 goto default;
271               default:
272                 put(sink, yystr[i]);
273                 break;
275               case '"':
276                 return;
277               }
278         }
279       else if (yystr == "$end")
280       {
281         put(sink, "end of input");
282         return;
283       }
285       put(sink, yystr);
286     }
287   }
291 # b4-case(ID, CODE, [COMMENTS])
292 # -----------------------------
293 m4_define([b4_case], [    case $1:m4_ifval([$3], [ b4_comment([$3])])
295       break;])
298 ## ---------------- ##
299 ## Default values.  ##
300 ## ---------------- ##
302 m4_define([b4_yystype], [b4_percent_define_get([[stype]])])
303 b4_percent_define_default([[stype]], [[YYSemanticType]])])
305 # %name-prefix
306 m4_define_default([b4_prefix], [[YY]])
308 b4_percent_define_default([[api.parser.class]], [b4_prefix[]Parser])])
309 m4_define([b4_parser_class], [b4_percent_define_get([[api.parser.class]])])
311 #b4_percent_define_default([[location_type]], [Location])])
312 m4_define([b4_location_type], b4_percent_define_ifdef([[location_type]],[b4_percent_define_get([[location_type]])],[YYLocation]))
314 #b4_percent_define_default([[position_type]], [Position])])
315 m4_define([b4_position_type], b4_percent_define_ifdef([[position_type]],[b4_percent_define_get([[position_type]])],[YYPosition]))
318 ## ----------------- ##
319 ## Semantic Values.  ##
320 ## ----------------- ##
323 # b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG])
324 # ----------------------------------------------
325 # See README.  FIXME: factor in c-like?
326 m4_define([b4_symbol_value],
327 [m4_ifval([$3],
328           [($1.$3)],
329           [m4_ifval([$2],
330                     [b4_symbol_if([$2], [has_type],
331                                   [($1.b4_symbol([$2], [type]))],
332                                   [$1])],
333                     [$1])])])
335 # b4_lhs_value(SYMBOL-NUM, [TYPE])
336 # --------------------------------
337 # See README.
338 m4_define([b4_lhs_value],
339 [b4_symbol_value([yyval], [$1], [$2])])
342 # b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE])
343 # --------------------------------------------------
344 # See README.
346 # In this simple implementation, %token and %type have class names
347 # between the angle brackets.
348 m4_define([b4_rhs_value],
349 [b4_symbol_value([(yystack.valueAt (b4_subtract([$1], [$2])))], [$3], [$4])])
352 # b4_lhs_location()
353 # -----------------
354 # Expansion of @$.
355 m4_define([b4_lhs_location],
356 [(yyloc)])
359 # b4_rhs_location(RULE-LENGTH, POS)
360 # ---------------------------------
361 # Expansion of @POS, where the current rule has RULE-LENGTH symbols
362 # on RHS.
363 m4_define([b4_rhs_location],
364 [yystack.locationAt (b4_subtract($@))])
367 # b4_lex_param
368 # b4_parse_param
369 # --------------
370 # If defined, b4_lex_param arrives double quoted, but below we prefer
371 # it to be single quoted.  Same for b4_parse_param.
373 # TODO: should be in bison.m4
374 m4_define_default([b4_lex_param], [[]]))
375 m4_define([b4_lex_param], b4_lex_param))
376 m4_define([b4_parse_param], b4_parse_param))
378 # b4_lex_param_decl
379 # -------------------
380 # Extra formal arguments of the constructor.
381 m4_define([b4_lex_param_decl],
382 [m4_ifset([b4_lex_param],
383           [b4_remove_comma([$1],
384                            b4_param_decls(b4_lex_param))],
385           [$1])])
387 m4_define([b4_param_decls],
388           [m4_map([b4_param_decl], [$@])])
389 m4_define([b4_param_decl], [, $1])
391 m4_define([b4_remove_comma], [m4_ifval(m4_quote($1), [$1, ], [])m4_shift2($@)])
395 # b4_parse_param_decl
396 # -------------------
397 # Extra formal arguments of the constructor.
398 m4_define([b4_parse_param_decl],
399 [m4_ifset([b4_parse_param],
400           [b4_remove_comma([$1],
401                            b4_param_decls(b4_parse_param))],
402           [$1])])
406 # b4_lex_param_call
407 # -------------------
408 # Delegating the lexer parameters to the lexer constructor.
409 m4_define([b4_lex_param_call],
410           [m4_ifset([b4_lex_param],
411                     [b4_remove_comma([$1],
412                                      b4_param_calls(b4_lex_param))],
413                     [$1])])
414 m4_define([b4_param_calls],
415           [m4_map([b4_param_call], [$@])])
416 m4_define([b4_param_call], [, $2])
420 # b4_parse_param_cons
421 # -------------------
422 # Extra initialisations of the constructor.
423 m4_define([b4_parse_param_cons],
424           [m4_ifset([b4_parse_param],
425                     [b4_constructor_calls(b4_parse_param)])])
427 m4_define([b4_constructor_calls],
428           [m4_map([b4_constructor_call], [$@])])
429 m4_define([b4_constructor_call],
430           [this.$2 = $2;
431           ])
435 # b4_parse_param_vars
436 # -------------------
437 # Extra instance variables.
438 m4_define([b4_parse_param_vars],
439           [m4_ifset([b4_parse_param],
440                     [
441     /* User arguments.  */
442 b4_var_decls(b4_parse_param)])])
444 m4_define([b4_var_decls],
445           [m4_map_sep([b4_var_decl], [
446 ], [$@])])
447 m4_define([b4_var_decl],
448           [    protected $1;])
451 # b4_public_types_declare
452 # -----------------------
453 # Define the public types: token, semantic value, location, and so forth.
454 # Depending on %define token_lex, may be output in the header or source file.
455 m4_define([b4_public_types_declare],
457 alias Symbol = ]b4_parser_class[.Symbol;
458 alias Value = ]b4_yystype[;]b4_locations_if([[
459 alias Location = ]b4_location_type[;
460 alias Position = ]b4_position_type[;]])[
464 # b4_symbol_type_define
465 # ---------------------
466 # Define symbol_type, the external type for symbols used for symbol
467 # constructors.
468 m4_define([b4_symbol_type_define],
470   /**
471     * A complete symbol
472     */
473   struct Symbol
474   {
475     private SymbolKind kind;
476     private Value value_;]b4_locations_if([[
477     private Location location_;]])[
478     this(TokenKind token]b4_locations_if([[, Location loc]])[)
479     {
480       kind = yytranslate_(token);]b4_locations_if([
481       location_ = loc;])[
482     }
483     static foreach (member; __traits(allMembers, YYSemanticType))
484     {
485       this(TokenKind token, typeof(mixin("YYSemanticType." ~ member)) val]b4_locations_if([[, Location loc]])[)
486       {
487         kind = yytranslate_(token);
488         mixin("value_." ~ member ~ " = val;");]b4_locations_if([
489         location_ = loc;])[
490       }
491     }
492     SymbolKind token() { return kind; }
493     Value value() { return value_; }]b4_locations_if([[
494     Location location() { return location_; }]])[
495   }