Files
bison/tests/input.at
Theophile Ranquet 46bdb8ec59 errors: don't display "warnings treated as errors"
This line doesn't add any meaningful information anymore, the appended
[-Werror=CATEGORY] is enough.  It is actually more insightful, as it
allows to distinguish warnings treated as errors from those that
aren't.  This line is also removed by gcc 4.8.

* src/complain.c (set_warnings_issued): The only action left was
checking if the error bit corresponding to the warning issued was set,
and that function was only called once. Therefore, remove it, and do
its job directly in the caller...
(complains): here.
* src/complains.h: Adjust.
* tests/input.at: Adjust.
* NEWS: Document this change.

Signed-off-by: Akim Demaille <akim@lrde.epita.fr>
2012-09-27 12:26:05 +02:00

1597 lines
41 KiB
Plaintext

# Checking the Bison scanner. -*- Autotest -*-
# Copyright (C) 2002-2012 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AT_BANNER([[Input Processing.]])
# Mostly test that we are robust to mistakes.
## ------------ ##
## Invalid $n. ##
## ------------ ##
AT_SETUP([Invalid $n and @n])
AT_DATA([input.y],
[[%%
exp: { $$ = $1 ; };
exp: { @$ = @1 ; };
]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:2.13-14: error: integer out of range: '$1'
input.y:3.13-14: error: integer out of range: '@1'
]])
AT_CLEANUP
## -------------- ##
## Type Clashes. ##
## -------------- ##
AT_SETUP([Type Clashes])
AT_DATA([input.y],
[[%union { int bar; }
%token foo
%type <bar> exp
%%
exp: foo { $$; } foo { $2; } foo
| foo
| /* Empty. */
;
]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:5.12-13: error: $$ for the midrule at $2 of 'exp' has no declared type
input.y:5.24-25: error: $2 of 'exp' has no declared type
input.y:5.6-32: warning: type clash on default action: <bar> != <> [-Wother]
input.y:6.6-8: warning: type clash on default action: <bar> != <> [-Wother]
input.y:7.5: warning: empty rule for typed nonterminal, and no action [-Wother]
]])
AT_CLEANUP
# _AT_UNUSED_VALUES_DECLARATIONS()
# --------------------------------
# Generate the token, type, and destructor
# declarations for the unused values tests.
m4_define([_AT_UNUSED_VALUES_DECLARATIONS],
[[[%token <integer> INT;
%type <integer> a b c d e f g h i j k l;
%destructor { destroy ($$); } INT a b c d e f g h i j k l;]]])
# AT_CHECK_UNUSED_VALUES(DECLARATIONS_AFTER, CHECK_MIDRULE_VALUES)
# ----------------------------------------------------------------
# Generate a grammar to test unused values, compile it, run it. If
# DECLARATIONS_AFTER is set, then the token, type, and destructor
# declarations are generated after the rules rather than before. If
# CHECK_MIDRULE_VALUES is set, then --warnings=midrule-values is set.
m4_define([AT_CHECK_UNUSED_VALUES],
[AT_DATA([input.y],
m4_ifval($1, [
], [_AT_UNUSED_VALUES_DECLARATIONS
])[[%%
start:
'a' a { $]2[; } | 'b' b { $]2[; } | 'c' c { $]2[; } | 'd' d { $]2[; }
| 'e' e { $]2[; } | 'f' f { $]2[; } | 'g' g { $]2[; } | 'h' h { $]2[; }
| 'i' i { $]2[; } | 'j' j { $]2[; } | 'k' k { $]2[; } | 'l' l { $]2[; }
;
a: INT | INT { } INT { } INT { };
b: INT | /* empty */;
c: INT | INT { $]1[; } INT { $<integer>2; } INT { $<integer>4; };
d: INT | INT { } INT { $]1[; } INT { $<integer>2; };
e: INT | INT { } INT { } INT { $]1[; };
f: INT | INT { } INT { } INT { $]$[ = $]1[ + $]3[ + $]5[; };
g: INT | INT { $<integer>$; } INT { $<integer>$; } INT { };
h: INT | INT { $<integer>$; } INT { $<integer>$ = $<integer>2; } INT { };
i: INT | INT INT { } { $]$[ = $]1[ + $]2[; };
j: INT | INT INT { $<integer>$ = 1; } { $]$[ = $]1[ + $]2[; };
k: INT | INT INT { $<integer>$; } { $<integer>$ = $<integer>3; } { };
l: INT | INT { $<integer>$ = $<integer>1; } INT { $<integer>$ = $<integer>2 + $<integer>3; } INT { $<integer>$ = $<integer>4 + $<integer>5; };]]m4_ifval($1, [
_AT_UNUSED_VALUES_DECLARATIONS])
)
AT_BISON_CHECK(m4_ifval($2, [ --warnings=midrule-values ])[ input.y], [0], [],
[[input.y:11.10-32: warning: unset value: $]$[ [-Wother]
input.y:11.10-32: warning: unused value: $]1[ [-Wother]
input.y:11.10-32: warning: unused value: $]3[ [-Wother]
input.y:11.10-32: warning: unused value: $]5[ [-Wother]
input.y:12.9: warning: empty rule for typed nonterminal, and no action [-Wother]
]]m4_ifval($2, [[[input.y:13.14-20: warning: unset value: $$ [-Wmidrule-values]
input.y:13.26-41: warning: unset value: $$ [-Wmidrule-values]
]]])[[input.y:13.10-62: warning: unset value: $]$[ [-Wother]
input.y:13.10-62: warning: unused value: $]3[ [-Wother]
input.y:13.10-62: warning: unused value: $]5[ [-Wother]
]]m4_ifval($2, [[[input.y:14.14-16: warning: unset value: $$ [-Wmidrule-values]
]]])[[input.y:14.10-49: warning: unset value: $]$[ [-Wother]
input.y:14.10-49: warning: unused value: $]3[ [-Wother]
input.y:14.10-49: warning: unused value: $]5[ [-Wother]
input.y:15.10-37: warning: unset value: $]$[ [-Wother]
input.y:15.10-37: warning: unused value: $]3[ [-Wother]
input.y:15.10-37: warning: unused value: $]5[ [-Wother]
input.y:17.10-58: warning: unset value: $]$[ [-Wother]
input.y:17.10-58: warning: unused value: $]1[ [-Wother]
]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]2[ [-Wmidrule-values]
]]])[[input.y:17.10-58: warning: unused value: $]3[ [-Wother]
]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]4[ [-Wmidrule-values]
]]])[[input.y:17.10-58: warning: unused value: $]5[ [-Wother]
input.y:18.10-72: warning: unset value: $]$[ [-Wother]
input.y:18.10-72: warning: unused value: $]1[ [-Wother]
input.y:18.10-72: warning: unused value: $]3[ [-Wother]
]]m4_ifval($2, [[[input.y:18.10-72: warning: unused value: $]4[ [-Wmidrule-values]
]]])[[input.y:18.10-72: warning: unused value: $]5[ [-Wother]
]]m4_ifval($2, [[[input.y:20.10-55: warning: unused value: $]3[ [-Wmidrule-values]
]]])[[input.y:21.10-68: warning: unset value: $]$[ [-Wother]
input.y:21.10-68: warning: unused value: $]1[ [-Wother]
input.y:21.10-68: warning: unused value: $]2[ [-Wother]
]]m4_ifval($2, [[[input.y:21.10-68: warning: unused value: $]4[ [-Wmidrule-values]
]]]))])
## --------------- ##
## Unused values. ##
## --------------- ##
AT_SETUP([Unused values])
AT_CHECK_UNUSED_VALUES
AT_CHECK_UNUSED_VALUES(, [1])
AT_CLEANUP
## ------------------------------------------ ##
## Unused values before symbol declarations. ##
## ------------------------------------------ ##
AT_SETUP([Unused values before symbol declarations])
AT_CHECK_UNUSED_VALUES([1])
AT_CHECK_UNUSED_VALUES([1], [1])
AT_CLEANUP
## --------------------------------------------- ##
## Default %printer and %destructor redeclared. ##
## --------------------------------------------- ##
AT_SETUP([Default %printer and %destructor redeclared])
AT_DATA([[input.y]],
[[%destructor { destroy ($$); } <*> <*>
%printer { print ($$); } <*> <*>
%destructor { destroy ($$); } <*>
%printer { print ($$); } <*>
%destructor { destroy ($$); } <> <>
%printer { print ($$); } <> <>
%destructor { destroy ($$); } <>
%printer { print ($$); } <>
%%
start: ;
%destructor { destroy ($$); } <*>;
%printer { print ($$); } <*>;
%destructor { destroy ($$); } <>;
%printer { print ($$); } <>;
]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:1.13-29: error: %destructor redeclaration for <*>
input.y:1.13-29: previous declaration
input.y:2.10-24: error: %printer redeclaration for <*>
input.y:2.10-24: previous declaration
input.y:4.13-29: error: %destructor redeclaration for <*>
input.y:1.13-29: previous declaration
input.y:5.10-24: error: %printer redeclaration for <*>
input.y:2.10-24: previous declaration
input.y:7.13-29: error: %destructor redeclaration for <>
input.y:7.13-29: previous declaration
input.y:8.10-24: error: %printer redeclaration for <>
input.y:8.10-24: previous declaration
input.y:10.13-29: error: %destructor redeclaration for <>
input.y:7.13-29: previous declaration
input.y:11.10-24: error: %printer redeclaration for <>
input.y:8.10-24: previous declaration
input.y:17.13-29: error: %destructor redeclaration for <*>
input.y:4.13-29: previous declaration
input.y:18.10-24: error: %printer redeclaration for <*>
input.y:5.10-24: previous declaration
input.y:20.13-29: error: %destructor redeclaration for <>
input.y:10.13-29: previous declaration
input.y:21.10-24: error: %printer redeclaration for <>
input.y:11.10-24: previous declaration
]])
AT_CLEANUP
## ---------------------------------------------- ##
## Per-type %printer and %destructor redeclared. ##
## ---------------------------------------------- ##
AT_SETUP([Per-type %printer and %destructor redeclared])
AT_DATA([[input.y]],
[[%destructor { destroy ($$); } <field1> <field2>
%printer { print ($$); } <field1> <field2>
%destructor { destroy ($$); } <field1> <field1>
%printer { print ($$); } <field2> <field2>
%%
start: ;
%destructor { destroy ($$); } <field2> <field1>;
%printer { print ($$); } <field2> <field1>;
]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:4.13-29: error: %destructor redeclaration for <field1>
input.y:1.13-29: previous declaration
input.y:4.13-29: error: %destructor redeclaration for <field1>
input.y:4.13-29: previous declaration
input.y:5.10-24: error: %printer redeclaration for <field2>
input.y:2.10-24: previous declaration
input.y:5.10-24: error: %printer redeclaration for <field2>
input.y:5.10-24: previous declaration
input.y:11.13-29: error: %destructor redeclaration for <field1>
input.y:4.13-29: previous declaration
input.y:11.13-29: error: %destructor redeclaration for <field2>
input.y:1.13-29: previous declaration
input.y:12.10-24: error: %printer redeclaration for <field1>
input.y:2.10-24: previous declaration
input.y:12.10-24: error: %printer redeclaration for <field2>
input.y:5.10-24: previous declaration
]])
AT_CLEANUP
## ------------------- ##
## Undefined symbols. ##
## ------------------- ##
AT_SETUP([Undefined symbols])
AT_DATA([[input.y]],
[[%printer {} foo baz
%destructor {} bar
%type <foo> qux
%%
exp: bar;
]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:2.16-18: error: symbol bar is used, but is not defined as a token and has no rules
input.y:1.17-19: warning: symbol baz is used, but is not defined as a token and has no rules [-Wother]
input.y:1.13-15: warning: symbol foo is used, but is not defined as a token and has no rules [-Wother]
input.y:3.13-15: warning: symbol qux is used, but is not defined as a token and has no rules [-Wother]
]])
AT_CLEANUP
## ----------------------------------------------------- ##
## Unassociated types used for a printer or destructor. ##
## ----------------------------------------------------- ##
AT_SETUP([Unassociated types used for a printer or destructor])
AT_DATA([[input.y]],
[[%token <type1> tag1
%type <type2> tag2
%printer { } <type1> <type3>
%destructor { } <type2> <type4>
%%
exp: tag1 { $1; }
| tag2 { $1; }
tag2: "a" { $$; }
]])
AT_BISON_CHECK([input.y], [0], [],
[[input.y:4.22-28: warning: type <type3> is used, but is not associated to any symbol [-Wother]
input.y:5.25-31: warning: type <type4> is used, but is not associated to any symbol [-Wother]
]])
AT_CLEANUP
## --------------------------------- ##
## Useless printers or destructors. ##
## --------------------------------- ##
AT_SETUP([Useless printers or destructors])
# AT_TEST([INPUT], [STDERR])
# --------------------------
m4_pushdef([AT_TEST],
[AT_DATA([[input.y]],
[$1
])
AT_BISON_CHECK([input.y], [0], [], [$2
])])
AT_TEST([[%token <type1> token1
%token <type2> token2
%token <type3> token3
%token <type4> token4
%token <type5> token51 token52
%token <type6> token61 token62
%token <type7> token7
%printer {} token1
%destructor {} token2
%printer {} token51
%destructor {} token61
%printer {} token7
%printer {} <type1>
%destructor {} <type2>
%printer {} <type3>
%destructor {} <type4>
%printer {} <type5>
%destructor {} <type6>
%destructor {} <type7>
%%
exp: "a";]],
[[input.y:16.13-19: warning: useless %printer for type <type1> [-Wother]
input.y:17.16-22: warning: useless %destructor for type <type2> [-Wother]]])
# If everybody is typed, <> is useless.
AT_TEST([[%type <type> exp
%token <type> a
%printer {} <> <*>
%%
exp: a;]],
[[input.y:3.13-14: warning: useless %printer for type <> [-Wother]]])
# If nobody is typed, <*> is useless.
AT_TEST([[%token a
%printer {} <> <*>
%%
exp: a;]],
[[input.y:2.16-18: warning: useless %printer for type <*> [-Wother]]])
m4_popdef([AT_TEST])
AT_CLEANUP
## ---------------------------------------- ##
## Unused values with default %destructor. ##
## ---------------------------------------- ##
AT_SETUP([Unused values with default %destructor])
AT_DATA([[input.y]],
[[%destructor { destroy ($$); } <>
%type <tag> tagged
%%
start: end end tagged tagged { $<tag>1; $3; } ;
end: { } ;
tagged: { } ;
]])
AT_BISON_CHECK([input.y], [0], [],
[[input.y:6.8-45: warning: unset value: $$ [-Wother]
input.y:6.8-45: warning: unused value: $2 [-Wother]
input.y:7.6-8: warning: unset value: $$ [-Wother]
]])
AT_DATA([[input.y]],
[[%destructor { destroy ($$); } <*>
%type <tag> tagged
%%
start: end end tagged tagged { $<tag>1; $3; } ;
end: { } ;
tagged: { } ;
]])
AT_BISON_CHECK([input.y], [0], [],
[[input.y:6.8-45: warning: unused value: $4 [-Wother]
input.y:8.9-11: warning: unset value: $$ [-Wother]
]])
AT_CLEANUP
## ----------------------------------------- ##
## Unused values with per-type %destructor. ##
## ----------------------------------------- ##
AT_SETUP([Unused values with per-type %destructor])
AT_DATA([[input.y]],
[[%destructor { destroy ($$); } <field1>
%type <field1> start end
%%
start: end end { $1; } ;
end: { } ;
]])
AT_BISON_CHECK([input.y], [0], [],
[[input.y:6.8-22: warning: unset value: $$ [-Wother]
input.y:6.8-22: warning: unused value: $2 [-Wother]
input.y:7.6-8: warning: unset value: $$ [-Wother]
]])
AT_CLEANUP
## ---------------------- ##
## Incompatible Aliases. ##
## ---------------------- ##
AT_SETUP([Incompatible Aliases])
AT_DATA([input.y],
[[%token foo "foo"
%type <bar> foo
%printer {bar} foo
%destructor {bar} foo
%left foo
%type <baz> "foo"
%printer {baz} "foo"
%destructor {baz} "foo"
%left "foo"
%%
exp: foo;
]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:8.7-11: error: %type redeclaration for foo
input.y:3.7-11: previous declaration
input.y:10.13-17: error: %destructor redeclaration for foo
input.y:5.13-17: previous declaration
input.y:9.10-14: error: %printer redeclaration for foo
input.y:4.10-14: previous declaration
input.y:11.1-5: error: %left redeclaration for foo
input.y:6.1-5: previous declaration
]])
AT_CLEANUP
## ----------------------- ##
## Torturing the Scanner. ##
## ----------------------- ##
# Be sure to compile and run, so that the C compiler checks what
# we do.
AT_SETUP([Torturing the Scanner])
AT_BISON_OPTION_PUSHDEFS
AT_DATA([input.y], [])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:1.1: error: syntax error, unexpected end of file
]])
AT_DATA([input.y],
[{}
])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:1.1-2: error: syntax error, unexpected {...}
]])
AT_DATA_GRAMMAR([input.y],
[[%{
/* This is seen in GCC: a %{ and %} in middle of a comment. */
const char *foo = "So %{ and %} can be here too.";
#if 0
/* These examples test Bison while not stressing C compilers too much.
Many C compilers mishandle backslash-newlines, so this part of the
test is inside "#if 0". The comment and string are written so that
the "#endif" will be seen regardless of the C compiler bugs that we
know about, namely:
HP C (as of late 2002) mishandles *\[newline]\[newline]/ within a
comment.
The Apple Darwin compiler (as of late 2002) mishandles
\\[newline]' within a character constant.
*/
/\
* A comment with backslash-newlines in it. %} *\
\
/
/* { Close the above comment, if the C compiler mishandled it. */
char str[] = "\\
" A string with backslash-newlines in it %{ %} \\
\
"";
char apostrophe = '\'';
#endif
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
%}
/* %{ and %} can be here too. */
%{
/* Exercise pre-prologue dependency to %union. */
typedef int value;
%}
/* Exercise M4 quoting: '@:>@@:>@', 0. */
/* Also exercise %union. */
%union
{
value ival; /* A comment to exercise an old bug. */
};
/* Exercise post-prologue dependency to %union. */
%{
static YYSTYPE value_as_yystype (value val);
/* Exercise quotes in declarations. */
char quote[] = "@:>@@:>@,";
%}
%{
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
%}
%type <ival> '@<:@'
/* Exercise quotes in strings. */
%token FAKE "fake @<:@@:>@ \a\b\f\n\r\t\v\"\'\?\\\u005B\U0000005c ??!??'??(??)??-??/??<??=??> \x1\1"
%%
/* Exercise M4 quoting: '@:>@@:>@', @<:@, 1. */
exp: '@<:@' '\1' two '$' '@' '{' oline output.or.oline.opt
{
/* Exercise quotes in braces. */
char tmp[] = "@<:@%c@:>@,\n";
printf (tmp, $1);
}
;
two: '\x000000000000000000000000000000000000000000000000000000000000000000002';
oline: '@' 'o' 'l' 'i' 'n' 'e' '@' '_' '_' 'o' 'l' 'i' 'n' 'e' '_' '_';
output.or.oline.opt: ;|oline;;|output;;;
output: '#' 'o' 'u' 't' 'p' 'u' 't' ' ';
%%
/* Exercise M4 quoting: '@:>@@:>@', @<:@, 2. */
static YYSTYPE
value_as_yystype (value val)
{
YYSTYPE res;
res.ival = val;
return res;
}
]AT_YYERROR_DEFINE[
static int
yylex (void)
{
static char const input[] = "@<:@\1\2$@{@oline@__@&t@oline__\
#output "; /* "
*/
static size_t toknum;
assert (toknum < sizeof input);
yylval = value_as_yystype (input[toknum]);
return input[toknum++];
}
]])
# Pacify Emacs'font-lock-mode: "
AT_DATA([main.c],
[[typedef int value;
#include "input.h"
int yyparse (void);
int
main (void)
{
return yyparse ();
}
]])
AT_BISON_OPTION_POPDEFS
AT_BISON_CHECK([-d -v -o input.c input.y])
AT_COMPILE([input.o])
AT_COMPILE([main.o])
AT_COMPILE([input], [input.o main.o])
AT_PARSER_CHECK([./input], 0,
[[[@<:@],
]])
AT_CLEANUP
## ---------------------- ##
## Typed symbol aliases. ##
## ---------------------- ##
AT_SETUP([Typed symbol aliases])
# Bison 2.0 broke typed symbol aliases - ensure they work.
AT_DATA_GRAMMAR([input.y],
[[%union
{
int val;
};
%token <val> MY_TOKEN "MY TOKEN"
%type <val> exp
%%
exp: "MY TOKEN";
%%
]])
AT_BISON_CHECK([-o input.c input.y])
AT_CLEANUP
## --------- ##
## Require. ##
## --------- ##
m4_define([AT_CHECK_REQUIRE],
[AT_SETUP([Require $1])
AT_DATA_GRAMMAR([input.y],
[[%require "$1";
%%
empty_file:;
]])
AT_BISON_CHECK([-o input.c input.y], $2, [], ignore)
AT_CLEANUP
])
AT_CHECK_REQUIRE(1.0, 0)
AT_CHECK_REQUIRE(AT_PACKAGE_VERSION, 0)
## FIXME: Some day augment this version number.
AT_CHECK_REQUIRE(100.0, 63)
## ------------------------------------- ##
## String aliases for character tokens. ##
## ------------------------------------- ##
AT_SETUP([String aliases for character tokens])
# Bison once thought a character token and its alias were different
# symbols with the same user token number.
AT_DATA_GRAMMAR([input.y],
[[%token 'a' "a"
%%
start: 'a';
%%
]])
AT_BISON_CHECK([-o input.c input.y])
AT_CLEANUP
## -------------- ##
## Symbol names. ##
## -------------- ##
AT_SETUP([Symbols])
AT_BISON_OPTION_PUSHDEFS
AT_DATA_GRAMMAR([input.y],
[[%token WITH-DASH
%token WITHOUT_DASH "WITHOUT-DASH"
%token WITH.PERIOD
%token WITHOUT_PERIOD "WITHOUT.PERIOD"
%code {
]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[
}
%%
start: with-dash without_dash with.period without_period;
with-dash: WITH-DASH;
without_dash: "WITHOUT-DASH";
with.period: WITH.PERIOD;
without_period: "WITHOUT.PERIOD";
%%
]AT_YYERROR_DEFINE[
]AT_YYLEX_DEFINE[
]])
AT_BISON_OPTION_POPDEFS
# POSIX Yacc accept periods, but not dashes.
AT_BISON_CHECK([--yacc -Wno-error input.y], [], [],
[[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: WITH-DASH [-Wyacc]
input.y:18.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash [-Wyacc]
]])
# So warn about them.
AT_BISON_CHECK([-Wyacc input.y], [], [],
[[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: WITH-DASH [-Wyacc]
input.y:18.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash [-Wyacc]
]])
# Dashes are fine for GNU Bison.
AT_BISON_CHECK([-o input.c input.y])
# Make sure we don't export silly token identifiers with periods or dashes.
AT_COMPILE([input.o])
# Periods are genuine letters, they can start identifiers.
# Digits and dashes cannot.
AT_DATA_GRAMMAR([input.y],
[[%token .GOOD
-GOOD
1NV4L1D
-123
%%
start: .GOOD GOOD
]])
AT_BISON_CHECK([-o input.c input.y], [1], [],
[[input.y:10.10: error: invalid character: '-'
input.y:11.10-16: error: invalid identifier: '1NV4L1D'
input.y:12.10: error: invalid character: '-'
]])
AT_CLEANUP
## ----------------- ##
## Numbered tokens. ##
## ----------------- ##
AT_SETUP([Numbered tokens])
AT_DATA_GRAMMAR([redecl.y],
[[%token DECIMAL_1 11259375
HEXADECIMAL_1 0xabcdef
HEXADECIMAL_2 0xFEDCBA
DECIMAL_2 16702650
%%
start: DECIMAL_1 HEXADECIMAL_2;
]])
AT_BISON_CHECK([redecl.y], [1], [],
[[redecl.y:10.10-22: error: user token number 11259375 redeclaration for HEXADECIMAL_1
redecl.y:9.8-16: previous declaration for DECIMAL_1
redecl.y:12.10-18: error: user token number 16702650 redeclaration for DECIMAL_2
redecl.y:11.10-22: previous declaration for HEXADECIMAL_2
]])
AT_DATA_GRAMMAR([too-large.y],
[[%token TOO_LARGE_DEC 999999999999999999999
TOO_LARGE_HEX 0xFFFFFFFFFFFFFFFFFFF
%%
start: TOO_LARGE_DEC TOO_LARGE_HEX
%%
]])
AT_BISON_CHECK([too-large.y], [1], [],
[[too-large.y:9.22-42: error: integer out of range: '999999999999999999999'
too-large.y:10.24-44: error: integer out of range: '0xFFFFFFFFFFFFFFFFFFF'
]])
AT_CLEANUP
## --------------------- ##
## Unclosed constructs. ##
## --------------------- ##
AT_SETUP([Unclosed constructs])
# Bison's scan-gram.l once forgot to STRING_FINISH some unclosed
# constructs, so they were prepended to whatever it STRING_GROW'ed
# next. It also threw them away rather than returning them to the
# parser. The effect was confusing subsequent error messages.
AT_DATA([input.y],
[[%token A "a
%token B "b"
%token AB "ab" // Used to complain that "ab" was already used.
%token C '1
%token TWO "2"
%token TICK_TWELVE "'12" // Used to complain that "'12" was already used.
%%
start: ;
// Used to report a syntax error because it didn't see any kind of symbol
// identifier.
%type <f> 'a
;
%type <f> "a
;
// Used to report a syntax error because it didn't see braced code.
%destructor { free ($$)
]])
AT_BISON_CHECK([-o input.c input.y], 1, [],
[[input.y:1.10-2.0: error: missing '"' at end of line
input.y:4.10-5.0: error: missing "'" at end of line
input.y:14.11-15.0: error: missing "'" at end of line
input.y:16.11-17.0: error: missing '"' at end of line
input.y:19.13-20.0: error: missing '}' at end of file
input.y:20.1: error: syntax error, unexpected end of file
]])
AT_CLEANUP
## ------------------------- ##
## %start after first rule. ##
## ------------------------- ##
AT_SETUP([%start after first rule])
# Bison once complained that a %start after the first rule was a
# redeclaration of the start symbol.
AT_DATA([input.y],
[[%%
false_start: ;
start: false_start ;
%start start;
]])
AT_BISON_CHECK([-o input.c input.y])
AT_CLEANUP
## --------------------- ##
## %prec takes a token. ##
## --------------------- ##
AT_SETUP([%prec takes a token])
# Bison once allowed %prec sym where sym was a nonterminal.
AT_DATA([input.y],
[[%%
start: PREC %prec PREC ;
PREC: ;
]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:3.1-4: error: rule given for PREC, which is a token
]])
AT_CLEANUP
## ------------------------------- ##
## %prec's token must be defined. ##
## ------------------------------- ##
AT_SETUP([[%prec's token must be defined]])
# According to POSIX, a %prec token must be defined separately.
AT_DATA([[input.y]],
[[%%
start: %prec PREC ;
]])
AT_BISON_CHECK([[input.y]], [[0]], [],
[[input.y:2.8-17: warning: token for %prec is not defined: PREC [-Wother]
]])
AT_CLEANUP
## -------------------------------- ##
## Reject unused %code qualifiers. ##
## -------------------------------- ##
AT_SETUP([Reject unused %code qualifiers])
AT_DATA([input-c.y],
[[%code q {}
%code bad {}
%code bad {}
%code format {}
%%
start: ;
]])
AT_BISON_CHECK([[input-c.y]], [[1]], [],
[[input-c.y:1.7: error: %code qualifier 'q' is not used
input-c.y:2.7-9: error: %code qualifier 'bad' is not used
input-c.y:3.7-9: error: %code qualifier 'bad' is not used
input-c.y:4.7-12: error: %code qualifier 'format' is not used
]])
AT_DATA([input-c-glr.y],
[[%code q {}
%code bad {}
%code bad {}
%%
start: ;
]])
AT_BISON_CHECK([[input-c-glr.y]], [[1]], [],
[[input-c-glr.y:1.7: error: %code qualifier 'q' is not used
input-c-glr.y:2.7-9: error: %code qualifier 'bad' is not used
input-c-glr.y:3.8-10: error: %code qualifier 'bad' is not used
]])
AT_DATA([input-c++.y],
[[%code q {}
%code bad {}
%code q {}
%%
start: ;
]])
AT_BISON_CHECK([[input-c++.y]], [[1]], [],
[[input-c++.y:1.7: error: %code qualifier 'q' is not used
input-c++.y:2.7-9: error: %code qualifier 'bad' is not used
input-c++.y:3.8: error: %code qualifier 'q' is not used
]])
AT_DATA([input-c++-glr.y],
[[%code bad {}
%code q {}
%code q {}
%%
start: ;
]])
AT_BISON_CHECK([[input-c++-glr.y]], [[1]], [],
[[input-c++-glr.y:1.7-9: error: %code qualifier 'bad' is not used
input-c++-glr.y:2.7: error: %code qualifier 'q' is not used
input-c++-glr.y:3.7: error: %code qualifier 'q' is not used
]])
AT_DATA([special-char-@@.y],
[[%code bad {}
%code q {}
%code q {}
%%
start: ;
]])
AT_BISON_CHECK([[special-char-@@.y]], [[1]], [],
[[special-char-@@.y:1.7-9: error: %code qualifier 'bad' is not used
special-char-@@.y:2.7: error: %code qualifier 'q' is not used
special-char-@@.y:3.7: error: %code qualifier 'q' is not used
]])
AT_DATA([special-char-@:>@.y],
[[%code bad {}
%code q {}
%code q {}
%%
start: ;
]])
AT_BISON_CHECK([[special-char-@:>@.y]], [[1]], [],
[[special-char-@:>@.y:1.7-9: error: %code qualifier 'bad' is not used
special-char-@:>@.y:2.7: error: %code qualifier 'q' is not used
special-char-@:>@.y:3.7: error: %code qualifier 'q' is not used
]])
AT_CLEANUP
## ---------------- ##
## %define errors. ##
## ---------------- ##
AT_SETUP([%define errors])
AT_DATA([input-redefined.y],
[[%define var "value1"
%define var "value1"
%define var "value2"
%define special1 "@:>@"
%define special2 "@<:@"
%%
start: ;
]])
AT_BISON_CHECK([[input-redefined.y]], [[1]], [],
[[input-redefined.y:2.9-11: error: %define variable 'var' redefined
input-redefined.y:1.9-11: previous definition
input-redefined.y:3.10-12: error: %define variable 'var' redefined
input-redefined.y:2.9-11: previous definition
]])
AT_DATA([input-unused.y],
[[%define var "value"
%%
start: ;
]])
AT_BISON_CHECK([[input-unused.y]], [[1]], [],
[[input-unused.y:1.9-11: error: %define variable 'var' is not used
]])
AT_CLEANUP
## ----------------------------------- ##
## %define, --define, --force-define. ##
## ----------------------------------- ##
AT_SETUP([[%define, --define, --force-define]])
AT_DATA([[skel.c]],
[[m4@&t@_divert_push(0)@
@output(b4_parser_file_name@)@
[var-dd: ]b4_percent_define_get([[var-dd]])[
var-ff: ]b4_percent_define_get([[var-ff]])[
var-dfg: ]b4_percent_define_get([[var-dfg]])[
var-fd: ]b4_percent_define_get([[var-fd]])
m4@&t@_divert_pop(0)
]])
AT_DATA([[input.y]],
[[%define var-dfg "gram"
%%
start: ;
]])
AT_BISON_CHECK([[-Dvar-dd=cmd-d1 -Dvar-dd=cmd-d2 \
-Fvar-ff=cmd-f1 -Fvar-ff=cmd-f2 \
-Dvar-dfg=cmd-d -Fvar-dfg=cmd-f \
-Fvar-fd=cmd-f -Dvar-fd=cmd-d \
--skeleton ./skel.c input.y]])
AT_CHECK([[cat input.tab.c]], [[0]],
[[var-dd: cmd-d2
var-ff: cmd-f2
var-dfg: cmd-f
var-fd: cmd-d
]])
AT_DATA([[input-dg.y]],
[[%define var "gram"
%%
start: ;
]])
AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [],
[[input-dg.y:1.9-11: error: %define variable 'var' redefined
<command line>:2: previous definition
]])
AT_DATA([[input-unused.y]],
[[%%
start: ;
]])
AT_BISON_CHECK([[-Dunused-d -Funused-f input-unused.y]], [[1]], [],
[[<command line>:2: error: %define variable 'unused-d' is not used
<command line>:3: error: %define variable 'unused-f' is not used
]])
AT_CLEANUP
## --------------------------- ##
## %define Boolean variables. ##
## --------------------------- ##
AT_SETUP([[%define Boolean variables]])
AT_DATA([Input.y],
[[%language "Java"
%define public "maybe"
%define parser_class_name "Input"
%%
start: ;
]])
AT_BISON_CHECK([[Input.y]], [1], [],
[[Input.y:2.9-14: error: invalid value for %define Boolean variable 'public'
]])
AT_CLEANUP
## ------------------------ ##
## %define enum variables. ##
## ------------------------ ##
AT_SETUP([[%define enum variables]])
# Front-end.
AT_DATA([[input.y]],
[[%define lr.default-reductions bogus
%%
start: ;
]])
AT_BISON_CHECK([[input.y]], [[1]], [[]],
[[input.y:1.9-29: error: invalid value for %define variable 'lr.default-reductions': 'bogus'
input.y:1.9-29: accepted value: 'most'
input.y:1.9-29: accepted value: 'consistent'
input.y:1.9-29: accepted value: 'accepting'
]])
# Back-end.
# FIXME: these should be indented, but we shouldn't mess with the m4 yet
AT_DATA([[input.y]],
[[%define api.push-pull neither
%%
start: ;
]])
AT_BISON_CHECK([[input.y]], [1], [],
[[input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither'
input.y:1.9-21: error: accepted value: 'pull'
input.y:1.9-21: error: accepted value: 'push'
input.y:1.9-21: error: accepted value: 'both'
]])
AT_CLEANUP
## -------------------------------- ##
## %define backward compatibility. ##
## -------------------------------- ##
AT_SETUP([[%define backward compatibility]])
# The error messages tell us whether underscores in these variables are
# being converted to dashes.
AT_DATA([[input.y]],
[[%define api.push_pull "neither"
%%
start: ;
]])
AT_BISON_CHECK([[input.y]], [1], [],
[[input.y:1.9-21: warning: deprecated %define variable name: 'api.push_pull', use 'api.push-pull' [-Wdeprecated]
input.y:1.9-21: error: invalid value for %define variable 'api.push-pull': 'neither'
input.y:1.9-21: error: accepted value: 'pull'
input.y:1.9-21: error: accepted value: 'push'
input.y:1.9-21: error: accepted value: 'both'
]])
AT_DATA([[input.y]],
[[%define lr.keep_unreachable_states maybe
%%
start: ;
]])
AT_BISON_CHECK([[input.y]], [1], [],
[[input.y:1.9-34: warning: deprecated %define variable name: 'lr.keep_unreachable_states', use 'lr.keep-unreachable-states' [-Wdeprecated]
input.y:1.9-34: error: invalid value for %define Boolean variable 'lr.keep-unreachable-states'
]])
AT_DATA([[input.y]],
[[%define namespace "foo"
%define api.namespace "foo"
%%
start: ;
]])
AT_BISON_CHECK([[input.y]], [1], [],
[[input.y:1.9-17: warning: deprecated %define variable name: 'namespace', use 'api.namespace' [-Wdeprecated]
input.y:2.9-21: error: %define variable 'api.namespace' redefined
input.y:1.9-17: previous definition
]])
AT_DATA([[input.y]],
[[%define foo_bar "baz"
%%
start: ;
]])
AT_BISON_CHECK([[input.y]], [[1]], [],
[[input.y:1.9-15: error: %define variable 'foo_bar' is not used
]])
AT_CLEANUP
## ------------------------- ##
## Unused %define api.pure. ##
## ------------------------- ##
AT_SETUP([[Unused %define api.pure]])
# AT_CHECK_API_PURE(DECLS, VALUE)
# -------------------------------
# Make sure Bison reports that `%define api.pure VALUE' is unused when DECLS
# are specified.
m4_define([AT_CHECK_API_PURE],
[
AT_DATA([[input.y]],
[[%define api.pure ]$2[
]$1[
%%
start: ;
]])
AT_BISON_CHECK([[input.y]], [[1]], [],
[[input.y:1.9-16: error: %define variable 'api.pure' is not used
]])
])
AT_CHECK_API_PURE([[%language "c++" %defines]], [[]])
AT_CHECK_API_PURE([[%language "c++" %defines]], [[false]])
AT_CHECK_API_PURE([[%language "c++" %defines %glr-parser]], [[""]])
AT_CHECK_API_PURE([[%language "c++" %defines %glr-parser]], [[false]])
AT_CHECK_API_PURE([[%language "java"]], [[true]])
AT_CHECK_API_PURE([[%language "java"]], [[false]])
AT_CLEANUP
## -------------------------------- ##
## C++ namespace reference errors. ##
## -------------------------------- ##
AT_SETUP([[C++ namespace reference errors]])
# AT_CHECK_NAMESPACE_ERROR(NAMESPACE-DECL, ERROR, [ERROR], ...)
# -------------------------------------------------------------
# Make sure Bison reports all ERROR's for %define namespace "NAMESPACE-DECL".
m4_define([AT_CHECK_NAMESPACE_ERROR],
[
AT_DATA([[input.y]],
[[%language "C++"
%defines
%define api.namespace "]$1["
%%
start: ;
]])
AT_BISON_CHECK([[input.y]], [1], [],
[m4_foreach([b4_arg], m4_dquote(m4_shift($@)),
[[input.y:3.9-21: error: ]b4_arg[
]])])
])
AT_CHECK_NAMESPACE_ERROR([[]],
[[namespace reference is empty]])
AT_CHECK_NAMESPACE_ERROR([[ ]],
[[namespace reference is empty]])
AT_CHECK_NAMESPACE_ERROR([[foo::::bar]],
[[namespace reference has consecutive "::"]])
AT_CHECK_NAMESPACE_ERROR([[foo:: ::bar]],
[[namespace reference has consecutive "::"]])
AT_CHECK_NAMESPACE_ERROR([[::::bar]],
[[namespace reference has consecutive "::"]])
AT_CHECK_NAMESPACE_ERROR([[:: ::bar]],
[[namespace reference has consecutive "::"]])
AT_CHECK_NAMESPACE_ERROR([[foo::bar:: ::]],
[[namespace reference has consecutive "::"]],
[[namespace reference has a trailing "::"]])
AT_CHECK_NAMESPACE_ERROR([[foo::bar::]],
[[namespace reference has a trailing "::"]])
AT_CHECK_NAMESPACE_ERROR([[foo::bar:: ]],
[[namespace reference has a trailing "::"]])
AT_CHECK_NAMESPACE_ERROR([[::]],
[[namespace reference has a trailing "::"]])
AT_CLEANUP
## ------------------------ ##
## Bad character literals. ##
## ------------------------ ##
# Bison used to accept character literals that were empty or contained
# too many characters.
# FIXME: AT_DATA or some variant of AT_DATA may eventually permit
# the final newline to be omitted. See the threads starting at
# <http://lists.gnu.org/archive/html/bison-patches/2009-07/msg00019.html>.
AT_SETUP([[Bad character literals]])
AT_DATA([empty.y],
[[%%
start: '';
start: '
]])
AT_CHECK([[perl -e "print 'start: \'';" >> empty.y || exit 77]])
AT_BISON_CHECK([empty.y], [1], [],
[[empty.y:2.8-9: warning: empty character literal [-Wother]
empty.y:3.8-4.0: warning: empty character literal [-Wother]
empty.y:3.8-4.0: error: missing "'" at end of line
empty.y:4.8: warning: empty character literal [-Wother]
empty.y:4.8: error: missing "'" at end of file
]])
AT_DATA([two.y],
[[%%
start: 'ab';
start: 'ab
]])
AT_CHECK([[perl -e "print 'start: \'ab';" >> two.y || exit 77]])
AT_BISON_CHECK([two.y], [1], [],
[[two.y:2.8-11: warning: extra characters in character literal [-Wother]
two.y:3.8-4.0: warning: extra characters in character literal [-Wother]
two.y:3.8-4.0: error: missing "'" at end of line
two.y:4.8-10: warning: extra characters in character literal [-Wother]
two.y:4.8-10: error: missing "'" at end of file
]])
AT_DATA([three.y],
[[%%
start: 'abc';
start: 'abc
]])
AT_CHECK([[perl -e "print 'start: \'abc';" >> three.y || exit 77]])
AT_BISON_CHECK([three.y], [1], [],
[[three.y:2.8-12: warning: extra characters in character literal [-Wother]
three.y:3.8-4.0: warning: extra characters in character literal [-Wother]
three.y:3.8-4.0: error: missing "'" at end of line
three.y:4.8-11: warning: extra characters in character literal [-Wother]
three.y:4.8-11: error: missing "'" at end of file
]])
AT_CLEANUP
## ------------------------- ##
## Bad escapes in literals. ##
## ------------------------- ##
AT_SETUP([[Bad escapes in literals]])
AT_DATA([input.y],
[[%%
start: '\777' '\0' '\xfff' '\x0'
'\uffff' '\u0000' '\Uffffffff' '\U00000000'
'\ ' '\A';
]])
# It is not easy to create special characters, we cannot even trust tr.
# Beside we cannot even expect "echo '\0'" to output two characters
# (well three with \n): at least Bash 3.2 converts the two-character
# sequence "\0" into a single NUL character.
AT_CHECK([[perl -e 'print "start: \"\\\t\\\f\\\0\\\1\" ;";' >> input.y \
|| exit 77]])
AT_BISON_CHECK([input.y], [1], [],
[[input.y:2.9-12: error: invalid number after \-escape: 777
input.y:2.8-13: warning: empty character literal [-Wother]
input.y:2.16-17: error: invalid number after \-escape: 0
input.y:2.15-18: warning: empty character literal [-Wother]
input.y:2.21-25: error: invalid number after \-escape: xfff
input.y:2.20-26: warning: empty character literal [-Wother]
input.y:2.29-31: error: invalid number after \-escape: x0
input.y:2.28-32: warning: empty character literal [-Wother]
input.y:3.9-14: error: invalid number after \-escape: uffff
input.y:3.8-15: warning: empty character literal [-Wother]
input.y:3.18-23: error: invalid number after \-escape: u0000
input.y:3.17-24: warning: empty character literal [-Wother]
input.y:3.27-36: error: invalid number after \-escape: Uffffffff
input.y:3.26-37: warning: empty character literal [-Wother]
input.y:3.40-49: error: invalid number after \-escape: U00000000
input.y:3.39-50: warning: empty character literal [-Wother]
input.y:4.9-10: error: invalid character after \-escape: ' '
input.y:4.8-11: warning: empty character literal [-Wother]
input.y:4.14-15: error: invalid character after \-escape: A
input.y:4.13-16: warning: empty character literal [-Wother]
input.y:5.9-16: error: invalid character after \-escape: \t
input.y:5.17: error: invalid character after \-escape: \f
input.y:5.18: error: invalid character after \-escape: \0
input.y:5.19: error: invalid character after \-escape: \001
]])
AT_CLEANUP
## ------------------------- ##
## LAC: Errors for %define. ##
## ------------------------- ##
AT_SETUP([[LAC: Errors for %define]])
AT_DATA([[input.y]],
[[%%
start: ;
]])
# parse.lac.* options are useless if LAC isn't actually activated.
AT_BISON_CHECK([[-Dparse.lac.es-capacity-initial=1 input.y]],
[[1]], [],
[[<command line>:2: error: %define variable 'parse.lac.es-capacity-initial' is not used
]])
AT_BISON_CHECK([[-Dparse.lac.memory-trace=full input.y]],
[[1]], [],
[[<command line>:2: error: %define variable 'parse.lac.memory-trace' is not used
]])
AT_CLEANUP
## --------------------------------------------- ##
## -Werror is not affected by -Wnone and -Wall. ##
## --------------------------------------------- ##
AT_SETUP([[-Werror is not affected by -Wnone and -Wall]])
AT_DATA([[input.y]],
[[%%
foo-bar: ;
]])
# -Werror is not enabled by -Wall or equivalent.
AT_BISON_CHECK([[-Wall input.y]], [[0]], [[]],
[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
]])
AT_BISON_CHECK([[-W input.y]], [[0]], [[]],
[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
]])
AT_BISON_CHECK([[-Wno-none input.y]], [[0]], [[]],
[[input.y:2.1-7: warning: POSIX Yacc forbids dashes in symbol names: foo-bar [-Wyacc]
]])
# -Werror is not disabled by -Wnone or equivalent.
AT_BISON_CHECK([[-Werror,none,yacc input.y]], [[1]], [[]], [[stderr]])
AT_CHECK([[sed 's/^.*bison:/bison:/' stderr]], [[0]],
[[input.y:2.1-7: error: POSIX Yacc forbids dashes in symbol names: foo-bar [-Werror=yacc]
]])
[mv stderr experr]
AT_BISON_CHECK([[-Werror,no-all,yacc input.y]], [[1]], [[]], [[experr]])
AT_CLEANUP
## ------------------------------------------------------ ##
## %name-prefix and %define api.prefix are incompatible. ##
## ------------------------------------------------------ ##
AT_SETUP([[%name-prefix and %define api.prefix are incompatible]])
# AT_TEST(DIRECTIVES, OPTIONS, ERROR-LOCATION)
# --------------------------------------------
m4_pushdef([AT_TEST],
[AT_DATA([[input.y]],
[[$1
%%
exp:;
]])
AT_BISON_CHECK([[$2 input.y]], [[1]], [[]],
[[$3: error: '%name-prefix' and '%define api.prefix' cannot be used together
]])
])
AT_TEST([%define api.prefix foo %name-prefix "bar"], [], [input.y:1.9-18])
AT_TEST([], [-Dapi.prefix=foo -p bar], [<command line>:2])
AT_TEST([%name-prefix "bar"], [-Dapi.prefix=foo], [<command line>:2])
AT_TEST([%define api.prefix foo], [-p bar], [input.y:1.9-18])
m4_popdef([AT_TEST])
AT_CLEANUP
## -------------- ##
## Stray $ or @. ##
## -------------- ##
AT_SETUP([[Stray $ or @]])
# Give %printer and %destructor "<*> exp TOK" instead of "<*>" to
# check that the warnings are reported once, not three times.
AT_DATA_GRAMMAR([[input.y]],
[[%type <TYPE> exp
%token <TYPE> TOK TOK2
%destructor { $%; @%; } <*> exp TOK;
%initial-action { $%; @%; };
%printer { $%; @%; } <*> exp TOK;
%%
exp: TOK { $%; @%; $$ = $1; };
]])
AT_BISON_CHECK([[input.y]], 0, [],
[[input.y:11.19: warning: stray '$' [-Wother]
input.y:11.23: warning: stray '@' [-Wother]
input.y:12.19: warning: stray '$' [-Wother]
input.y:12.23: warning: stray '@' [-Wother]
input.y:13.19: warning: stray '$' [-Wother]
input.y:13.23: warning: stray '@' [-Wother]
input.y:15.19: warning: stray '$' [-Wother]
input.y:15.23: warning: stray '@' [-Wother]
]])
AT_CLEANUP
## ---------------- ##
## Code injection. ##
## ---------------- ##
AT_SETUP([[Code injection]])
m4_pattern_allow([^m4_errprintn$])
# AT_TEST([MACRO])
# ----------------
# Try to have MACRO be run by bison.
m4_pushdef([AT_TEST],
[AT_DATA([[input.y]],
[[%type <$1(DEAD %type)> exp
%token <$1(DEAD %token)> a
%token b
%initial-action
{
$$;
$<$1(DEAD %initial-action)>$
};
%printer
{
$$
$<$1(DEAD %printer)>$
} <> <*>;
%lex-param
{
$1(DEAD %lex-param)
};
%parse-param
{
$1(DEAD %parse-param)
};
%%
exp:
a a[name] b
{
$$;
$][1;
$<$1(DEAD action 1)>$
$<$1(DEAD action 2)>1
$<$1(DEAD action 3)>name
$<$1(DEAD action 4)>0
;
};
]])
# FIXME: Provide a means to iterate over all the skeletons.
AT_BISON_CHECK([[-d input.y]])
AT_BISON_CHECK([[-d -S glr.c input.y]])
AT_BISON_CHECK([[-d -S lalr1.cc input.y]])
AT_BISON_CHECK([[-d -S glr.cc input.y]])
AT_BISON_CHECK([[ -S lalr1.java input.y]])
])
AT_TEST([m4_errprintn])
AT_TEST([@:>@m4_errprintn])
m4_popdef([AT_TEST])
AT_CLEANUP