-# Executing Actions. -*- Autotest -*-
+e# Executing Actions. -*- Autotest -*-
# Copyright (C) 2001-2012 Free Software Foundation, Inc.
}
]])
-AT_BISON_CHECK([-o input.c input.y])
+AT_BISON_CHECK([-o input.c input.y], [], [],
+[[input.y:27.3-5: warning: useless %destructor for type <*> [-Wother]
+input.y:27.3-5: warning: useless %printer for type <*> [-Wother]
+]])
AT_COMPILE([input])
AT_PARSER_CHECK([./input], 1,
[[<> destructor for 'd' @ 4.
}
]])
-AT_BISON_CHECK([-o input.c input.y])
+AT_BISON_CHECK([-o input.c input.y], [], [],
+[[input.y:22.3-4: warning: useless %destructor for type <> [-Wother]
+input.y:22.3-4: warning: useless %printer for type <> [-Wother]
+]])
AT_COMPILE([input])
AT_PARSER_CHECK([./input], 1,
[[<*>/<field2>/e destructor.
AT_SETUP([Default %printer and %destructor for user-defined end token])
-# _AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(TYPED)
-# -------------------------------------------------------------
-m4_define([_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN],
+# AT_TEST(TYPED)
+# --------------
+m4_pushdef([AT_TEST],
[m4_if($1, 0,
[m4_pushdef([kind], []) m4_pushdef([not_kind], [*])],
[m4_pushdef([kind], [*]) m4_pushdef([not_kind], [])])
]])
AT_BISON_OPTION_POPDEFS
-AT_BISON_CHECK([-o input$1.c input$1.y])
+AT_BISON_CHECK([-o input$1.c input$1.y], [], [],
+[m4_if([$1], [0],
+[[input0.y:27.3-5: warning: useless %destructor for type <*> [-Wother]
+input0.y:27.3-5: warning: useless %printer for type <*> [-Wother]
+]],
+[[input1.y:27.3-4: warning: useless %destructor for type <> [-Wother]
+input1.y:27.3-4: warning: useless %printer for type <> [-Wother]
+]])])
+
AT_COMPILE([input$1])
+
AT_PARSER_CHECK([./input$1], 0,
[[<]]kind[[> for 'E' @ 1.
<]]kind[[> for 'S' @ 1.
m4_popdef([not_kind])
])
-_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(0)
-_AT_CHECK_DEFAULT_PRINTER_AND_DESTRUCTOR_FOR_END_TOKEN(1)
+AT_TEST(0)
+AT_TEST(1)
+
+m4_popdef([AT_TEST])
AT_CLEANUP
]])
AT_BISON_OPTION_POPDEFS
-AT_BISON_CHECK([-o input.c input.y])
+AT_BISON_CHECK([-o input.c input.y], [], [],
+[[input.y:21.6-8: warning: useless %destructor for type <*> [-Wother]
+input.y:21.6-8: warning: useless %printer for type <*> [-Wother]
+]])
AT_COMPILE([input])
AT_PARSER_CHECK([./input], [1], [],
[[Starting parse
]])
AT_BISON_OPTION_POPDEFS
-AT_BISON_CHECK([-o input.c input.y])
+AT_BISON_CHECK([-o input.c input.y], [], [],
+[[input.y:22.3-4: warning: useless %destructor for type <> [-Wother]
+input.y:22.3-4: warning: useless %printer for type <> [-Wother]
+]])
AT_COMPILE([input])
AT_CLEANUP
AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([-o input.c input.y], 0,,
-[[input.y:33.3-23: warning: unset value: $$ [-Wother]
+[[input.y:24.70-72: warning: useless %destructor for type <*> [-Wother]
+input.y:24.70-72: warning: useless %printer for type <*> [-Wother]
+input.y:33.3-23: warning: unset value: $$ [-Wother]
input.y:30.3-35.37: warning: unused value: $3 [-Wother]
]])
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([%skeleton "$1"])
+
+AT_DATA_GRAMMAR([[input.y]],
+[[%skeleton "$1"
+%defines // FIXME: Mandated by glr.cc.
+%debug
+%code requires
+{
+ typedef struct sem_type
+ {
+ int ival;
+ float fval;
+ } sem_type;
+
+# define YYSTYPE sem_type
+
+]AT_SKEL_CC_IF([[
+# include <iostream>
+ static void
+ report (std::ostream& yyo, int ival, float fval)
+ {
+ yyo << "ival: " << ival << ", fval: " << fval;
+ }
+]], [[
+# include <stdio.h>
+ static void
+ report (FILE* yyo, int ival, float fval)
+ {
+ fprintf (yyo, "ival: %d, fval: %1.1f", ival, fval);
+ }
+]])[
+}
+
+%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.
+AT_CHECK([[sed -ne '/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. ##
## ----------------------------------------------- ##