bison-patches
[Top][All Lists]
Advanced

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

[PATCH 3/3] support $<tag>$ in printers and destructors


From: Akim Demaille
Subject: [PATCH 3/3] support $<tag>$ in printers and destructors
Date: Fri, 27 Jul 2012 17:13:23 +0200

* src/scan-code.l (SC_SYMBOL_ACTION): Accept $<tag>$, not just $$.
* data/c.m4 (b4_dollar_dollar_): New.
(b4_symbol_actions): Let b4_dollar_dollar use b4_dollar_dollar_.
* NEWS, doc/bison.texi: Document it.
* tests/actions.at: Check this for C and C++.
---
 NEWS             |  10 +++++
 data/c.m4        |  17 +++++++-
 doc/bison.texi   |  19 +++++----
 src/scan-code.l  |   8 +++-
 tests/actions.at | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 168 insertions(+), 12 deletions(-)

diff --git a/NEWS b/NEWS
index b97956c..56961cc 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,16 @@ GNU Bison NEWS
 
 *** glr.cc: set_debug_level and debug_level work as expected.
 
+** Type names in printers and destructors
+
+  For consistency with rule actions, it is now possible to qualify $$ by a
+  type-name in printers and destructors.  For instance:
+
+    %printer { fprintf (yyo, "(%d, %f)", $<ival>$, $<fval>$); } <*> <>;
+
+  will display two values for each typed and untyped symbol (provided
+  that YYSTYPE supports it).
+
 * Noteworthy changes in release 2.6 (2012-07-19) [stable]
 
 ** Future Changes
diff --git a/data/c.m4 b/data/c.m4
index 08296c6..3954613 100644
--- a/data/c.m4
+++ b/data/c.m4
@@ -417,13 +417,28 @@ m4_define([b4_case],
 $2
     break;])
 
+# b4_dollar_dollar_(NAME, FIELD, DEFAULT-FIELD)
+# ---------------------------------------------
+# If FIELD (or DEFAULT-FIELD) is non-null, read it in pointer NAME,
+# otherwise just dereference.
+m4_define([b4_dollar_dollar_],
+[m4_if([$2], [[]],
+       [m4_ifval([$3], [($1->$3)],
+                 [(*$1)])],
+       [($1->$2)])])
+
+
 # b4_symbol_actions(FILENAME, LINENO,
 #                   SYMBOL-TAG, SYMBOL-NUM,
 #                   SYMBOL-ACTION, SYMBOL-TYPENAME)
 # -------------------------------------------------
+# Issue the code for a symbol action (e.g., %printer).
+#
+# Define b4_dollar_dollar([TYPE-NAME]), and b4_at_dollar, which are
+# invoked where $<TYPE-NAME>$ and @$ were specified by the user.
 m4_define([b4_symbol_actions],
 [m4_pushdef([b4_dollar_dollar],
-   [m4_ifval([$6], [(yyvaluep->$6)], [(*yyvaluep)])])dnl
+   [b4_dollar_dollar_([yyvaluep], m4_dquote($][1), [$6])])dnl
 m4_pushdef([b4_at_dollar], [(*yylocationp)])dnl
       case $4: /* $3 */
 b4_syncline([$2], [$1])
diff --git a/doc/bison.texi b/doc/bison.texi
index 6156b41..e50bd17 100644
--- a/doc/bison.texi
+++ b/doc/bison.texi
@@ -4592,11 +4592,11 @@ symbol is automatically discarded.
 @deffn {Directive} %destructor @{ @var{code} @} @var{symbols}
 @findex %destructor
 Invoke the braced @var{code} whenever the parser discards one of the
address@hidden
-Within @var{code}, @code{$$} designates the semantic value associated
-with the discarded symbol, and @code{@@$} designates its location.
-The additional parser parameters are also available (@pxref{Parser Function, ,
-The Parser Function @code{yyparse}}).
address@hidden  Within @var{code}, @code{$$} (or @code{$<@var{tag}>$})
+designates the semantic value associated with the discarded symbol, and
address@hidden@@$} designates its location.  The additional parser parameters 
are
+also available (@pxref{Parser Function, , The Parser Function
address@hidden).
 
 When a symbol is listed among @var{symbols}, its @code{%destructor} is called a
 per-symbol @code{%destructor}.
@@ -4734,10 +4734,11 @@ Decl, , Freeing Discarded Symbols}).
 @c This is the same text as for %destructor.
 Invoke the braced @var{code} whenever the parser displays one of the
 @var{symbols}.  Within @var{code}, @code{yyoutput} denotes the output stream
-(a @code{FILE*} in C, and an @code{std::ostream&} in C++),
address@hidden designates the semantic value associated with the symbol, and
address@hidden@@$} its location.  The additional parser parameters are also
-available (@pxref{Parser Function, , The Parser Function @code{yyparse}}).
+(a @code{FILE*} in C, and an @code{std::ostream&} in C++), @code{$$} (or
address@hidden<@var{tag}>$}) designates the semantic value associated with the
+symbol, and @code{@@$} its location.  The additional parser parameters are
+also available (@pxref{Parser Function, , The Parser Function
address@hidden).
 
 The @var{symbols} are defined as for @code{%destructor} (@pxref{Destructor
 Decl, , Freeing Discarded Symbols}.): they can be per-type (e.g.,
diff --git a/src/scan-code.l b/src/scan-code.l
index 2fab6d9..e30bf9d 100644
--- a/src/scan-code.l
+++ b/src/scan-code.l
@@ -264,8 +264,12 @@ ref      -?[0-9]+|{id}|"["{id}"]"|"$"
 
 <SC_SYMBOL_ACTION>
 {
-  "$$" {
-    obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar[");
+  "$"("<"{tag}">")?"$" {
+    const char *type_name = NULL;
+    fetch_type_name (yytext + 1, &type_name, *loc)[-1] = 0;
+    obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar(");
+    obstack_quote (&obstack_for_string, type_name);
+    obstack_sgrow (&obstack_for_string, ")[");
     self->is_value_used = true;
   }
   "@$" {
diff --git a/tests/actions.at b/tests/actions.at
index e8e8cd9..d686d30 100644
--- a/tests/actions.at
+++ b/tests/actions.at
@@ -1230,6 +1230,132 @@ AT_CHECK_ACTION_LOCATIONS([[%destructor]])
 AT_CHECK_ACTION_LOCATIONS([[%printer]])
 
 
+## ------------------------- ##
+## Qualified $$ in actions.  ##
+## ------------------------- ##
+
+# Check that we can used qualified $$ (v.g., $<type>$) not only in
+# rule actions, but also where $$ is valid: %printer and %destructor.
+#
+# FIXME: Not actually checking %desctructor, but it's the same code as
+# %printer...
+#
+# To do that, use a semantic value that has two fields (sem_type),
+# declare symbols to have only one of these types (INT, float), and
+# use $<type>$ to get the other one.  Including for symbols that are
+# not typed (UNTYPED).
+
+m4_pushdef([AT_TEST],
+[AT_SETUP([[Qualified $$ in actions: $1]])
+
+AT_BISON_OPTION_PUSHDEFS([%locations %skeleton "$1"])
+
+AT_DATA_GRAMMAR([[input.y]],
+[[%skeleton "$1"
+%defines   // FIXME: Mandated by lalr1.cc in Bison 2.6.
+%locations // FIXME: Mandated by lalr1.cc in Bison 2.6.
+%debug
+%code requires
+{
+# include <stdio.h>
+
+  typedef struct sem_type
+  {
+    int ival;
+    float fval;
+  } sem_type;
+
+# define YYSTYPE sem_type
+
+#ifdef __cplusplus
+# include <iostream>
+  static void
+  report (std::ostream& yyo, int ival, float fval)
+  {
+    yyo << "ival: " << ival << ", fval: " <<  fval;
+  }
+#else
+  static void
+  report (FILE* yyo, int ival, float fval)
+  {
+    fprintf (yyo, "ival: %d, fval: %1.1f", ival, fval);
+  }
+#endif
+}
+
+%code
+{
+  ]AT_YYERROR_DECLARE[
+  ]AT_YYLEX_DECLARE[
+}
+
+%token UNTYPED
+%token <ival> INT
+%type <fval> float
+%printer { report (yyo, $$,       $<fval>$); } <ival>;
+%printer { report (yyo, $<ival>$, $$      ); } <fval>;
+%printer { report (yyo, $<ival>$, $<fval>$); } <>;
+
+// %initial-action
+// {
+//   $<ival>$ = 42;
+//   $<fval>$ = 4.2;
+// }
+
+%%
+float: UNTYPED INT
+{
+   $$       = $<fval>1 + $<fval>2;
+   $<ival>$ = $<ival>1 + $][2;
+};
+%%
+]AT_YYERROR_DEFINE[
+]AT_YYLEX_DEFINE(AT_SKEL_CC_IF([[{yy::parser::token::UNTYPED,
+                                 yy::parser::token::INT,
+                                  EOF}]],
+                               [[{UNTYPED, INT, EOF}]]),
+                 [AT_VAL.ival = toknum * 10; AT_VAL.fval = toknum / 10.0;])[
+int
+main (void)
+{]AT_SKEL_CC_IF([[
+  yy::parser p;
+  p.set_debug_level(1);
+  return p.parse ();]], [[
+  yydebug = 1;
+  return yyparse ();]])[
+}
+]])
+
+AT_FULL_COMPILE([[input]])
+AT_PARSER_CHECK([./input], 0, [], [stderr])
+# Don't be too picky on the traces, GLR is not exactly the same.  Keep
+# only the lines from the printer.
+#
+# Don't care about locations.  FIXME: remove their removal when Bison
+# supports C++ without locations.
+AT_CHECK([[sed -ne 's/([-0-9.]*: /(/;/ival:/p' stderr]], 0,
+[[Reading a token: Next token is token UNTYPED (ival: 10, fval: 0.1)
+Shifting token UNTYPED (ival: 10, fval: 0.1)
+Reading a token: Next token is token INT (ival: 20, fval: 0.2)
+Shifting token INT (ival: 20, fval: 0.2)
+   $][1 = token UNTYPED (ival: 10, fval: 0.1)
+   $][2 = token INT (ival: 20, fval: 0.2)
+-> $$ = nterm float (ival: 30, fval: 0.3)
+Cleanup: popping nterm float (ival: 30, fval: 0.3)
+]])
+
+AT_BISON_OPTION_POPDEFS
+
+AT_CLEANUP
+])
+
+AT_TEST([yacc.c])
+AT_TEST([glr.c])
+AT_TEST([lalr1.cc])
+AT_TEST([glr.cc])
+
+m4_popdef([AT_TEST])
+
 ## ----------------------------------------------- ##
 ## Fix user actions without a trailing semicolon.  ##
 ## ----------------------------------------------- ##
-- 
1.7.11.3




reply via email to

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