bison-patches
[Top][All Lists]
Advanced

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

Re: [PATCH 1/6] api.value.type: implement proper support, check, and doc


From: Akim Demaille
Subject: Re: [PATCH 1/6] api.value.type: implement proper support, check, and document
Date: Mon, 25 Feb 2013 11:20:58 +0100

Le 23 févr. 2013 à 17:00, Akim Demaille <address@hidden> a écrit :

> * data/c.m4 (b4_symbol_type_register, b4_type_define_tag)
> (b4_symbol_value_union, b4_value_type_setup_union)
> (b4_value_type_setup_variant, b4_value_type_setup):
> New.
> (b4_value_type_define): Use it to set up properly the type.
> Handle the various possible values of api.value.type.
> * data/c++.m4 (b4_value_type_declare): Likewise.
> * data/lalr1.cc (b4_value_type_setup_variant): Redefine.
> 
> * tests/types.at: New.
> Exercise all the C/C++ skeletons with different types of
> api.value.type values.
> * tests/local.mk, tests/testsuite.at: Use it.
> 
> * doc/bison.texi (%define Summary): Document api.value.type.
> * NEWS: Advertise it, together with api.token.constructor.

I will squash the following patch in this one.  The point is
to be even clearer in NEWS, and also to fix issues with %printer
and %destructor (for a while I meant to turn api.value.type=union
into the same situation as with %union, assigning each symbol
a forged tag.  But this is wrong, as the real key to use to
manipulate the symbols is its genuine type, not a union member
name, for things like %printer and %destructor, but also
explicit "casts" such as $<int>$).


commit 36bb498d99742a0cc8c3499f5935da181bcca1f2
Author: Akim Demaille <address@hidden>
Date:   Mon Feb 25 11:20:08 2013 +0100

    squash! api.value.type: implement proper support, check, and document

diff --git a/NEWS b/NEWS
index 0aabc13..7af59ea 100644
--- a/NEWS
+++ b/NEWS
@@ -255,11 +255,11 @@ GNU Bison NEWS
 ** Variable api.value.type
 
   This new %define variable supersedes the #define macro YYSTYPE.  The use
-  of YYSTYPE is discouraged.  In particular, #defining YYTSYPE *and* using
+  of YYSTYPE is discouraged.  In particular, #defining YYSTYPE *and* using
   %union or %defining api.value.type results in undefined behavior.
 
   The %define variable api.value.type supports several special values,
-  examplified below:
+  exemplified below:
 
   The value "%union" denotes that fact that %union is used.
 
@@ -270,29 +270,33 @@ GNU Bison NEWS
       char *sval;
     }
     %token <ival> INT "integer"
-    %token <sval> STR "string"
+    %token <sval> STRING "string"
+    %printer { fprintf (yyo, "%d", $$); } <ival>
+    %destructor { free ($$); } <sval>
 
     /* In yylex().  */
     yylval.ival = 42; return INT;
-    yylval.sval = "42"; return STR;
+    yylval.sval = "42"; return STRING;
 
-  The value "union" means that the user provides genuine types, not
-  union members names such as "ival" and "sval" above.
+  The value "union" means that the user provides genuine types, not union
+  member names such as "ival" and "sval" above.
 
     %define api.value.type "union"
     %token <int> INT "integer"
-    %token <char *> STR "string"
+    %token <char *> STRING "string"
+    %printer { fprintf (yyo, "%d", $$); } <int>
+    %destructor { free ($$); } <char *>
 
     /* In yylex().  */
     yylval.yytype_INT = 42; return INT;
-    yylval.yytype_STR = "42"; return STR;
+    yylval.yytype_STRING = "42"; return STRING;
 
   The value "variant" is somewhat equivalent, but for C++ special provision
-  is made to allow classes to be used.
+  is made to allow classes to be used (more about this below).
 
     %define api.value.type "variant"
     %token <int> INT "integer"
-    %token <std::string> STR "string"
+    %token <std::string> STRING "string"
 
   Any other name is a user type to use.  This is where YYSTYPE used to be
   used.
@@ -303,7 +307,7 @@ GNU Bison NEWS
       {
         enum
         {
-          is_int, is_str
+          is_int, is_string
         } kind;
         union
         {
@@ -314,11 +318,13 @@ GNU Bison NEWS
     }
     %define api.value.type "struct my_value"
     %token <u.ival> INT "integer"
-    %token <u.sval> STR "string"
+    %token <u.sval> STRING "string"
+    %printer { fprintf (yyo, "%d", $$); } <u.ival>
+    %destructor { free ($$); } <u.sval>
 
     /* In yylex().  */
     yylval.u.ival = 42; return INT;
-    yylval.u.sval = "42"; return STR;
+    yylval.u.sval = "42"; return STRING;
 
 ** Variable parse.error
 
@@ -2588,7 +2594,7 @@ along with this program.  If not, see 
<http://www.gnu.org/licenses/>.
  LocalWords:  Wprecedence Rassoul Wempty Paolo Bonzini parser's Michiel loc
  LocalWords:  redeclaration sval fcaret reentrant XSLT xsl Wmaybe yyvsp Tedi
  LocalWords:  pragmas noreturn untyped Rozenman unexpanded Wojciech Polak
- LocalWords:  Alexandre MERCHANTABILITY
+ LocalWords:  Alexandre MERCHANTABILITY yytype
 
 Local Variables:
 mode: outline
diff --git a/data/bison.m4 b/data/bison.m4
index 4aa6448..2e73f0d 100644
--- a/data/bison.m4
+++ b/data/bison.m4
@@ -359,12 +359,11 @@ b4_define_flag_if([yacc])               # Whether POSIX 
Yacc is emulated.
 #   Whether has a semantic value.
 # - type_tag: string
 #   When api.value.type=union, the generated name for the union member.
-#   yytype_INT etc. for %tokens, otherwise yytype_1 etc.
+#   yytype_INT etc. for symbols that has_id, otherwise yytype_1 etc.
 # - type
 #   If it has a semantic value, its type tag, or, if variant are used,
 #   its type.
-#   In the case of api.value.type=union, type is first defined
-#   as the real type (e.g. int), and then changed to be equal to type_tag.
+#   In the case of api.value.type=union, type is the real type (e.g. int).
 # - has_printer: 0, 1
 # - printer: string
 # - printer_file: string
diff --git a/data/c.m4 b/data/c.m4
index 35741b3..1814877 100644
--- a/data/c.m4
+++ b/data/c.m4
@@ -510,17 +510,13 @@ b4_locations_if([, yylocationp])[]b4_user_args[);
 # instead of the type name.
 m4_define([b4_symbol_type_register],
 [m4_define([b4_symbol($1, type_tag)],
-           [yytype_[]b4_symbol_if([$1], [is_token],
-                                  [b4_symbol_if([$1], [has_id],
-                                                [b4_symbol([$1], [id])],
-                                                [b4_symbol([$1], [number])])],
+           [yytype_[]b4_symbol_if([$1], [has_id],
+                                  [b4_symbol([$1], [id])],
                                   [b4_symbol([$1], [number])])])dnl
 m4_append([b4_user_union_members],
 m4_expand([
   b4_symbol_tag_comment([$1])dnl
   b4_symbol([$1], [type]) b4_symbol([$1], [type_tag]);]))
-m4_define([b4_symbol($1, type)],
-          [b4_symbol([$1], [type_tag])])dnl
 ])
 
 
diff --git a/data/lalr1.cc b/data/lalr1.cc
index 1d864b5..4eec878 100644
--- a/data/lalr1.cc
+++ b/data/lalr1.cc
@@ -44,9 +44,11 @@ m4_define([b4_integral_parser_table_define],
 # b4_symbol_value_template(VAL, [TYPE])
 # -------------------------------------
 # Same as b4_symbol_value, but used in a template method.  It makes
-# a difference when using variants.
+# a difference when using variants.  Note that b4_value_type_setup_union
+# overrides b4_symbol_value, so we must override it again.
 m4_copy([b4_symbol_value], [b4_symbol_value_template])
-
+m4_append([b4_value_type_setup_union],
+          [m4_copy_force([b4_symbol_value_union], [b4_symbol_value_template])])
 
 # b4_lhs_value([TYPE])
 # --------------------
diff --git a/tests/types.at b/tests/types.at
index 901e4cc..022c7a1 100644
--- a/tests/types.at
+++ b/tests/types.at
@@ -138,19 +138,27 @@ m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], 
[glr.cc]],
              AT_VAL.fval = 0.2f],
           [10 0.2])
 
-
   # A Bison-defined union.
+  # The tokens names are not available directly in C++, we use their
+  # user number to keep it simple between C and C++.
   AT_TEST([%skeleton "]b4_skel["
            %define api.value.type union],
           [%token <int> ONE 101;
-           %token <float> TWO 102;],
-          [ONE TWO { printf ("%d %2.1f\n", $1, $2); }],
-          [{ 101, 102, EOF }],
+           %token <float> TWO 102 THREE 103;
+           %printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
+                                     [[fprintf (yyo, "%d", $$)]])[; } <int>
+           %printer { ]AT_SKEL_CC_IF([[yyoutput << $$]],
+                                     [[fprintf (yyo, "%f", $$)]])[; } <float>
+          ],
+          [ONE TWO THREE { printf ("%d %2.1f %2.1f\n", $1, $2, $3); }],
+          [{ 101, 102, 103, EOF }],
           [if (res == 101)
              AT_VAL.yytype_ONE = 10;
-           else
-             AT_VAL.yytype_TWO = .2f],
-          [10 0.2])
+           else if (res == 102)
+             AT_VAL.yytype_TWO = .2f;
+           else if (res == 103)
+             AT_VAL.yytype_THREE = 3.3f],
+          [10 0.2 3.3])
 
   # A Bison-defined variant, for lalr1.cc only.
   m4_if(b4_skel, [lalr1.cc], [




reply via email to

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