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 21m4_include(b4_skeletonsdir/[c-like.m4]) 22 23 24# b4_symbol_action(SYMBOL-NUM, ACTION) 25# ------------------------------------ 26# Run the action ACTION ("destructor" or "printer") for SYMBOL-NUM. 27m4_define([b4_symbol_action], 28[b4_symbol_if([$1], [has_$2], 29[b4_dollar_pushdef([yyval], 30 [$1], 31 [], 32 [yyloc])dnl 33 _b4_symbol_case([$1])[]dnl 34b4_syncline([b4_symbol([$1], [$2_line])], [b4_symbol([$1], [$2_file])])dnl 35b4_symbol([$1], [$2]) 36b4_syncline([@oline@], [@ofile@])dnl 37 break; 38 39b4_dollar_popdef[]dnl 40])]) 41 42 43# b4_use(EXPR) 44# ------------ 45# Pacify the compiler about some maybe unused value. 46m4_define([b4_use], 47[]) 48 49 50# b4_sync_start(LINE, FILE) 51# ------------------------- 52m4_define([b4_sync_start], [[#]line $1 $2]) 53 54 55# b4_list2(LIST1, LIST2) 56# ---------------------- 57# Join two lists with a comma if necessary. 58m4_define([b4_list2], 59 [$1[]m4_ifval(m4_quote($1), [m4_ifval(m4_quote($2), [[, ]])])[]$2]) 60 61 62# b4_percent_define_get3(DEF, PRE, POST, NOT) 63# ------------------------------------------- 64# Expand to the value of DEF surrounded by PRE and POST if it's %define'ed, 65# otherwise NOT. 66m4_define([b4_percent_define_get3], 67 [m4_ifval(m4_quote(b4_percent_define_get([$1])), 68 [$2[]b4_percent_define_get([$1])[]$3], [$4])]) 69 70# b4_percent_define_if_get2(ARG1, ARG2, DEF, NOT) 71# ----------------------------------------------- 72# Expand to the value of DEF if ARG1 or ARG2 are %define'ed, 73# otherwise NOT. 74m4_define([b4_percent_define_if_get2], 75 [m4_ifval(m4_quote(b4_percent_define_get([$1])), 76 [$3], [m4_ifval(m4_quote(b4_percent_define_get([$2])), 77 [$3], [$4])])]) 78 79# b4_percent_define_class_before_interface(CLASS, INTERFACE) 80# ---------------------------------------------------------- 81# Expand to a ', ' if both a class and an interface have been %define'ed 82m4_define([b4_percent_define_class_before_interface], 83 [m4_ifval(m4_quote(b4_percent_define_get([$1])), 84 [m4_ifval(m4_quote(b4_percent_define_get([$2])), 85 [, ])])]) 86 87 88# b4_flag_value(BOOLEAN-FLAG) 89# --------------------------- 90m4_define([b4_flag_value], [b4_flag_if([$1], [true], [false])]) 91 92 93# b4_parser_class_declaration 94# --------------------------- 95# The declaration of the parser class ("class YYParser"), with all its 96# qualifiers/annotations. 97b4_percent_define_default([[api.parser.abstract]], [[false]]) 98b4_percent_define_default([[api.parser.final]], [[false]]) 99b4_percent_define_default([[api.parser.public]], [[false]]) 100 101m4_define([b4_parser_class_declaration], 102[b4_percent_define_get3([api.parser.annotations], [], [ ])dnl 103b4_percent_define_flag_if([api.parser.public], [public ])dnl 104b4_percent_define_flag_if([api.parser.abstract], [abstract ])dnl 105b4_percent_define_flag_if([api.parser.final], [final ])dnl 106[class ]b4_parser_class[]dnl 107b4_percent_define_if_get2([api.parser.extends], [api.parser.implements], [ : ])dnl 108b4_percent_define_get([api.parser.extends])dnl 109b4_percent_define_class_before_interface([api.parser.extends], [api.parser.implements])dnl 110b4_percent_define_get([api.parser.implements])]) 111 112 113# b4_lexer_if(TRUE, FALSE) 114# ------------------------ 115m4_define([b4_lexer_if], 116[b4_percent_code_ifdef([[lexer]], [$1], [$2])]) 117 118 119# b4_position_type_if(TRUE, FALSE) 120# -------------------------------- 121m4_define([b4_position_type_if], 122[b4_percent_define_ifdef([[position_type]], [$1], [$2])]) 123 124 125# b4_location_type_if(TRUE, FALSE) 126# -------------------------------- 127m4_define([b4_location_type_if], 128[b4_percent_define_ifdef([[location_type]], [$1], [$2])]) 129 130 131# b4_identification 132# ----------------- 133m4_define([b4_identification], 134[[/** Version number for the Bison executable that generated this parser. */ 135 public static immutable string yy_bison_version = "]b4_version_string["; 136 137 /** Name of the skeleton that generated this parser. */ 138 public static immutable string yy_bison_skeleton = ]b4_skeleton[; 139]]) 140 141 142## ------------ ## 143## Data types. ## 144## ------------ ## 145 146# b4_int_type(MIN, MAX) 147# --------------------- 148# Return the smallest int type able to handle numbers ranging from 149# MIN to MAX (included). 150m4_define([b4_int_type], 151[m4_if(b4_ints_in($@, [-128], [127]), [1], [byte], 152 b4_ints_in($@, [-32768], [32767]), [1], [short], 153 [int])]) 154 155# b4_int_type_for(NAME) 156# --------------------- 157# Return the smallest int type able to handle numbers ranging from 158# `NAME_min' to `NAME_max' (included). 159m4_define([b4_int_type_for], 160[b4_int_type($1_min, $1_max)]) 161 162# b4_null 163# ------- 164m4_define([b4_null], [null]) 165 166 167# b4_integral_parser_table_define(NAME, DATA, COMMENT) 168#----------------------------------------------------- 169# Define "yy<TABLE-NAME>" whose contents is CONTENT. 170m4_define([b4_integral_parser_table_define], 171[m4_ifvaln([$3], [b4_comment([$3], [ ])])dnl 172private static immutable b4_int_type_for([$2])[[]] yy$1_ = 173@{ 174 $2 175@};dnl 176]) 177 178 179## ------------- ## 180## Token kinds. ## 181## ------------- ## 182 183m4_define([b4_symbol(-2, id)], [[YYEMPTY]]) 184b4_percent_define_default([[api.token.raw]], [[true]]) 185 186# b4_token_enum(TOKEN-NAME, TOKEN-NUMBER) 187# --------------------------------------- 188# Output the definition of this token as an enum. 189m4_define([b4_token_enum], 190[b4_token_format([ %s = %s, 191], [$1])]) 192 193# b4_token_enums 194# -------------- 195# Output the definition of the tokens as enums. 196m4_define([b4_token_enums], 197[/* Token kinds. */ 198public enum TokenKind { 199 ]b4_symbol(empty, id)[ = -2, 200b4_symbol_foreach([b4_token_enum])dnl 201} 202]) 203 204# b4_symbol_translate(STRING) 205# --------------------------- 206# Used by "bison" in the array of symbol names to mark those that 207# require translation. 208m4_define([b4_symbol_translate], 209[[_($1)]]) 210 211 212# _b4_token_constructor_define(SYMBOL-NUM) 213# ---------------------------------------- 214# Define Symbol.FOO for SYMBOL-NUM. 215m4_define([_b4_token_constructor_define], 216[b4_token_visible_if([$1], 217[[ 218 static auto ]b4_symbol([$1], [id])[(]b4_symbol_if([$1], [has_type], 219[b4_union_if([b4_symbol([$1], [type]], 220[[typeof(YYSemanticType.]b4_symbol([$1], [type])[]])) [val]])dnl 221[]b4_locations_if([b4_symbol_if([$1], [has_type], [[, ]])[Location l]])[) 222 { 223 return Symbol(TokenKind.]b4_symbol([$1], [id])[]b4_symbol_if([$1], [has_type], 224 [[, val]])[]b4_locations_if([[, l]])[); 225 }]])]) 226 227# b4_token_constructor_define 228# --------------------------- 229# Define Symbol.FOO for each token kind FOO. 230m4_define([b4_token_constructor_define], 231[[ 232 /* Implementation of token constructors for each symbol type visible to 233 * the user. The code generates static methods that have the same names 234 * as the TokenKinds. 235 */]b4_symbol_foreach([_b4_token_constructor_define])dnl 236]) 237 238## -------------- ## 239## Symbol kinds. ## 240## -------------- ## 241 242# b4_symbol_kind(NUM) 243# ------------------- 244m4_define([b4_symbol_kind], 245[SymbolKind.b4_symbol_kind_base($@)]) 246 247 248# b4_symbol_enum(SYMBOL-NUM) 249# -------------------------- 250# Output the definition of this symbol as an enum. 251m4_define([b4_symbol_enum], 252[m4_format([ %-30s %s], 253 m4_format([[%s = %s,]], 254 b4_symbol([$1], [kind_base]), 255 [$1]), 256 [b4_symbol_tag_comment([$1])])]) 257 258 259# b4_declare_symbol_enum 260# ---------------------- 261# The definition of the symbol internal numbers as an enum. 262# Defining YYEMPTY here is important: it forces the compiler 263# to use a signed type, which matters for yytoken. 264m4_define([b4_declare_symbol_enum], 265[[ /* Symbol kinds. */ 266 struct SymbolKind 267 { 268 enum 269 { 270 ]b4_symbol(empty, kind_base)[ = -2, /* No symbol. */ 271]b4_symbol_foreach([b4_symbol_enum])dnl 272[ } 273 274 private int yycode_; 275 alias yycode_ this; 276 277 this(int code) 278 { 279 yycode_ = code; 280 } 281 282 /* Return YYSTR after stripping away unnecessary quotes and 283 backslashes, so that it's suitable for yyerror. The heuristic is 284 that double-quoting is unnecessary unless the string contains an 285 apostrophe, a comma, or backslash (other than backslash-backslash). 286 YYSTR is taken from yytname. */ 287 final void toString(W)(W sink) const 288 if (isOutputRange!(W, char)) 289 { 290 immutable string[] yy_sname = @{ 291 ]b4_symbol_names[ 292 @};]b4_has_translations_if([[ 293 /* YYTRANSLATABLE[SYMBOL-NUM] -- Whether YY_SNAME[SYMBOL-NUM] is 294 internationalizable. */ 295 immutable ]b4_int_type_for([b4_translatable])[[] yytranslatable = @{ 296 ]b4_translatable[ 297 @};]])[ 298 299 put(sink, yy_sname[yycode_]); 300 } 301 } 302]]) 303 304 305# b4_case(ID, CODE, [COMMENTS]) 306# ----------------------------- 307m4_define([b4_case], [ case $1:m4_ifval([$3], [ b4_comment([$3])]) 308$2 309 break;]) 310 311 312## ---------------- ## 313## Default values. ## 314## ---------------- ## 315 316m4_define([b4_yystype], [b4_percent_define_get([[stype]])]) 317b4_percent_define_default([[stype]], [[YYSemanticType]])]) 318 319# %name-prefix 320m4_define_default([b4_prefix], [[YY]]) 321 322b4_percent_define_default([[api.parser.class]], [b4_prefix[]Parser])]) 323m4_define([b4_parser_class], [b4_percent_define_get([[api.parser.class]])]) 324 325#b4_percent_define_default([[location_type]], [Location])]) 326m4_define([b4_location_type], b4_percent_define_ifdef([[location_type]],[b4_percent_define_get([[location_type]])],[YYLocation])) 327 328#b4_percent_define_default([[position_type]], [Position])]) 329m4_define([b4_position_type], b4_percent_define_ifdef([[position_type]],[b4_percent_define_get([[position_type]])],[YYPosition])) 330 331 332## ---------------- ## 333## api.value.type. ## 334## ---------------- ## 335 336 337# ---------------------- # 338# api.value.type=union. # 339# ---------------------- # 340 341# b4_symbol_type_register(SYMBOL-NUM) 342# ----------------------------------- 343# Symbol SYMBOL-NUM has a type (for union) instead of a type-tag. 344# Extend the definition of %union's body (b4_union_members) with a 345# field of that type, and extend the symbol's "type" field to point to 346# the field name, instead of the type name. 347m4_define([b4_symbol_type_register], 348[m4_define([b4_symbol($1, type_tag)], 349 [b4_symbol_if([$1], [has_id], 350 [b4_symbol([$1], [id])], 351 [yykind_[]b4_symbol([$1], [number])])])dnl 352m4_append([b4_union_members], 353m4_expand([m4_format([ %-40s %s], 354 m4_expand([b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]), 355 [b4_symbol_tag_comment([$1])])])) 356]) 357 358 359# b4_type_define_tag(SYMBOL1-NUM, ...) 360# ------------------------------------ 361# For the batch of symbols SYMBOL1-NUM... (which all have the same 362# type), enhance the %union definition for each of them, and set 363# there "type" field to the field tag name, instead of the type name. 364m4_define([b4_type_define_tag], 365[b4_symbol_if([$1], [has_type], 366 [m4_map([b4_symbol_type_register], [$@])]) 367]) 368 369 370# b4_symbol_value_union(VAL, SYMBOL-NUM, [TYPE]) 371# ---------------------------------------------- 372# Same of b4_symbol_value, but when api.value.type=union. 373m4_define([b4_symbol_value_union], 374[m4_ifval([$3], 375 [(*($3*)(&$1))], 376 [m4_ifval([$2], 377 [b4_symbol_if([$2], [has_type], 378 [($1.b4_symbol([$2], [type_tag]))], 379 [$1])], 380 [$1])])]) 381 382 383# b4_value_type_setup_union 384# ------------------------- 385# Setup support for api.value.type=union. Symbols are defined with a 386# type instead of a union member name: build the corresponding union, 387# and give the symbols their tag. 388m4_define([b4_value_type_setup_union], 389[m4_define([b4_union_members]) 390b4_type_foreach([b4_type_define_tag]) 391m4_copy_force([b4_symbol_value_union], [b4_symbol_value]) 392]) 393 394 395# _b4_value_type_setup_keyword 396# ---------------------------- 397# api.value.type is defined with a keyword/string syntax. Check if 398# that is properly defined, and prepare its use. 399m4_define([_b4_value_type_setup_keyword], 400[b4_percent_define_check_values([[[[api.value.type]], 401 [[none]], 402 [[union]], 403 [[union-directive]], 404 [[yystype]]]])dnl 405m4_case(b4_percent_define_get([[api.value.type]]), 406 [union], [b4_value_type_setup_union])]) 407 408 409# b4_value_type_setup 410# ------------------- 411# Check if api.value.type is properly defined, and possibly prepare 412# its use. 413b4_define_silent([b4_value_type_setup], 414[ 415# Define default value. 416b4_percent_define_ifdef([[api.value.type]], [], 417[# %union => api.value.type=union-directive 418m4_ifdef([b4_union_members], 419[m4_define([b4_percent_define_kind(api.value.type)], [keyword]) 420m4_define([b4_percent_define(api.value.type)], [union-directive])], 421[# no tag seen => api.value.type={int} 422m4_if(b4_tag_seen_flag, 0, 423[m4_define([b4_percent_define_kind(api.value.type)], [code]) 424m4_define([b4_percent_define(api.value.type)], [int])], 425[# otherwise api.value.type=yystype 426m4_define([b4_percent_define_kind(api.value.type)], [keyword]) 427m4_define([b4_percent_define(api.value.type)], [yystype])])])]) 428 429# Set up. 430m4_bmatch(b4_percent_define_get_kind([[api.value.type]]), 431 [keyword], [_b4_value_type_setup_keyword]) 432]) 433 434 435## ----------------- ## 436## Semantic Values. ## 437## ----------------- ## 438 439 440# b4_symbol_value(VAL, [SYMBOL-NUM], [TYPE-TAG]) 441# ---------------------------------------------- 442# See README. FIXME: factor in c-like? 443m4_define([b4_symbol_value], 444[m4_ifval([$3], 445 [($1.$3)], 446 [m4_ifval([$2], 447 [b4_symbol_if([$2], [has_type], 448 [($1.b4_symbol([$2], [type]))], 449 [$1])], 450 [$1])])]) 451 452# b4_lhs_value(SYMBOL-NUM, [TYPE]) 453# -------------------------------- 454# See README. 455m4_define([b4_lhs_value], 456[b4_symbol_value([yyval], [$1], [$2])]) 457 458 459# b4_rhs_value(RULE-LENGTH, POS, SYMBOL-NUM, [TYPE]) 460# -------------------------------------------------- 461# See README. 462# 463# In this simple implementation, %token and %type have class names 464# between the angle brackets. 465m4_define([b4_rhs_value], 466[b4_symbol_value([(yystack.valueAt (b4_subtract([$1], [$2])))], [$3], [$4])]) 467 468 469# b4_lhs_location() 470# ----------------- 471# Expansion of @$. 472m4_define([b4_lhs_location], 473[(yyloc)]) 474 475 476# b4_rhs_location(RULE-LENGTH, POS) 477# --------------------------------- 478# Expansion of @POS, where the current rule has RULE-LENGTH symbols 479# on RHS. 480m4_define([b4_rhs_location], 481[yystack.locationAt (b4_subtract($@))]) 482 483 484# b4_lex_param 485# b4_parse_param 486# -------------- 487# If defined, b4_lex_param arrives double quoted, but below we prefer 488# it to be single quoted. Same for b4_parse_param. 489 490# TODO: should be in bison.m4 491m4_define_default([b4_lex_param], [[]])) 492m4_define([b4_lex_param], b4_lex_param)) 493m4_define([b4_parse_param], b4_parse_param)) 494 495# b4_lex_param_decl 496# ------------------- 497# Extra formal arguments of the constructor. 498m4_define([b4_lex_param_decl], 499[m4_ifset([b4_lex_param], 500 [b4_remove_comma([$1], 501 b4_param_decls(b4_lex_param))], 502 [$1])]) 503 504m4_define([b4_param_decls], 505 [m4_map([b4_param_decl], [$@])]) 506m4_define([b4_param_decl], [, $1]) 507 508m4_define([b4_remove_comma], [m4_ifval(m4_quote($1), [$1, ], [])m4_shift2($@)]) 509 510 511 512# b4_parse_param_decl 513# ------------------- 514# Extra formal arguments of the constructor. 515m4_define([b4_parse_param_decl], 516[m4_ifset([b4_parse_param], 517 [b4_remove_comma([$1], 518 b4_param_decls(b4_parse_param))], 519 [$1])]) 520 521 522 523# b4_lex_param_call 524# ------------------- 525# Delegating the lexer parameters to the lexer constructor. 526m4_define([b4_lex_param_call], 527 [m4_ifset([b4_lex_param], 528 [b4_remove_comma([$1], 529 b4_param_calls(b4_lex_param))], 530 [$1])]) 531m4_define([b4_param_calls], 532 [m4_map([b4_param_call], [$@])]) 533m4_define([b4_param_call], [, $2]) 534 535 536 537# b4_parse_param_cons 538# ------------------- 539# Extra initialisations of the constructor. 540m4_define([b4_parse_param_cons], 541 [m4_ifset([b4_parse_param], 542 [b4_constructor_calls(b4_parse_param)])]) 543 544m4_define([b4_constructor_calls], 545 [m4_map([b4_constructor_call], [$@])]) 546m4_define([b4_constructor_call], 547 [this.$2 = $2; 548 ]) 549 550 551 552# b4_parse_param_vars 553# ------------------- 554# Extra instance variables. 555m4_define([b4_parse_param_vars], 556 [m4_ifset([b4_parse_param], 557 [ 558 /* User arguments. */ 559b4_var_decls(b4_parse_param)])]) 560 561m4_define([b4_var_decls], 562 [m4_map_sep([b4_var_decl], [ 563], [$@])]) 564m4_define([b4_var_decl], 565 [ protected $1;]) 566 567 568# b4_public_types_declare 569# ----------------------- 570# Define the public types: token, semantic value, location, and so forth. 571# Depending on %define token_lex, may be output in the header or source file. 572m4_define([b4_public_types_declare], 573[[ 574alias Symbol = ]b4_parser_class[.Symbol; 575alias Value = ]b4_yystype[;]b4_locations_if([[ 576alias Location = ]b4_location_type[; 577alias Position = ]b4_position_type[;]b4_push_if([[ 578alias PUSH_MORE = ]b4_parser_class[.YYPUSH_MORE; 579alias ABORT = ]b4_parser_class[.YYABORT; 580alias ACCEPT = ]b4_parser_class[.YYACCEPT;]])[]])[ 581]]) 582 583 584# b4_basic_symbol_constructor_define 585# ---------------------------------- 586# Create Symbol struct constructors for all the visible types. 587m4_define([b4_basic_symbol_constructor_define], 588[b4_token_visible_if([$1], 589[[ this(TokenKind token]b4_symbol_if([$1], [has_type], 590[[, ]b4_union_if([], [[typeof(YYSemanticType.]])b4_symbol([$1], [type])dnl 591[]b4_union_if([], [[) ]])[ val]])[]b4_locations_if([[, Location loc]])[) 592 { 593 kind = yytranslate_(token);]b4_union_if([b4_symbol_if([$1], [has_type], [[ 594 static foreach (member; __traits(allMembers, YYSemanticType)) 595 { 596 static if (is(typeof(mixin("value_." ~ member)) == ]b4_symbol([$1], [type])[)) 597 { 598 mixin("value_." ~ member ~ " = val;"); 599 } 600 }]])], [b4_symbol_if([$1], [has_type], [[ 601 value_.]b4_symbol([$1], [type])[ = val;]])])[]b4_locations_if([ 602 location_ = loc;])[ 603 } 604]])]) 605 606 607# b4_symbol_type_define 608# --------------------- 609# Define symbol_type, the external type for symbols used for symbol 610# constructors. 611m4_define([b4_symbol_type_define], 612[[ 613 /** 614 * A complete symbol 615 */ 616 struct Symbol 617 { 618 private SymbolKind kind; 619 private Value value_;]b4_locations_if([[ 620 private Location location_;]])[ 621 622]b4_type_foreach([b4_basic_symbol_constructor_define])[ 623 SymbolKind token() { return kind; } 624 Value value() { return value_; }]b4_locations_if([[ 625 Location location() { return location_; }]])[ 626]b4_token_ctor_if([b4_token_constructor_define])[ 627 } 628]]) 629