diff --git a/NEWS b/NEWS index f794bfe6..b3de1c2e 100644 --- a/NEWS +++ b/NEWS @@ -73,8 +73,8 @@ GNU Bison NEWS **** Token aliases internationalization When the %define variable parse.error is set to `custom` or `detailed`, - one may use the _() annotation to specify which token aliases are to be - translated. For instance + one may specify which token aliases are to be translated using _(). For + instance %token PLUS "+" @@ -163,6 +163,18 @@ GNU Bison NEWS Contributed by Victor Morales Cayuela. +*** C++ + + The token and symbol kinds are yy::parser::token_kind_type and + yy::parser::symbol_kind_type. + + The symbol_type::kind() member function allows to get the kind of a + symbol. This can be used to write unit tests for scanners, e.g., + + yy::parser::symbol_type t = make_NUMBER ("123"); + assert (t.kind () == yy::parser::symbol_kind::S_NUMBER); + assert (t.value.as () == 123); + ** Documentation *** User Manual diff --git a/TODO b/TODO index e1466cb8..4d2a8acb 100644 --- a/TODO +++ b/TODO @@ -16,7 +16,6 @@ ** Documentation - YYERRCODE, YYUNDEF, YYEOF -- symbol.type_get should be kind_get, and it's not documented. - YYERRCODE and translation ** Java diff --git a/data/skeletons/c++.m4 b/data/skeletons/c++.m4 index d5f94d15..d509fb44 100644 --- a/data/skeletons/c++.m4 +++ b/data/skeletons/c++.m4 @@ -290,8 +290,8 @@ m4_define([b4_public_types_declare], m4_define([b4_symbol_type_define], [[ /// A complete symbol. /// - /// Expects its Base type to provide access to the symbol type - /// via type_get (). + /// Expects its Base type to provide access to the symbol kind + /// via kind (). /// /// Provide access to semantic value]b4_locations_if([ and location])[. template @@ -313,7 +313,7 @@ m4_define([b4_symbol_type_define], , value (]b4_variant_if([], [std::move (that.value)]))b4_locations_if([ , location (std::move (that.location))])[ {]b4_variant_if([ - b4_symbol_variant([this->type_get ()], [value], [move], + b4_symbol_variant([this->kind ()], [value], [move], [std::move (that.value)]) ])[} #endif @@ -342,7 +342,7 @@ m4_define([b4_symbol_type_define], void clear () {]b4_variant_if([[ // User destructor. - symbol_kind_type yykind = this->type_get (); + symbol_kind_type yykind = this->kind (); basic_symbol& yysym = *this; (void) yysym; switch (yykind) @@ -357,6 +357,9 @@ m4_define([b4_symbol_type_define], Base::clear (); } + /// Backward compatibility. + symbol_kind_type type_get () const YY_NOEXCEPT; + /// Whether empty. bool empty () const YY_NOEXCEPT; @@ -390,7 +393,7 @@ m4_define([b4_symbol_type_define], /// Copy constructor. by_type (const by_type& that); - /// The symbol type as needed by the constructor. + /// The symbol kind as needed by the constructor. typedef token_kind_type kind_type; /// Constructor from (external) token numbers. @@ -399,14 +402,14 @@ m4_define([b4_symbol_type_define], /// Record that this symbol is empty. void clear (); - /// Steal the symbol type from \a that. + /// Steal the symbol kind from \a that. void move (by_type& that); /// The (internal) type number (corresponding to \a type). /// \a empty when empty. - symbol_kind_type type_get () const YY_NOEXCEPT; + symbol_kind_type kind () const YY_NOEXCEPT; - /// The symbol type. + /// The symbol kind. /// \a ]b4_symbol_prefix[YYEMPTY when empty. symbol_kind_type type; }; @@ -437,7 +440,7 @@ m4_define([b4_public_types_define], , value (]b4_variant_if([], [that.value]))b4_locations_if([ , location (that.location)])[ {]b4_variant_if([ - b4_symbol_variant([this->type_get ()], [value], [copy], + b4_symbol_variant([this->kind ()], [value], [copy], [YY_MOVE (that.value)]) ])[} @@ -462,13 +465,20 @@ m4_define([b4_public_types_define], , location (YY_MOVE (l))])[ {]b4_variant_if([[ (void) v; - ]b4_symbol_variant([this->type_get ()], [value], [YY_MOVE_OR_COPY], [YY_MOVE (v)])])[}]])[ + ]b4_symbol_variant([this->kind ()], [value], [YY_MOVE_OR_COPY], [YY_MOVE (v)])])[}]])[ + + template + ]b4_parser_class[::symbol_kind_type + ]b4_parser_class[::basic_symbol::type_get () const YY_NOEXCEPT + { + return this->kind (); + } template bool ]b4_parser_class[::basic_symbol::empty () const YY_NOEXCEPT { - return Base::type_get () == symbol_kind::]b4_symbol_prefix[YYEMPTY; + return this->kind () == symbol_kind::]b4_symbol_prefix[YYEMPTY; } template @@ -476,7 +486,7 @@ m4_define([b4_public_types_define], ]b4_parser_class[::basic_symbol::move (basic_symbol& s) { super_type::move (s); - ]b4_variant_if([b4_symbol_variant([this->type_get ()], [value], [move], + ]b4_variant_if([b4_symbol_variant([this->kind ()], [value], [move], [YY_MOVE (s.value)])], [value = YY_MOVE (s.value);])[]b4_locations_if([ location = YY_MOVE (s.location);])[ @@ -517,7 +527,7 @@ m4_define([b4_public_types_define], } ]b4_inline([$1])[]b4_parser_class[::symbol_kind_type - ]b4_parser_class[::by_type::type_get () const YY_NOEXCEPT + ]b4_parser_class[::by_type::kind () const YY_NOEXCEPT { return type; } diff --git a/data/skeletons/glr.cc b/data/skeletons/glr.cc index 8eb762cf..e931dd4b 100644 --- a/data/skeletons/glr.cc +++ b/data/skeletons/glr.cc @@ -107,7 +107,7 @@ yyerror (]b4_locations_if([[const ]b4_namespace_ref::b4_parser_class[::location_ ]b4_percent_define_flag_if([[global_tokens_and_yystype]], [], [m4_define([b4_pre_epilogue], -[[/* The user is using the C++ token type, not the C one. */ +[[/* The user is using the C++ token kind, not the C one. */ #undef ]b4_symbol(0, [id]) ])])[ diff --git a/data/skeletons/lalr1.cc b/data/skeletons/lalr1.cc index e9ad255c..8c6aa930 100644 --- a/data/skeletons/lalr1.cc +++ b/data/skeletons/lalr1.cc @@ -241,7 +241,7 @@ m4_define([b4_shared_declarations], public: context (const ]b4_parser_class[& yyparser, const symbol_type& yyla); const symbol_type& lookahead () const { return yyla_; } - symbol_kind_type token () const { return yyla_.type_get (); }]b4_locations_if([[ + symbol_kind_type token () const { return yyla_.kind (); }]b4_locations_if([[ const location_type& location () const { return yyla_.location; } ]])[ /// Put in YYARG at most YYARGN of the expected tokens, and return the @@ -340,7 +340,7 @@ m4_define([b4_shared_declarations], /// Debug stream. std::ostream* yycdebug_; - /// \brief Display a symbol type, value and location. + /// \brief Display a symbol kind, value and location. /// \param yyo The output stream. /// \param yysym The symbol. template @@ -373,12 +373,12 @@ m4_define([b4_shared_declarations], /// Record that this symbol is empty. void clear () YY_NOEXCEPT; - /// Steal the symbol type from \a that. + /// Steal the symbol kind from \a that. void move (by_state& that); /// The symbol kind (corresponding to \a state). /// \a ]b4_symbol(-2, kind)[ when empty. - symbol_kind_type type_get () const YY_NOEXCEPT; + symbol_kind_type kind () const YY_NOEXCEPT; /// The state number used to denote an empty symbol. /// We use the initial state, as it does not have a value. @@ -665,7 +665,7 @@ b4_parse_error_case([verbose], [[ {} /*---------------. - | Symbol types. | + | symbol kinds. | `---------------*/ ]b4_token_ctor_if([], [b4_public_types_define([cc])])[ @@ -697,7 +697,7 @@ b4_parse_error_case([verbose], [[ {} ]b4_parser_class[::symbol_kind_type - ]b4_parser_class[::by_state::type_get () const YY_NOEXCEPT + ]b4_parser_class[::by_state::kind () const YY_NOEXCEPT { if (state == empty_state) return symbol_kind::]b4_symbol(-2, kind)[; @@ -711,7 +711,7 @@ b4_parse_error_case([verbose], [[ ]b4_parser_class[::stack_symbol_type::stack_symbol_type (YY_RVREF (stack_symbol_type) that) : super_type (YY_MOVE (that.state)]b4_variant_if([], [, YY_MOVE (that.value)])b4_locations_if([, YY_MOVE (that.location)])[) {]b4_variant_if([ - b4_symbol_variant([that.type_get ()], + b4_symbol_variant([that.kind ()], [value], [YY_MOVE_OR_COPY], [YY_MOVE (that.value)])])[ #if 201103L <= YY_CPLUSPLUS // that is emptied. @@ -722,7 +722,7 @@ b4_parse_error_case([verbose], [[ ]b4_parser_class[::stack_symbol_type::stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) that) : super_type (s]b4_variant_if([], [, YY_MOVE (that.value)])[]b4_locations_if([, YY_MOVE (that.location)])[) {]b4_variant_if([ - b4_symbol_variant([that.type_get ()], + b4_symbol_variant([that.kind ()], [value], [move], [YY_MOVE (that.value)])])[ // that is emptied. that.type = symbol_kind::]b4_symbol(-2, kind)[; @@ -733,7 +733,7 @@ b4_parse_error_case([verbose], [[ ]b4_parser_class[::stack_symbol_type::operator= (const stack_symbol_type& that) { state = that.state; - ]b4_variant_if([b4_symbol_variant([that.type_get ()], + ]b4_variant_if([b4_symbol_variant([that.kind ()], [value], [copy], [that.value])], [[value = that.value;]])[]b4_locations_if([ location = that.location;])[ @@ -744,7 +744,7 @@ b4_parse_error_case([verbose], [[ ]b4_parser_class[::stack_symbol_type::operator= (stack_symbol_type& that) { state = that.state; - ]b4_variant_if([b4_symbol_variant([that.type_get ()], + ]b4_variant_if([b4_symbol_variant([that.kind ()], [value], [move], [that.value])], [[value = that.value;]])[]b4_locations_if([ location = that.location;])[ @@ -762,7 +762,7 @@ b4_parse_error_case([verbose], [[ YY_SYMBOL_PRINT (yymsg, yysym);]b4_variant_if([], [ // User destructor. - b4_symbol_actions([destructor], [yysym.type_get ()])])[ + b4_symbol_actions([destructor], [yysym.kind ()])])[ } #if ]b4_api_PREFIX[DEBUG @@ -773,7 +773,7 @@ b4_parse_error_case([verbose], [[ { std::ostream& yyoutput = yyo; YYUSE (yyoutput); - symbol_kind_type yykind = yysym.type_get (); + symbol_kind_type yykind = yysym.kind (); #if defined __GNUC__ && ! defined __clang__ && ! defined __ICC && __GNUC__ * 100 + __GNUC_MINOR__ <= 408 // Avoid a (spurious) G++ 4.8 warning about "array subscript is // below array bounds". @@ -958,10 +958,10 @@ b4_dollar_popdef])[]dnl /* If the proper action on seeing token YYLA.TYPE is to reduce or to detect an error, take that action. */ - yyn += yyla.type_get (); - if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ()) + yyn += yyla.kind (); + if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.kind ()) {]b4_lac_if([[ - if (!yy_lac_establish_ (yyla.type_get ())) + if (!yy_lac_establish_ (yyla.kind ())) goto yyerrlab;]])[ goto yydefault; } @@ -972,7 +972,7 @@ b4_dollar_popdef])[]dnl { if (yy_table_value_is_error_ (yyn)) goto yyerrlab;]b4_lac_if([[ - if (!yy_lac_establish_ (yyla.type_get ())) + if (!yy_lac_establish_ (yyla.kind ())) goto yyerrlab; ]])[ yyn = -yyn; @@ -1089,7 +1089,7 @@ b4_dollar_popdef])[]dnl error, discard it. */ // Return failure if at end of input. - if (yyla.type_get () == symbol_kind::]b4_symbol_prefix[YYEOF) + if (yyla.kind () == symbol_kind::]b4_symbol_prefix[YYEOF) YYABORT; else if (!yyla.empty ()) { @@ -1240,7 +1240,7 @@ b4_dollar_popdef])[]dnl // Execute LAC once. We don't care if it is successful, we // only do it for the sake of debugging output. if (!yyparser_.yy_lac_established_) - yyparser_.yy_lac_check_ (yyla_.type_get ()); + yyparser_.yy_lac_check_ (yyla_.kind ()); #endif for (int yyx = 0; yyx < YYNTOKENS; ++yyx) diff --git a/doc/bison.texi b/doc/bison.texi index f9794ecf..3ed36098 100644 --- a/doc/bison.texi +++ b/doc/bison.texi @@ -12193,6 +12193,17 @@ location. Invocations of @samp{%lex-param @{@var{type1} @var{arg1}@}} yield additional arguments. @end deftypefun +@defcv {Type} {parser} {symbol_type} +A ``complete symbol'', that binds together its kind, value and (when +applicable) location. +@end defcv + +@deftypemethod {symbol_type} {symbol_kind_type} kind () @code{const} +The kind of this symbol. +@end deftypemethod + +@sp 1 + For each token kind, Bison generates named constructors as follows. @deftypeop {Constructor} {parser::symbol_type} {} {symbol_type} (@code{int} @var{token}, @code{const @var{value_type}&} @var{value}, @code{const location_type&} @var{location})