bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

c++: give public access to the symbol kind


From: Akim Demaille
Subject: c++: give public access to the symbol kind
Date: Sat, 18 Apr 2020 08:17:10 +0200

commit d6ae95fb50317fc3ffee018bfc4a6358da04332a
Author: Akim Demaille <address@hidden>
Date:   Fri Apr 17 08:51:18 2020 +0200

    c++: give public access to the symbol kind
    
    symbol_type::token () was removed: it returned the token kind of a
    symbol.  To do that, one needs to convert from the symbol kind to the
    token kind, which requires a table.
    
    This broke some users' unit tests for scanners, see
    https://lists.gnu.org/r/bug-bison/2020-01/msg00001.html
    https://lists.gnu.org/r/bug-bison/2020-03/msg00020.html
    https://lists.gnu.org/r/help-bison/2020-04/msg00005.html
    
    Instead of making this possible again, let's check the symbol's kind
    instead.  So give proper access to a symbol's kind.
    
    That feature existed, undocumented, as 'type_get()'.  Let's rename
    this as 'kind()'.
    
    * data/skeletons/c++.m4, data/skeletons/glr.cc,
    * data/skeletons/lalr1.cc (type_get): Rename as...
    (kind): This.
    (type_get): Install a backward compatibility alias.
    * doc/bison.texi (Complete Symbols): Document symbol_type and
    symbol_type::kind.

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<int> () == 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 <typename Base>
@@ -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<Base>& 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 <typename Base>
+  ]b4_parser_class[::symbol_kind_type
+  ]b4_parser_class[::basic_symbol<Base>::type_get () const YY_NOEXCEPT
+  {
+    return this->kind ();
+  }
 
   template <typename Base>
   bool
   ]b4_parser_class[::basic_symbol<Base>::empty () const YY_NOEXCEPT
   {
-    return Base::type_get () == symbol_kind::]b4_symbol_prefix[YYEMPTY;
+    return this->kind () == symbol_kind::]b4_symbol_prefix[YYEMPTY;
   }
 
   template <typename Base>
@@ -476,7 +486,7 @@ m4_define([b4_public_types_define],
   ]b4_parser_class[::basic_symbol<Base>::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 <typename Base>
@@ -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})




reply via email to

[Prev in Thread] Current Thread [Next in Thread]