X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/faef34664a1e4cd7eeaa085e8daaee83d0a85875..9b9e0a7d46123c50e51f6742eba1bfa0d091b8aa:/data/lalr1-fusion.cc diff --git a/data/lalr1-fusion.cc b/data/lalr1-fusion.cc index bae0c49e..20f1cb8c 100644 --- a/data/lalr1-fusion.cc +++ b/data/lalr1-fusion.cc @@ -40,6 +40,12 @@ b4_variant_if([ ]) # b4_variant_if +# b4_assert_if([IF-ASSERTIONS-ARE-USED], [IF-NOT]) +# ---------------------------------------------------- +m4_define([b4_assert_if], +[b4_percent_define_ifdef([[assert]], [$1], [$2])]) + + # b4_rhs_value(RULE-LENGTH, NUM, [TYPE]) # -------------------------------------- # Expansion of $NUM, where the current rule has RULE-LENGTH @@ -85,13 +91,13 @@ m4_define([b4_symbol_action_], ])]) -# b4_symbol_variant(YYTYPE, YYVAL, ACTION) -# ---------------------------------------- +# b4_symbol_variant(YYTYPE, YYVAL, ACTION, [ARGS]) +# ------------------------------------------------ # Run some ACTION ("build", or "destroy") on YYVAL of symbol type # YYTYPE. m4_define([b4_symbol_variant], [m4_pushdef([b4_dollar_dollar], - [$2.$3<$][3>()])dnl + [$2.$3<$][3>(m4_shift3($@))])dnl switch ($1) { m4_map([b4_symbol_action_], m4_defn([b4_type_names])) @@ -161,6 +167,7 @@ dnl FIXME: This is wrong, we want computed header guards. ]b4_percent_code_get([[requires]])[ +]b4_assert_if([#include ])[ #include #include #include "stack.hh" @@ -177,28 +184,31 @@ dnl FIXME: This is wrong, we want computed header guards. /// via the current state. template struct variant - { + {]b4_assert_if([ + /// Whether something is contained. + bool built; + + /// Initially uninitialized. + variant () + : built(false) + {}])[ + /// Instantiate a \a T in here. template inline T& build() - { + {]b4_assert_if([ + assert(!built); + built = true;])[ return *new (buffer) T; } - /// Destroy the stored \a T. - template - inline void - destroy() - { - reinterpret_cast(buffer).~T(); - } - /// Accessor to a built \a T. template inline T& as() - { + {]b4_assert_if([ + assert(built);])[ return reinterpret_cast(buffer); } @@ -206,10 +216,39 @@ dnl FIXME: This is wrong, we want computed header guards. template inline const T& as() const - { + {]b4_assert_if([ + assert(built);])[ return reinterpret_cast(buffer); } + /// Swap the content with \a other. + template + inline void + swap(variant& other) + { + std::swap(as(), other.as()); + } + + /// Assign the content of \a other to this. + /// Destroys \a other. + template + inline void + build(variant& other) + { + build(); + swap(other); + other.destroy(); + } + + /// Destroy the stored \a T. + template + inline void + destroy() + { + as().~T();]b4_assert_if([ + built = false;])[ + } + /// A buffer large enough to store any of the semantic values. char buffer[S]; }; @@ -411,6 +450,7 @@ m4_ifdef([b4_stype], /// \brief Reclaim the memory associated to a symbol. /// \param yymsg Why this token is reclaimed. + /// If null, nothing is printed at all. /// \param yytype The symbol type. /// \param yyvalue Its semantic value. /// \param yylocation Its location. @@ -520,26 +560,26 @@ b4_percent_code_get[]dnl # define YYCDEBUG if (yydebug_) (*yycdebug_) # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug_) \ + do { \ + if (yydebug_) \ { \ *yycdebug_ << Title << ' '; \ yy_symbol_print_ ((Type), (Value), (Location)); \ *yycdebug_ << std::endl; \ } \ -} while (false) + } while (false) # define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug_) \ - yy_reduce_print_ (Rule); \ -} while (false) + do { \ + if (yydebug_) \ + yy_reduce_print_ (Rule); \ + } while (false) # define YY_STACK_PRINT() \ -do { \ - if (yydebug_) \ - yystack_print_ (); \ -} while (false) + do { \ + if (yydebug_) \ + yystack_print_ (); \ + } while (false) #else /* !YYDEBUG */ @@ -654,14 +694,19 @@ do { \ YYUSE (yyvalue); YYUSE (yylocation); - YY_SYMBOL_PRINT (yymsg, yytype, yyvalue, yylocation); + if (yymsg) + YY_SYMBOL_PRINT (yymsg, yytype, yyvalue, yylocation); + // User destructor. switch (yytype) { ]m4_map([b4_symbol_actions], m4_defn([b4_symbol_destructors]))[ default: break; - } + }]b4_variant_if([ + + // Type destructor. + b4_symbol_variant([[yytype]], [[yyvalue]], [[destroy]])])[ } ]b4_parser_class_name[::data_type::data_type () @@ -683,7 +728,10 @@ do { \ ]b4_parser_class_name[::yypush_ (state_type s, semantic_type& v, const location_type& l) { - yystack_.push (data_type (s, v, l)); +]b4_variant_if( +[[ yystack_.push (data_type (s, semantic_type(), l)); + ]b4_symbol_variant([[yystos_[s]]], [[yystack_[0].value]], [build], [v])], +[ yystack_.push (data_type (s, v, l));])[ } void @@ -884,16 +932,21 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], yyval, yyloc); - -]b4_variant_if([ +]b4_variant_if([[ // Destroy the lhs symbols. for (int i = 0; i < yylen; ++i) - { - b4_symbol_variant([[yystos_[yystack_@{i@}.state]]], - [[yystack_@{i@}.value]], - [[destroy]]) - }])dnl -[ + // Destroy a variant which value may have be swapped with yyval. + // The value of yyval (hence maybe one of these lhs symbols) + // depends on what does the default contruction for this type. + // In the case of pointers for instance, nothing is done, so the + // value is junk. Therefore do not try to report the content in + // the debug trace, it's junk. Hence yymsg = 0. Besides, that + // keeps exactly the same traces as with the other Bison + // skeletons. + yydestruct_ (0, + yystos_[yystack_[i].state], + yystack_[i].value, yystack_[i].location);]])[ + yypop_ (yylen); yylen = 0; YY_STACK_PRINT (); @@ -928,9 +981,9 @@ m4_ifdef([b4_lex_param], [, ]b4_lex_param))[; if (yychar <= yyeof_) { - /* Return failure if at end of input. */ - if (yychar == yyeof_) - YYABORT; + /* Return failure if at end of input. */ + if (yychar == yyeof_) + YYABORT; } else {