[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], [
- Re: [PATCH 0/6] api.value.type support, (continued)
- Re: [PATCH 0/6] api.value.type support, Paul Eggert, 2013/02/23
- [PATCH 0/6] api.value.type support (was: rename variant), Akim Demaille, 2013/02/23
- [PATCH 4/6] doc: deprecate #define YYSTYPE in favor of %define api.value.type, Akim Demaille, 2013/02/23
- [PATCH 3/6] value type: accept "->" in type tags, Akim Demaille, 2013/02/23
- [PATCH 2/6] style: simplify the scanning of type tags, Akim Demaille, 2013/02/23
- [PATCH 6/6] doc: api.value.type union., Akim Demaille, 2013/02/23
- [PATCH 5/6] doc: move the section about "%union" where types are discussed, Akim Demaille, 2013/02/23
- [PATCH 1/6] api.value.type: implement proper support, check, and document, Akim Demaille, 2013/02/23
- Re: [PATCH 1/6] api.value.type: implement proper support, check, and document,
Akim Demaille <=
- Re: [PATCH 0/6] api.value.type support (was: rename variant), Joel E. Denny, 2013/02/24