]> git.saurik.com Git - bison.git/blame - tests/torture.at
Work around Java's ``code too large'' problem for parser tables.
[bison.git] / tests / torture.at
CommitLineData
6d7d248e 1# Torturing Bison. -*- Autotest -*-
279cabb6
JD
2# Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007 Free Software Foundation,
3# Inc.
6d7d248e 4
f16b0819 5# This program is free software: you can redistribute it and/or modify
6d7d248e 6# it under the terms of the GNU General Public License as published by
f16b0819
PE
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
6d7d248e
AD
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
f16b0819 14#
6d7d248e 15# You should have received a copy of the GNU General Public License
f16b0819 16# along with this program. If not, see <http://www.gnu.org/licenses/>.
6d7d248e
AD
17
18AT_BANNER([[Torture Tests.]])
19
20
49e794c5 21# AT_INCREASE_DATA_SIZE(SIZE)
f79b4f5c 22# ---------------------------
49e794c5
PE
23# Try to increase the data size to SIZE KiB if possible.
24m4_define([AT_INCREASE_DATA_SIZE],
25[data_limit=`(ulimit -S -d) 2>/dev/null`
26case $data_limit in
27[[0-9]]*)
28 if test "$data_limit" -lt $1; then
f79b4f5c 29 AT_CHECK([ulimit -S -d $1 || exit 77])
49e794c5
PE
30 ulimit -S -d $1
31 fi
32esac])
33
34
817e9f41
AD
35## ------------------------------------- ##
36## Creating a large artificial grammar. ##
37## ------------------------------------- ##
38
39# AT_DATA_TRIANGULAR_GRAMMAR(FILE-NAME, SIZE)
40# -------------------------------------------
41# Create FILE-NAME, containing a self checking parser for a huge
42# triangular grammar.
817e9f41
AD
43m4_define([AT_DATA_TRIANGULAR_GRAMMAR],
44[AT_DATA([[gengram.pl]],
45[[#! /usr/bin/perl -w
46
47use strict;
48my $max = $ARGV[0] || 10;
49
50print <<EOF;
9501dc6e 51]AT_DATA_GRAMMAR_PROLOGUE[
8f3596a6
AD
52%error-verbose
53%debug
817e9f41
AD
54%{
55#include <stdio.h>
56#include <stdlib.h>
817e9f41 57
817e9f41
AD
58static int yylex (void);
59static void yyerror (const char *msg);
60%}
61%union
62{
63 int val;
64};
65
66%token END "end"
67%type <val> exp input
68EOF
69
70for my $size (1 .. $max)
71 {
e9955c83 72 print "%token t$size $size \"$size\"\n";
817e9f41
AD
73 };
74
75print <<EOF;
76%%
77input:
66871a81
PE
78 exp { if (\@S|@1 != 0) abort (); \$\$ = \@S|@1; }
79| input exp { if (\@S|@2 != \@S|@1 + 1) abort (); \$\$ = \@S|@2; }
817e9f41
AD
80;
81
82exp:
83 END
84 { \$\$ = 0; }
85EOF
86
87for my $size (1 .. $max)
88 {
89 use Text::Wrap;
90 print wrap ("| ", " ",
91 (map { "\"$_\"" } (1 .. $size)),
92 " END \n"),
93 " { \$\$ = $size; }\n";
94 };
95print ";\n";
96
97print <<EOF;
98%%
99static int
100yylex (void)
101{
102 static int inner = 1;
103 static int outer = 0;
104 if (outer > $max)
105 return 0;
106 else if (inner > outer)
107 {
108 inner = 1;
109 ++outer;
110 return END;
111 }
23c5a174 112 return inner++;
817e9f41
AD
113}
114
115static void
116yyerror (const char *msg)
117{
118 fprintf (stderr, "%s\\n", msg);
119}
120
121int
122main (void)
123{
124 yydebug = !!getenv ("YYDEBUG");
125 return yyparse ();
126}
127EOF
128]])
129
130AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
131mv stdout $1
132])
133
134
135## -------------- ##
136## Big triangle. ##
137## -------------- ##
138
817e9f41
AD
139AT_SETUP([Big triangle])
140
355e7c1c
AD
141# I have been able to go up to 2000 on my machine.
142# I tried 3000, a 29Mb grammar file, but then my system killed bison.
e9955c83
AD
143# With 500 and the new parser, which consume far too much memory,
144# it gets killed too. Of course the parser is to be cleaned.
145AT_DATA_TRIANGULAR_GRAMMAR([input.y], [200])
da730230 146AT_BISON_CHECK_NO_XML([-v -o input.c input.y])
1154cced
AD
147AT_COMPILE([input])
148AT_PARSER_CHECK([./input])
817e9f41
AD
149
150AT_CLEANUP
151
152
153
62a3e4f0
AD
154# AT_DATA_HORIZONTAL_GRAMMAR(FILE-NAME, SIZE)
155# -------------------------------------------
156# Create FILE-NAME, containing a self checking parser for a huge
157# horizontal grammar.
62a3e4f0
AD
158m4_define([AT_DATA_HORIZONTAL_GRAMMAR],
159[AT_DATA([[gengram.pl]],
160[[#! /usr/bin/perl -w
161
162use strict;
163my $max = $ARGV[0] || 10;
164
165print <<EOF;
9501dc6e 166]AT_DATA_GRAMMAR_PROLOGUE[
8f3596a6
AD
167%error-verbose
168%debug
62a3e4f0
AD
169%{
170#include <stdio.h>
171#include <stdlib.h>
62a3e4f0 172
62a3e4f0
AD
173static int yylex (void);
174static void yyerror (const char *msg);
175%}
62a3e4f0 176
8f3596a6
AD
177%token
178EOF
62a3e4f0
AD
179for my $size (1 .. $max)
180 {
8f3596a6 181 print " t$size $size \"$size\"\n";
62a3e4f0
AD
182 };
183
184print <<EOF;
8f3596a6 185
62a3e4f0
AD
186%%
187EOF
188
189use Text::Wrap;
190print
191 wrap ("exp: ", " ",
192 (map { "\"$_\"" } (1 .. $max)), ";"),
193 "\n";
194
195print <<EOF;
196%%
197static int
198yylex (void)
199{
200 static int counter = 1;
cf806753
PE
201 if (counter <= $max)
202 return counter++;
203 if (counter++ != $max + 1)
204 abort ();
205 return 0;
62a3e4f0
AD
206}
207
208static void
209yyerror (const char *msg)
210{
211 fprintf (stderr, "%s\\n", msg);
212}
213
214int
215main (void)
216{
217 yydebug = !!getenv ("YYDEBUG");
218 return yyparse ();
219}
220EOF
221]])
222
223AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
224mv stdout $1
225])
226
227
228## ---------------- ##
229## Big horizontal. ##
230## ---------------- ##
231
232AT_SETUP([Big horizontal])
233
234# I have been able to go up to 10000 on my machine, but I had to
235# increase the maximum stack size (* 100). It gave:
236#
237# input.y 263k
238# input.tab.c 1.3M
239# input 453k
240#
241# gengram.pl 10000 0.70s user 0.01s sys 99% cpu 0.711 total
242# bison input.y 730.56s user 0.53s sys 99% cpu 12:12.34 total
243# gcc -Wall input.tab.c -o input 5.81s user 0.20s sys 100% cpu 6.01 total
244# ./input 0.00s user 0.01s sys 108% cpu 0.01 total
245#
246AT_DATA_HORIZONTAL_GRAMMAR([input.y], [1000])
49e794c5
PE
247
248# GNU m4 requires about 70 MiB for this test on a 32-bit host.
249# Ask for 200 MiB, which should be plenty even on a 64-bit host.
250AT_INCREASE_DATA_SIZE(204000)
251
da730230 252AT_BISON_CHECK_NO_XML([-v -o input.c input.y])
1154cced
AD
253AT_COMPILE([input])
254AT_PARSER_CHECK([./input])
62a3e4f0
AD
255
256AT_CLEANUP
257
258
259
742e4900 260# AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR(FILE-NAME, SIZE)
8f3596a6 261# --------------------------------------------------
39ceb25b 262# Create FILE-NAME, containing a self checking parser for a grammar
742e4900
JD
263# requiring SIZE lookahead tokens.
264m4_define([AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR],
39ceb25b
AD
265[AT_DATA([[gengram.pl]],
266[[#! /usr/bin/perl -w
267
268use strict;
269use Text::Wrap;
270my $max = $ARGV[0] || 10;
271
272print <<EOF;
8f3596a6
AD
273%error-verbose
274%debug
39ceb25b 275%{
8f3596a6
AD
276# include <stdio.h>
277# include <stdlib.h>
278# include <assert.h>
39ceb25b
AD
279
280static int yylex (void);
281static void yyerror (const char *msg);
282%}
283%union
284{
285 int val;
286};
287
288%type <val> input exp
289%token token
290EOF
291
292print
293 wrap ("%type <val> ",
294 " ",
e9955c83 295 map { "n$_" } (1 .. $max)),
39ceb25b
AD
296 "\n";
297
8f3596a6 298print "%token\n";
39ceb25b
AD
299for my $count (1 .. $max)
300 {
8f3596a6 301 print " t$count $count \"$count\"\n";
39ceb25b
AD
302 };
303
304print <<EOF;
305%%
306input:
8f3596a6
AD
307 exp { assert (\@S|@1 == 1); \$\$ = \@S|@1; }
308| input exp { assert (\@S|@2 == \@S|@1 + 1); \$\$ = \@S|@2; }
39ceb25b
AD
309;
310
311exp:
8f3596a6 312 n1 "1" { assert (\@S|@1 == 1); \@S|@\@S|@ = \@S|@1; }
39ceb25b
AD
313EOF
314
315for my $count (2 .. $max)
316 {
8f3596a6 317 print "| n$count \"$count\" { assert (\@S|@1 == $count); \@S|@\@S|@ = \@S|@1; }\n";
39ceb25b
AD
318 };
319print ";\n";
320
321for my $count (1 .. $max)
322 {
e9955c83 323 print "n$count: token { \$\$ = $count; };\n";
39ceb25b
AD
324 };
325
326print <<EOF;
327%%
328static int
329yylex (void)
330{
331 static int return_token = 1;
332 static int counter = 1;
333 if (counter > $max)
cf806753
PE
334 {
335 if (counter++ != $max + 1)
336 abort ();
337 return 0;
338 }
39ceb25b
AD
339 if (return_token)
340 {
341 return_token = 0;
342 return token;
343 }
344 return_token = 1;
345 return counter++;
346}
347
348static void
349yyerror (const char *msg)
350{
351 fprintf (stderr, "%s\\n", msg);
352}
353
354int
355main (void)
356{
357 yydebug = !!getenv ("YYDEBUG");
358 return yyparse ();
359}
360EOF
361]])
362
363AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
364mv stdout $1
365])
366
367
8dd162d3 368## ------------------------ ##
7d596384 369## Many lookahead tokens. ##
8dd162d3 370## ------------------------ ##
39ceb25b 371
742e4900 372AT_SETUP([Many lookahead tokens])
39ceb25b 373
742e4900 374AT_DATA_LOOKAHEAD_TOKENS_GRAMMAR([input.y], [1000])
49e794c5
PE
375
376# GNU m4 requires about 70 MiB for this test on a 32-bit host.
377# Ask for 200 MiB, which should be plenty even on a 64-bit host.
378AT_INCREASE_DATA_SIZE(204000)
379
da730230 380AT_BISON_CHECK([-v -o input.c input.y])
1154cced
AD
381AT_COMPILE([input])
382AT_PARSER_CHECK([./input])
39ceb25b
AD
383
384AT_CLEANUP
385
386
387
7d596384
JD
388# AT_DATA_STACK_TORTURE(C-PROLOGUE, [BISON-DECLS])
389# ------------------------------------------------
6d7d248e
AD
390# A parser specialized in torturing the stack size.
391m4_define([AT_DATA_STACK_TORTURE],
392[# A grammar of parens growing the stack thanks to right recursion.
393# exp:
394AT_DATA([input.y],
395[[%{
04098407
PE
396#include <errno.h>
397#include <limits.h>
6d7d248e
AD
398#include <stdio.h>
399#include <stdlib.h>
6d7d248e
AD
400]$1[
401 static int yylex (void);
402 static void yyerror (const char *msg);
6d7d248e 403%}
7d596384 404]$2[
04d843a2 405%error-verbose
6d7d248e
AD
406%debug
407%token WAIT_FOR_EOF
408%%
409exp: WAIT_FOR_EOF exp | ;
410%%
411static void
412yyerror (const char *msg)
413{
414 fprintf (stderr, "%s\n", msg);
6d7d248e
AD
415}
416
6d7d248e
AD
417static int
418yylex (void)
419{
cf806753
PE
420 if (yylval < 0)
421 abort ();
6d7d248e
AD
422 if (yylval--)
423 return WAIT_FOR_EOF;
424 else
425 return EOF;
426}
427
428int
429main (int argc, const char **argv)
430{
04098407 431 char *endp;
7d596384 432 YYSTYPE yylval_init;
66871a81
PE
433 if (argc != 2)
434 abort ();
7d596384 435 yylval_init = strtol (argv[1], &endp, 10);
04098407 436 if (! (argv[1] != endp
7d596384 437 && 0 <= yylval_init && yylval_init <= INT_MAX
04098407
PE
438 && errno != ERANGE))
439 abort ();
6d7d248e 440 yydebug = 1;
7d596384
JD
441 {
442 int count;
443 int status;
444]m4_bmatch([$2], [%push-],
5d31a216 445[[ yypstate *ps = yypstate_new ();
7d596384
JD
446]])[ for (count = 0; count < 2; ++count)
447 {
448 int new_status;
449 yylval = yylval_init;
450]m4_bmatch([$2], [%push-],
5d31a216 451[[ new_status = yypull_parse (ps);
7d596384
JD
452]],
453[[ new_status = yyparse ();
454]])[ if (count > 0 && new_status != status)
455 abort ();
456 status = new_status;
457 }
458]m4_bmatch([$2], [%push-],
5d31a216 459[[ yypstate_delete (ps);
7d596384
JD
460]])[ return status;
461 }
6d7d248e
AD
462}
463]])
da730230 464AT_BISON_CHECK([-o input.c input.y])
1154cced 465AT_COMPILE([input])
6d7d248e
AD
466])
467
468
469## -------------------------------------- ##
470## Exploding the Stack Size with Alloca. ##
471## -------------------------------------- ##
472
473AT_SETUP([Exploding the Stack Size with Alloca])
474
7d596384 475m4_pushdef([AT_USE_ALLOCA], [[
0d50976f 476#if (defined __GNUC__ || defined __BUILTIN_VA_ARG_INCR \
62c4328e 477 || defined _AIX || defined _MSC_VER || defined _ALLOCA_H)
577d7c33
PE
478# define YYSTACK_USE_ALLOCA 1
479#endif
480]])
6d7d248e 481
7d596384
JD
482AT_DATA_STACK_TORTURE([AT_USE_ALLOCA])
483
6d7d248e 484# Below the limit of 200.
e0ac9b4b
JD
485AT_PARSER_CHECK([./input 20], 0, [], [ignore],
486 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e 487# Two enlargements: 2 * 2 * 200.
e0ac9b4b
JD
488AT_PARSER_CHECK([./input 900], 0, [], [ignore],
489 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e
AD
490# Fails: beyond the limit of 10,000 (which we don't reach anyway since we
491# multiply by two starting at 200 => 5120 is the last possible).
e0ac9b4b
JD
492AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
493 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e 494
78143faa
JD
495# The push parser can't use alloca since the stacks can't be locals. This test
496# just helps guarantee we don't let the YYSTACK_USE_ALLOCA feature affect
497# push parsers.
7d596384 498AT_DATA_STACK_TORTURE([AT_USE_ALLOCA],
c373bf8b 499[[%define api.push_pull "both"
7d596384 500]])
e0ac9b4b
JD
501AT_PARSER_CHECK([./input 20], 0, [], [ignore],
502 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
503AT_PARSER_CHECK([./input 900], 0, [], [ignore],
504 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
505AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
506 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
7d596384
JD
507
508m4_popdef([AT_USE_ALLOCA])
509
6d7d248e
AD
510AT_CLEANUP
511
512
513
514
515## -------------------------------------- ##
516## Exploding the Stack Size with Malloc. ##
517## -------------------------------------- ##
518
519AT_SETUP([Exploding the Stack Size with Malloc])
520
7d596384
JD
521m4_pushdef([AT_USE_ALLOCA], [[#define YYSTACK_USE_ALLOCA 0]])
522
523AT_DATA_STACK_TORTURE([AT_USE_ALLOCA])
6d7d248e
AD
524
525# Below the limit of 200.
e0ac9b4b
JD
526AT_PARSER_CHECK([./input 20], 0, [], [ignore],
527 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e 528# Two enlargements: 2 * 2 * 200.
e0ac9b4b
JD
529AT_PARSER_CHECK([./input 900], 0, [], [ignore],
530 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e
AD
531# Fails: beyond the limit of 10,000 (which we don't reach anyway since we
532# multiply by two starting at 200 => 5120 is the possible).
e0ac9b4b
JD
533AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
534 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
6d7d248e 535
7d596384 536AT_DATA_STACK_TORTURE([AT_USE_ALLOCA],
c373bf8b 537[[%define api.push_pull "both"
7d596384 538]])
e0ac9b4b
JD
539AT_PARSER_CHECK([./input 20], 0, [], [ignore],
540 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
541AT_PARSER_CHECK([./input 900], 0, [], [ignore],
542 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
543AT_PARSER_CHECK([./input 10000], 2, [], [ignore],
544 [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]])
7d596384
JD
545
546m4_popdef([AT_USE_ALLOCA])
547
6d7d248e 548AT_CLEANUP