]> git.saurik.com Git - bison.git/blame - tests/torture.at
* NEWS: Bison-generated C parsers no longer quote literal strings
[bison.git] / tests / torture.at
CommitLineData
6d7d248e 1# Torturing Bison. -*- Autotest -*-
f79b4f5c 2# Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
6d7d248e
AD
3
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2, or (at your option)
7# any later version.
8
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17# 02111-1307, USA.
18
19AT_BANNER([[Torture Tests.]])
20
21
49e794c5 22# AT_INCREASE_DATA_SIZE(SIZE)
f79b4f5c 23# ---------------------------
49e794c5
PE
24# Try to increase the data size to SIZE KiB if possible.
25m4_define([AT_INCREASE_DATA_SIZE],
26[data_limit=`(ulimit -S -d) 2>/dev/null`
27case $data_limit in
28[[0-9]]*)
29 if test "$data_limit" -lt $1; then
f79b4f5c 30 AT_CHECK([ulimit -S -d $1 || exit 77])
49e794c5
PE
31 ulimit -S -d $1
32 fi
33esac])
34
35
817e9f41
AD
36## ------------------------------------- ##
37## Creating a large artificial grammar. ##
38## ------------------------------------- ##
39
40# AT_DATA_TRIANGULAR_GRAMMAR(FILE-NAME, SIZE)
41# -------------------------------------------
42# Create FILE-NAME, containing a self checking parser for a huge
43# triangular grammar.
817e9f41
AD
44m4_define([AT_DATA_TRIANGULAR_GRAMMAR],
45[AT_DATA([[gengram.pl]],
46[[#! /usr/bin/perl -w
47
48use strict;
49my $max = $ARGV[0] || 10;
50
51print <<EOF;
9501dc6e 52]AT_DATA_GRAMMAR_PROLOGUE[
817e9f41
AD
53%{
54#include <stdio.h>
55#include <stdlib.h>
817e9f41
AD
56
57#define YYERROR_VERBOSE 1
58#define YYDEBUG 1
59
60static int yylex (void);
61static void yyerror (const char *msg);
62%}
63%union
64{
65 int val;
66};
67
68%token END "end"
69%type <val> exp input
70EOF
71
72for my $size (1 .. $max)
73 {
e9955c83 74 print "%token t$size $size \"$size\"\n";
817e9f41
AD
75 };
76
77print <<EOF;
78%%
79input:
66871a81
PE
80 exp { if (\@S|@1 != 0) abort (); \$\$ = \@S|@1; }
81| input exp { if (\@S|@2 != \@S|@1 + 1) abort (); \$\$ = \@S|@2; }
817e9f41
AD
82;
83
84exp:
85 END
86 { \$\$ = 0; }
87EOF
88
89for my $size (1 .. $max)
90 {
91 use Text::Wrap;
92 print wrap ("| ", " ",
93 (map { "\"$_\"" } (1 .. $size)),
94 " END \n"),
95 " { \$\$ = $size; }\n";
96 };
97print ";\n";
98
99print <<EOF;
100%%
101static int
102yylex (void)
103{
104 static int inner = 1;
105 static int outer = 0;
106 if (outer > $max)
107 return 0;
108 else if (inner > outer)
109 {
110 inner = 1;
111 ++outer;
112 return END;
113 }
23c5a174 114 return inner++;
817e9f41
AD
115}
116
117static void
118yyerror (const char *msg)
119{
120 fprintf (stderr, "%s\\n", msg);
121}
122
123int
124main (void)
125{
126 yydebug = !!getenv ("YYDEBUG");
127 return yyparse ();
128}
129EOF
130]])
131
132AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
133mv stdout $1
134])
135
136
137## -------------- ##
138## Big triangle. ##
139## -------------- ##
140
817e9f41
AD
141AT_SETUP([Big triangle])
142
355e7c1c
AD
143# I have been able to go up to 2000 on my machine.
144# I tried 3000, a 29Mb grammar file, but then my system killed bison.
e9955c83
AD
145# With 500 and the new parser, which consume far too much memory,
146# it gets killed too. Of course the parser is to be cleaned.
147AT_DATA_TRIANGULAR_GRAMMAR([input.y], [200])
b56471a6 148AT_CHECK([bison -v -o input.c input.y])
1154cced
AD
149AT_COMPILE([input])
150AT_PARSER_CHECK([./input])
817e9f41
AD
151
152AT_CLEANUP
153
154
155
62a3e4f0
AD
156# AT_DATA_HORIZONTAL_GRAMMAR(FILE-NAME, SIZE)
157# -------------------------------------------
158# Create FILE-NAME, containing a self checking parser for a huge
159# horizontal grammar.
62a3e4f0
AD
160m4_define([AT_DATA_HORIZONTAL_GRAMMAR],
161[AT_DATA([[gengram.pl]],
162[[#! /usr/bin/perl -w
163
164use strict;
165my $max = $ARGV[0] || 10;
166
167print <<EOF;
9501dc6e 168]AT_DATA_GRAMMAR_PROLOGUE[
62a3e4f0
AD
169%{
170#include <stdio.h>
171#include <stdlib.h>
62a3e4f0
AD
172
173#define YYERROR_VERBOSE 1
174#define YYDEBUG 1
175
176static int yylex (void);
177static void yyerror (const char *msg);
178%}
179EOF
180
181for my $size (1 .. $max)
182 {
e9955c83 183 print "%token t$size $size \"$size\"\n";
62a3e4f0
AD
184 };
185
186print <<EOF;
187%%
188EOF
189
190use Text::Wrap;
191print
192 wrap ("exp: ", " ",
193 (map { "\"$_\"" } (1 .. $max)), ";"),
194 "\n";
195
196print <<EOF;
197%%
198static int
199yylex (void)
200{
201 static int counter = 1;
202 if (counter > $max)
203 return 0;
204 else
23c5a174 205 return counter++;
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
b56471a6 252AT_CHECK([bison -v -o input.c input.y])
1154cced
AD
253AT_COMPILE([input])
254AT_PARSER_CHECK([./input])
62a3e4f0
AD
255
256AT_CLEANUP
257
258
259
8dd162d3 260# AT_DATA_LOOK_AHEAD_TOKENS_GRAMMAR(FILE-NAME, SIZE)
39ceb25b
AD
261# -------------------------------------------
262# Create FILE-NAME, containing a self checking parser for a grammar
8dd162d3
PE
263# requiring SIZE look-ahead tokens.
264m4_define([AT_DATA_LOOK_AHEAD_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;
273%{
274#include <stdio.h>
275#include <stdlib.h>
39ceb25b
AD
276
277#define YYERROR_VERBOSE 1
278#define YYDEBUG 1
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
298for my $count (1 .. $max)
299 {
e9955c83 300 print "%token t$count $count \"$count\"\n";
39ceb25b
AD
301 };
302
303print <<EOF;
304%%
305input:
66871a81
PE
306 exp { if (\@S|@1 != 1) abort (); \$\$ = \@S|@1; }
307| input exp { if (\@S|@2 != \@S|@1 + 1) abort (); \$\$ = \@S|@2; }
39ceb25b
AD
308;
309
310exp:
66871a81 311 n1 "1" { if (\@S|@1 != 1) abort (); }
39ceb25b
AD
312EOF
313
314for my $count (2 .. $max)
315 {
66871a81 316 print "| n$count \"$count\" { if (\@S|@1 != $count) abort (); }\n";
39ceb25b
AD
317 };
318print ";\n";
319
320for my $count (1 .. $max)
321 {
e9955c83 322 print "n$count: token { \$\$ = $count; };\n";
39ceb25b
AD
323 };
324
325print <<EOF;
326%%
327static int
328yylex (void)
329{
330 static int return_token = 1;
331 static int counter = 1;
332 if (counter > $max)
333 return 0;
334 if (return_token)
335 {
336 return_token = 0;
337 return token;
338 }
339 return_token = 1;
340 return counter++;
341}
342
343static void
344yyerror (const char *msg)
345{
346 fprintf (stderr, "%s\\n", msg);
347}
348
349int
350main (void)
351{
352 yydebug = !!getenv ("YYDEBUG");
353 return yyparse ();
354}
355EOF
356]])
357
358AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
359mv stdout $1
360])
361
362
8dd162d3
PE
363## ------------------------ ##
364## Many look-ahead tokens. ##
365## ------------------------ ##
39ceb25b 366
8dd162d3 367AT_SETUP([Many look-ahead tokens])
39ceb25b 368
8dd162d3 369AT_DATA_LOOK_AHEAD_TOKENS_GRAMMAR([input.y], [1000])
49e794c5
PE
370
371# GNU m4 requires about 70 MiB for this test on a 32-bit host.
372# Ask for 200 MiB, which should be plenty even on a 64-bit host.
373AT_INCREASE_DATA_SIZE(204000)
374
b56471a6 375AT_CHECK([bison -v -o input.c input.y])
1154cced
AD
376AT_COMPILE([input])
377AT_PARSER_CHECK([./input])
39ceb25b
AD
378
379AT_CLEANUP
380
381
382
6d7d248e
AD
383# AT_DATA_STACK_TORTURE(C-PROLOGUE)
384# ---------------------------------
385# A parser specialized in torturing the stack size.
386m4_define([AT_DATA_STACK_TORTURE],
387[# A grammar of parens growing the stack thanks to right recursion.
388# exp:
389AT_DATA([input.y],
390[[%{
391#include <stdio.h>
392#include <stdlib.h>
6d7d248e
AD
393]$1[
394 static int yylex (void);
395 static void yyerror (const char *msg);
6d7d248e 396%}
04d843a2 397%error-verbose
6d7d248e
AD
398%debug
399%token WAIT_FOR_EOF
400%%
401exp: WAIT_FOR_EOF exp | ;
402%%
403static void
404yyerror (const char *msg)
405{
406 fprintf (stderr, "%s\n", msg);
407 exit (1);
408}
409
410/* There are YYLVAL_MAX of WAIT_FOR_EOFs. */
411unsigned int yylval_max;
412
413static int
414yylex (void)
415{
416 if (yylval--)
417 return WAIT_FOR_EOF;
418 else
419 return EOF;
420}
421
422int
423main (int argc, const char **argv)
424{
66871a81
PE
425 if (argc != 2)
426 abort ();
6d7d248e
AD
427 yylval = atoi (argv[1]);
428 yydebug = 1;
429 return yyparse ();
430}
431]])
b56471a6 432AT_CHECK([bison -o input.c input.y])
1154cced 433AT_COMPILE([input])
6d7d248e
AD
434])
435
436
437## -------------------------------------- ##
438## Exploding the Stack Size with Alloca. ##
439## -------------------------------------- ##
440
441AT_SETUP([Exploding the Stack Size with Alloca])
442
577d7c33
PE
443AT_DATA_STACK_TORTURE([[
444#if defined __GNUC__ || defined alloca
445# define YYSTACK_USE_ALLOCA 1
446#endif
447]])
6d7d248e
AD
448
449# Below the limit of 200.
1154cced 450AT_PARSER_CHECK([./input 20], 0, [], [ignore])
6d7d248e 451# Two enlargements: 2 * 2 * 200.
1154cced 452AT_PARSER_CHECK([./input 900], 0, [], [ignore])
6d7d248e
AD
453# Fails: beyond the limit of 10,000 (which we don't reach anyway since we
454# multiply by two starting at 200 => 5120 is the last possible).
1154cced 455AT_PARSER_CHECK([./input 10000], 1, [], [ignore])
6d7d248e
AD
456
457AT_CLEANUP
458
459
460
461
462## -------------------------------------- ##
463## Exploding the Stack Size with Malloc. ##
464## -------------------------------------- ##
465
466AT_SETUP([Exploding the Stack Size with Malloc])
467
000f1a3c 468AT_DATA_STACK_TORTURE([[#define YYSTACK_USE_ALLOCA 0]])
6d7d248e
AD
469
470# Below the limit of 200.
1154cced 471AT_PARSER_CHECK([./input 20], 0, [], [ignore])
6d7d248e 472# Two enlargements: 2 * 2 * 200.
1154cced 473AT_PARSER_CHECK([./input 900], 0, [], [ignore])
6d7d248e
AD
474# Fails: beyond the limit of 10,000 (which we don't reach anyway since we
475# multiply by two starting at 200 => 5120 is the possible).
1154cced 476AT_PARSER_CHECK([./input 10000], 1, [], [ignore])
6d7d248e
AD
477
478AT_CLEANUP