1 # C++ skeleton for Bison 2 3 # Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc. 4 5 # This program is free software: you can redistribute it and/or modify 6 # it under the terms of the GNU General Public License as published by 7 # the Free Software Foundation, either version 3 of the License, or 8 # (at your option) any later version. 9 # 10 # This program is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU General Public License 16 # along with this program. If not, see <https://www.gnu.org/licenses/>. 17 18 19 ## --------- ## 20 ## variant. ## 21 ## --------- ## 22 23 # b4_assert 24 # --------- 25 # The name of YY_ASSERT. 26 m4_define([b4_assert], 27 [b4_api_PREFIX[]_ASSERT]) 28 29 30 # b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS]) 31 # ------------------------------------------------ 32 # Run some ACTION ("build", or "destroy") on YYVAL of symbol type 33 # YYTYPE. 34 m4_define([b4_symbol_variant], 35 [m4_pushdef([b4_dollar_dollar], 36 [$2.$3< $][3 > (m4_shift3($@))])dnl 37 switch ($1) 38 { 39 b4_type_foreach([_b4_type_action])[]dnl 40 default: 41 break; 42 } 43 m4_popdef([b4_dollar_dollar])dnl 44 ]) 45 46 47 # _b4_char_sizeof_counter 48 # ----------------------- 49 # A counter used by _b4_char_sizeof_dummy to create fresh symbols. 50 m4_define([_b4_char_sizeof_counter], 51 [0]) 52 53 # _b4_char_sizeof_dummy 54 # --------------------- 55 # At each call return a new C++ identifier. 56 m4_define([_b4_char_sizeof_dummy], 57 [m4_define([_b4_char_sizeof_counter], m4_incr(_b4_char_sizeof_counter))dnl 58 dummy[]_b4_char_sizeof_counter]) 59 60 61 # b4_char_sizeof(SYMBOL-NUMS) 62 # --------------------------- 63 # To be mapped on the list of type names to produce: 64 # 65 # char dummy1[sizeof (type_name_1)]; 66 # char dummy2[sizeof (type_name_2)]; 67 # 68 # for defined type names. 69 m4_define([b4_char_sizeof], 70 [b4_symbol_if([$1], [has_type], 71 [ 72 m4_map([ b4_symbol_tag_comment], [$@])dnl 73 char _b4_char_sizeof_dummy@{sizeof (b4_symbol([$1], [type]))@}; 74 ])]) 75 76 77 # b4_variant_includes 78 # ------------------- 79 # The needed includes for variants support. 80 m4_define([b4_variant_includes], 81 [b4_parse_assert_if([[#include <typeinfo> 82 #ifndef ]b4_assert[ 83 # include <cassert> 84 # define ]b4_assert[ assert 85 #endif 86 ]])]) 87 88 89 90 ## -------------------------- ## 91 ## Adjustments for variants. ## 92 ## -------------------------- ## 93 94 95 # b4_value_type_declare 96 # --------------------- 97 # Define value_type. 98 m4_define([b4_value_type_declare], 99 [[ /// A buffer to store and retrieve objects. 100 /// 101 /// Sort of a variant, but does not keep track of the nature 102 /// of the stored data, since that knowledge is available 103 /// via the current parser state. 104 class value_type 105 { 106 public: 107 /// Type of *this. 108 typedef value_type self_type; 109 110 /// Empty construction. 111 value_type () YY_NOEXCEPT 112 : yyraw_ ()]b4_parse_assert_if([ 113 , yytypeid_ (YY_NULLPTR)])[ 114 {} 115 116 /// Construct and fill. 117 template <typename T> 118 value_type (YY_RVREF (T) t)]b4_parse_assert_if([ 119 : yytypeid_ (&typeid (T))])[ 120 {]b4_parse_assert_if([[ 121 ]b4_assert[ (sizeof (T) <= size);]])[ 122 new (yyas_<T> ()) T (YY_MOVE (t)); 123 } 124 125 #if 201103L <= YY_CPLUSPLUS 126 /// Non copyable. 127 value_type (const self_type&) = delete; 128 /// Non copyable. 129 self_type& operator= (const self_type&) = delete; 130 #endif 131 132 /// Destruction, allowed only if empty. 133 ~value_type () YY_NOEXCEPT 134 {]b4_parse_assert_if([ 135 ]b4_assert[ (!yytypeid_); 136 ])[} 137 138 # if 201103L <= YY_CPLUSPLUS 139 /// Instantiate a \a T in here from \a t. 140 template <typename T, typename... U> 141 T& 142 emplace (U&&... u) 143 {]b4_parse_assert_if([[ 144 ]b4_assert[ (!yytypeid_); 145 ]b4_assert[ (sizeof (T) <= size); 146 yytypeid_ = & typeid (T);]])[ 147 return *new (yyas_<T> ()) T (std::forward <U>(u)...); 148 } 149 # else 150 /// Instantiate an empty \a T in here. 151 template <typename T> 152 T& 153 emplace () 154 {]b4_parse_assert_if([[ 155 ]b4_assert[ (!yytypeid_); 156 ]b4_assert[ (sizeof (T) <= size); 157 yytypeid_ = & typeid (T);]])[ 158 return *new (yyas_<T> ()) T (); 159 } 160 161 /// Instantiate a \a T in here from \a t. 162 template <typename T> 163 T& 164 emplace (const T& t) 165 {]b4_parse_assert_if([[ 166 ]b4_assert[ (!yytypeid_); 167 ]b4_assert[ (sizeof (T) <= size); 168 yytypeid_ = & typeid (T);]])[ 169 return *new (yyas_<T> ()) T (t); 170 } 171 # endif 172 173 /// Instantiate an empty \a T in here. 174 /// Obsolete, use emplace. 175 template <typename T> 176 T& 177 build () 178 { 179 return emplace<T> (); 180 } 181 182 /// Instantiate a \a T in here from \a t. 183 /// Obsolete, use emplace. 184 template <typename T> 185 T& 186 build (const T& t) 187 { 188 return emplace<T> (t); 189 } 190 191 /// Accessor to a built \a T. 192 template <typename T> 193 T& 194 as () YY_NOEXCEPT 195 {]b4_parse_assert_if([[ 196 ]b4_assert[ (yytypeid_); 197 ]b4_assert[ (*yytypeid_ == typeid (T)); 198 ]b4_assert[ (sizeof (T) <= size);]])[ 199 return *yyas_<T> (); 200 } 201 202 /// Const accessor to a built \a T (for %printer). 203 template <typename T> 204 const T& 205 as () const YY_NOEXCEPT 206 {]b4_parse_assert_if([[ 207 ]b4_assert[ (yytypeid_); 208 ]b4_assert[ (*yytypeid_ == typeid (T)); 209 ]b4_assert[ (sizeof (T) <= size);]])[ 210 return *yyas_<T> (); 211 } 212 213 /// Swap the content with \a that, of same type. 214 /// 215 /// Both variants must be built beforehand, because swapping the actual 216 /// data requires reading it (with as()), and this is not possible on 217 /// unconstructed variants: it would require some dynamic testing, which 218 /// should not be the variant's responsibility. 219 /// Swapping between built and (possibly) non-built is done with 220 /// self_type::move (). 221 template <typename T> 222 void 223 swap (self_type& that) YY_NOEXCEPT 224 {]b4_parse_assert_if([[ 225 ]b4_assert[ (yytypeid_); 226 ]b4_assert[ (*yytypeid_ == *that.yytypeid_);]])[ 227 std::swap (as<T> (), that.as<T> ()); 228 } 229 230 /// Move the content of \a that to this. 231 /// 232 /// Destroys \a that. 233 template <typename T> 234 void 235 move (self_type& that) 236 { 237 # if 201103L <= YY_CPLUSPLUS 238 emplace<T> (std::move (that.as<T> ())); 239 # else 240 emplace<T> (); 241 swap<T> (that); 242 # endif 243 that.destroy<T> (); 244 } 245 246 # if 201103L <= YY_CPLUSPLUS 247 /// Move the content of \a that to this. 248 template <typename T> 249 void 250 move (self_type&& that) 251 { 252 emplace<T> (std::move (that.as<T> ())); 253 that.destroy<T> (); 254 } 255 #endif 256 257 /// Copy the content of \a that to this. 258 template <typename T> 259 void 260 copy (const self_type& that) 261 { 262 emplace<T> (that.as<T> ()); 263 } 264 265 /// Destroy the stored \a T. 266 template <typename T> 267 void 268 destroy () 269 { 270 as<T> ().~T ();]b4_parse_assert_if([ 271 yytypeid_ = YY_NULLPTR;])[ 272 } 273 274 private: 275 #if YY_CPLUSPLUS < 201103L 276 /// Non copyable. 277 value_type (const self_type&); 278 /// Non copyable. 279 self_type& operator= (const self_type&); 280 #endif 281 282 /// Accessor to raw memory as \a T. 283 template <typename T> 284 T* 285 yyas_ () YY_NOEXCEPT 286 { 287 void *yyp = yyraw_; 288 return static_cast<T*> (yyp); 289 } 290 291 /// Const accessor to raw memory as \a T. 292 template <typename T> 293 const T* 294 yyas_ () const YY_NOEXCEPT 295 { 296 const void *yyp = yyraw_; 297 return static_cast<const T*> (yyp); 298 } 299 300 /// An auxiliary type to compute the largest semantic type. 301 union union_type 302 {]b4_type_foreach([b4_char_sizeof])[ }; 303 304 /// The size of the largest semantic type. 305 enum { size = sizeof (union_type) }; 306 307 /// A buffer to store semantic values. 308 union 309 { 310 /// Strongest alignment constraints. 311 long double yyalign_me_; 312 /// A buffer large enough to store any of the semantic values. 313 char yyraw_[size]; 314 };]b4_parse_assert_if([ 315 316 /// Whether the content is built: if defined, the name of the stored type. 317 const std::type_info *yytypeid_;])[ 318 }; 319 ]]) 320 321 322 # How the semantic value is extracted when using variants. 323 324 # b4_symbol_value(VAL, SYMBOL-NUM, [TYPE]) 325 # ---------------------------------------- 326 # See README. 327 m4_define([b4_symbol_value], 328 [m4_ifval([$3], 329 [$1.as< $3 > ()], 330 [m4_ifval([$2], 331 [b4_symbol_if([$2], [has_type], 332 [$1.as < b4_symbol([$2], [type]) > ()], 333 [$1])], 334 [$1])])]) 335 336 # b4_symbol_value_template(VAL, SYMBOL-NUM, [TYPE]) 337 # ------------------------------------------------- 338 # Same as b4_symbol_value, but used in a template method. 339 m4_define([b4_symbol_value_template], 340 [m4_ifval([$3], 341 [$1.template as< $3 > ()], 342 [m4_ifval([$2], 343 [b4_symbol_if([$2], [has_type], 344 [$1.template as < b4_symbol([$2], [type]) > ()], 345 [$1])], 346 [$1])])]) 347 348 349 350 ## ------------- ## 351 ## make_SYMBOL. ## 352 ## ------------- ## 353 354 355 # _b4_includes_tokens(SYMBOL-NUM...) 356 # ---------------------------------- 357 # Expands to non-empty iff one of the SYMBOL-NUM denotes 358 # a token. 359 m4_define([_b4_is_token], 360 [b4_symbol_if([$1], [is_token], [1])]) 361 m4_define([_b4_includes_tokens], 362 [m4_map([_b4_is_token], [$@])]) 363 364 365 # _b4_token_maker_define(SYMBOL-NUM) 366 # ---------------------------------- 367 # Declare make_SYMBOL for SYMBOL-NUM. Use at class-level. 368 m4_define([_b4_token_maker_define], 369 [b4_token_visible_if([$1], 370 [#if 201103L <= YY_CPLUSPLUS 371 static 372 symbol_type 373 make_[]_b4_symbol([$1], [id]) (b4_join( 374 b4_symbol_if([$1], [has_type], 375 [b4_symbol([$1], [type]) v]), 376 b4_locations_if([location_type l]))) 377 { 378 return symbol_type (b4_join([token::b4_symbol([$1], [id])], 379 b4_symbol_if([$1], [has_type], [std::move (v)]), 380 b4_locations_if([std::move (l)]))); 381 } 382 #else 383 static 384 symbol_type 385 make_[]_b4_symbol([$1], [id]) (b4_join( 386 b4_symbol_if([$1], [has_type], 387 [const b4_symbol([$1], [type])& v]), 388 b4_locations_if([const location_type& l]))) 389 { 390 return symbol_type (b4_join([token::b4_symbol([$1], [id])], 391 b4_symbol_if([$1], [has_type], [v]), 392 b4_locations_if([l]))); 393 } 394 #endif 395 ])]) 396 397 398 # b4_token_kind(SYMBOL-NUM) 399 # ------------------------- 400 # Some tokens don't have an ID. 401 m4_define([b4_token_kind], 402 [b4_symbol_if([$1], [has_id], 403 [token::b4_symbol([$1], [id])], 404 [b4_symbol([$1], [code])])]) 405 406 407 # _b4_tok_in(SYMBOL-NUM, ...) 408 # --------------------------- 409 # See b4_tok_in below. The SYMBOL-NUMs... are tokens only. 410 # 411 # We iterate over the tokens to group them by "range" of token numbers (not 412 # symbols numbers!). 413 # 414 # b4_fst is the start of that range. 415 # b4_prev is the previous value. 416 # b4_val is the current value. 417 # If b4_val is the successor of b4_prev in token numbers, update the latter, 418 # otherwise emit the code for range b4_fst .. b4_prev. 419 # $1 is also used as a terminator in the foreach, but it will not be printed. 420 # 421 m4_define([_b4_tok_in], 422 [m4_pushdef([b4_prev], [$1])dnl 423 m4_pushdef([b4_fst], [$1])dnl 424 m4_pushdef([b4_sep], [])dnl 425 m4_foreach([b4_val], m4_dquote(m4_shift($@, $1)), 426 [m4_if(b4_symbol(b4_val, [code]), m4_eval(b4_symbol(b4_prev, [code]) + 1), [], 427 [b4_sep[]m4_if(b4_fst, b4_prev, 428 [tok == b4_token_kind(b4_fst)], 429 [(b4_token_kind(b4_fst) <= tok && tok <= b4_token_kind(b4_prev))])[]dnl 430 m4_define([b4_fst], b4_val)dnl 431 m4_define([b4_sep], [ 432 || ])])dnl 433 m4_define([b4_prev], b4_val)])dnl 434 m4_popdef([b4_sep])dnl 435 m4_popdef([b4_fst])dnl 436 m4_popdef([b4_prev])dnl 437 ]) 438 439 440 # _b4_filter_tokens(SYMBOL-NUM, ...) 441 # ---------------------------------- 442 # Expand as the list of tokens amongst SYMBOL-NUM. 443 m4_define([_b4_filter_tokens], 444 [m4_pushdef([b4_sep])dnl 445 m4_foreach([b4_val], [$@], 446 [b4_symbol_if(b4_val, [is_token], [b4_sep[]b4_val[]m4_define([b4_sep], [,])])])dnl 447 m4_popdef([b4_sep])dnl 448 ]) 449 450 451 # b4_tok_in(SYMBOL-NUM, ...) 452 # --------------------------- 453 # A C++ conditional that checks that `tok` is a member of this list of symbol 454 # numbers. 455 m4_define([b4_tok_in], 456 [_$0(_b4_filter_tokens($@))]) 457 458 459 460 461 # _b4_symbol_constructor_define(SYMBOL-NUM...) 462 # -------------------------------------------- 463 # Define a symbol_type constructor common to all the SYMBOL-NUM (they 464 # have the same type). Use at class-level. 465 m4_define([_b4_symbol_constructor_define], 466 [m4_ifval(_b4_includes_tokens($@), 467 [[#if 201103L <= YY_CPLUSPLUS 468 symbol_type (]b4_join( 469 [int tok], 470 b4_symbol_if([$1], [has_type], 471 [b4_symbol([$1], [type]) v]), 472 b4_locations_if([location_type l]))[) 473 : super_type (]b4_join([token_kind_type (tok)], 474 b4_symbol_if([$1], [has_type], [std::move (v)]), 475 b4_locations_if([std::move (l)]))[) 476 #else 477 symbol_type (]b4_join( 478 [int tok], 479 b4_symbol_if([$1], [has_type], 480 [const b4_symbol([$1], [type])& v]), 481 b4_locations_if([const location_type& l]))[) 482 : super_type (]b4_join([token_kind_type (tok)], 483 b4_symbol_if([$1], [has_type], [v]), 484 b4_locations_if([l]))[) 485 #endif 486 {]b4_parse_assert_if([[ 487 #if !defined _MSC_VER || defined __clang__ 488 ]b4_assert[ (]b4_tok_in($@)[); 489 #endif 490 ]])[} 491 ]])]) 492 493 494 # b4_basic_symbol_constructor_define(SYMBOL-NUM) 495 # ---------------------------------------------- 496 # Generate a constructor for basic_symbol from given type. 497 m4_define([b4_basic_symbol_constructor_define], 498 [[#if 201103L <= YY_CPLUSPLUS 499 basic_symbol (]b4_join( 500 [typename Base::kind_type t], 501 b4_symbol_if([$1], [has_type], [b4_symbol([$1], [type])&& v]), 502 b4_locations_if([location_type&& l]))[) 503 : Base (t)]b4_symbol_if([$1], [has_type], [ 504 , value (std::move (v))])[]b4_locations_if([ 505 , location (std::move (l))])[ 506 {} 507 #else 508 basic_symbol (]b4_join( 509 [typename Base::kind_type t], 510 b4_symbol_if([$1], [has_type], [const b4_symbol([$1], [type])& v]), 511 b4_locations_if([const location_type& l]))[) 512 : Base (t)]b4_symbol_if([$1], [has_type], [ 513 , value (v)])[]b4_locations_if([ 514 , location (l)])[ 515 {} 516 #endif 517 ]]) 518 519 520 # b4_token_constructor_define 521 # --------------------------- 522 # Define the overloaded versions of make_FOO for all the token kinds. 523 m4_define([b4_token_constructor_define], 524 [ // Implementation of make_symbol for each token kind. 525 b4_symbol_foreach([_b4_token_maker_define])]) 526