]> git.saurik.com Git - bison.git/blame - tests/torture.at
Use new @ escapes consistently.
[bison.git] / tests / torture.at
CommitLineData
6d7d248e 1# Torturing Bison. -*- Autotest -*-
817e9f41 2# Copyright (C) 2001, 2002 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
PE
22# AT_INCREASE_DATA_SIZE(SIZE)
23# -------------------------------------------
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
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;
51%{
52#include <stdio.h>
53#include <stdlib.h>
817e9f41
AD
54
55#define YYERROR_VERBOSE 1
56#define YYDEBUG 1
57
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])
b56471a6 146AT_CHECK([bison -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;
166%{
167#include <stdio.h>
168#include <stdlib.h>
62a3e4f0
AD
169
170#define YYERROR_VERBOSE 1
171#define YYDEBUG 1
172
173static int yylex (void);
174static void yyerror (const char *msg);
175%}
176EOF
177
178for my $size (1 .. $max)
179 {
e9955c83 180 print "%token t$size $size \"$size\"\n";
62a3e4f0
AD
181 };
182
183print <<EOF;
184%%
185EOF
186
187use Text::Wrap;
188print
189 wrap ("exp: ", " ",
190 (map { "\"$_\"" } (1 .. $max)), ";"),
191 "\n";
192
193print <<EOF;
194%%
195static int
196yylex (void)
197{
198 static int counter = 1;
199 if (counter > $max)
200 return 0;
201 else
23c5a174 202 return counter++;
62a3e4f0
AD
203}
204
205static void
206yyerror (const char *msg)
207{
208 fprintf (stderr, "%s\\n", msg);
209}
210
211int
212main (void)
213{
214 yydebug = !!getenv ("YYDEBUG");
215 return yyparse ();
216}
217EOF
218]])
219
220AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
221mv stdout $1
222])
223
224
225## ---------------- ##
226## Big horizontal. ##
227## ---------------- ##
228
229AT_SETUP([Big horizontal])
230
231# I have been able to go up to 10000 on my machine, but I had to
232# increase the maximum stack size (* 100). It gave:
233#
234# input.y 263k
235# input.tab.c 1.3M
236# input 453k
237#
238# gengram.pl 10000 0.70s user 0.01s sys 99% cpu 0.711 total
239# bison input.y 730.56s user 0.53s sys 99% cpu 12:12.34 total
240# gcc -Wall input.tab.c -o input 5.81s user 0.20s sys 100% cpu 6.01 total
241# ./input 0.00s user 0.01s sys 108% cpu 0.01 total
242#
243AT_DATA_HORIZONTAL_GRAMMAR([input.y], [1000])
49e794c5
PE
244
245# GNU m4 requires about 70 MiB for this test on a 32-bit host.
246# Ask for 200 MiB, which should be plenty even on a 64-bit host.
247AT_INCREASE_DATA_SIZE(204000)
248
b56471a6 249AT_CHECK([bison -v -o input.c input.y])
1154cced
AD
250AT_COMPILE([input])
251AT_PARSER_CHECK([./input])
62a3e4f0
AD
252
253AT_CLEANUP
254
255
256
39ceb25b
AD
257# AT_DATA_LOOKAHEADS_GRAMMAR(FILE-NAME, SIZE)
258# -------------------------------------------
259# Create FILE-NAME, containing a self checking parser for a grammar
260# requiring SIZE lookaheads.
261m4_define([AT_DATA_LOOKAHEADS_GRAMMAR],
262[AT_DATA([[gengram.pl]],
263[[#! /usr/bin/perl -w
264
265use strict;
266use Text::Wrap;
267my $max = $ARGV[0] || 10;
268
269print <<EOF;
270%{
271#include <stdio.h>
272#include <stdlib.h>
39ceb25b
AD
273
274#define YYERROR_VERBOSE 1
275#define YYDEBUG 1
276
277static int yylex (void);
278static void yyerror (const char *msg);
279%}
280%union
281{
282 int val;
283};
284
285%type <val> input exp
286%token token
287EOF
288
289print
290 wrap ("%type <val> ",
291 " ",
e9955c83 292 map { "n$_" } (1 .. $max)),
39ceb25b
AD
293 "\n";
294
295for my $count (1 .. $max)
296 {
e9955c83 297 print "%token t$count $count \"$count\"\n";
39ceb25b
AD
298 };
299
300print <<EOF;
301%%
302input:
66871a81
PE
303 exp { if (\@S|@1 != 1) abort (); \$\$ = \@S|@1; }
304| input exp { if (\@S|@2 != \@S|@1 + 1) abort (); \$\$ = \@S|@2; }
39ceb25b
AD
305;
306
307exp:
66871a81 308 n1 "1" { if (\@S|@1 != 1) abort (); }
39ceb25b
AD
309EOF
310
311for my $count (2 .. $max)
312 {
66871a81 313 print "| n$count \"$count\" { if (\@S|@1 != $count) abort (); }\n";
39ceb25b
AD
314 };
315print ";\n";
316
317for my $count (1 .. $max)
318 {
e9955c83 319 print "n$count: token { \$\$ = $count; };\n";
39ceb25b
AD
320 };
321
322print <<EOF;
323%%
324static int
325yylex (void)
326{
327 static int return_token = 1;
328 static int counter = 1;
329 if (counter > $max)
330 return 0;
331 if (return_token)
332 {
333 return_token = 0;
334 return token;
335 }
336 return_token = 1;
337 return counter++;
338}
339
340static void
341yyerror (const char *msg)
342{
343 fprintf (stderr, "%s\\n", msg);
344}
345
346int
347main (void)
348{
349 yydebug = !!getenv ("YYDEBUG");
350 return yyparse ();
351}
352EOF
353]])
354
355AT_CHECK([perl -w ./gengram.pl $2 || exit 77], 0, [stdout])
356mv stdout $1
357])
358
359
360## ----------------- ##
361## Many lookaheads. ##
362## ----------------- ##
363
364AT_SETUP([Many lookaheads])
365
366AT_DATA_LOOKAHEADS_GRAMMAR([input.y], [1000])
49e794c5
PE
367
368# GNU m4 requires about 70 MiB for this test on a 32-bit host.
369# Ask for 200 MiB, which should be plenty even on a 64-bit host.
370AT_INCREASE_DATA_SIZE(204000)
371
b56471a6 372AT_CHECK([bison -v -o input.c input.y])
1154cced
AD
373AT_COMPILE([input])
374AT_PARSER_CHECK([./input])
39ceb25b
AD
375
376AT_CLEANUP
377
378
379
6d7d248e
AD
380# AT_DATA_STACK_TORTURE(C-PROLOGUE)
381# ---------------------------------
382# A parser specialized in torturing the stack size.
383m4_define([AT_DATA_STACK_TORTURE],
384[# A grammar of parens growing the stack thanks to right recursion.
385# exp:
386AT_DATA([input.y],
387[[%{
388#include <stdio.h>
389#include <stdlib.h>
6d7d248e
AD
390]$1[
391 static int yylex (void);
392 static void yyerror (const char *msg);
6d7d248e 393%}
04d843a2 394%error-verbose
6d7d248e
AD
395%debug
396%token WAIT_FOR_EOF
397%%
398exp: WAIT_FOR_EOF exp | ;
399%%
400static void
401yyerror (const char *msg)
402{
403 fprintf (stderr, "%s\n", msg);
404 exit (1);
405}
406
407/* There are YYLVAL_MAX of WAIT_FOR_EOFs. */
408unsigned int yylval_max;
409
410static int
411yylex (void)
412{
413 if (yylval--)
414 return WAIT_FOR_EOF;
415 else
416 return EOF;
417}
418
419int
420main (int argc, const char **argv)
421{
66871a81
PE
422 if (argc != 2)
423 abort ();
6d7d248e
AD
424 yylval = atoi (argv[1]);
425 yydebug = 1;
426 return yyparse ();
427}
428]])
b56471a6 429AT_CHECK([bison -o input.c input.y])
1154cced 430AT_COMPILE([input])
6d7d248e
AD
431])
432
433
434## -------------------------------------- ##
435## Exploding the Stack Size with Alloca. ##
436## -------------------------------------- ##
437
438AT_SETUP([Exploding the Stack Size with Alloca])
439
440AT_DATA_STACK_TORTURE
441
442# Below the limit of 200.
1154cced 443AT_PARSER_CHECK([./input 20], 0, [], [ignore])
6d7d248e 444# Two enlargements: 2 * 2 * 200.
1154cced 445AT_PARSER_CHECK([./input 900], 0, [], [ignore])
6d7d248e
AD
446# Fails: beyond the limit of 10,000 (which we don't reach anyway since we
447# multiply by two starting at 200 => 5120 is the last possible).
1154cced 448AT_PARSER_CHECK([./input 10000], 1, [], [ignore])
6d7d248e
AD
449
450AT_CLEANUP
451
452
453
454
455## -------------------------------------- ##
456## Exploding the Stack Size with Malloc. ##
457## -------------------------------------- ##
458
459AT_SETUP([Exploding the Stack Size with Malloc])
460
000f1a3c 461AT_DATA_STACK_TORTURE([[#define YYSTACK_USE_ALLOCA 0]])
6d7d248e
AD
462
463# Below the limit of 200.
1154cced 464AT_PARSER_CHECK([./input 20], 0, [], [ignore])
6d7d248e 465# Two enlargements: 2 * 2 * 200.
1154cced 466AT_PARSER_CHECK([./input 900], 0, [], [ignore])
6d7d248e
AD
467# Fails: beyond the limit of 10,000 (which we don't reach anyway since we
468# multiply by two starting at 200 => 5120 is the possible).
1154cced 469AT_PARSER_CHECK([./input 10000], 1, [], [ignore])
6d7d248e
AD
470
471AT_CLEANUP