]> git.saurik.com Git - bison.git/blame - tests/regression.at
* data/c.m4 (b4_yy_symbol_print_generate):
[bison.git] / tests / regression.at
CommitLineData
342b8b6e 1# Bison Regressions. -*- Autotest -*-
d42cf844
PE
2
3# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software
4# Foundation, Inc.
c95f2d78 5
342b8b6e
AD
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2, or (at your option)
9# any later version.
c95f2d78 10
342b8b6e
AD
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
c95f2d78 15
342b8b6e
AD
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
0fb669f9
PE
18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19# 02110-1301, USA.
c95f2d78 20
342b8b6e 21AT_BANNER([[Regression tests.]])
c95f2d78 22
2b25d624 23
276f48df
PE
24## ------------------ ##
25## Trivial grammars. ##
26## ------------------ ##
27
28AT_SETUP([Trivial grammars])
29
30AT_DATA_GRAMMAR([input.y],
31[[%{
32void yyerror (char const *);
33int yylex (void);
50cce58e 34#define YYSTYPE int *
276f48df
PE
35%}
36
37%error-verbose
38
39%%
40
41program: 'x';
42]])
43
44AT_CHECK([bison -o input.c input.y])
45AT_COMPILE([input.o], [-c input.c])
50cce58e 46AT_COMPILE([input.o], [-DYYDEBUG -c input.c])
276f48df
PE
47
48AT_CLEANUP
49
50
51
69078d4b
AD
52## ------------------------- ##
53## Early token definitions. ##
54## ------------------------- ##
55
56
57AT_SETUP([Early token definitions])
58
59# Found in GCJ: they expect the tokens to be defined before the user
60# prologue, so that they can use the token definitions in it.
61
9501dc6e 62AT_DATA_GRAMMAR([input.y],
69078d4b
AD
63[[%{
64void yyerror (const char *s);
65int yylex (void);
66%}
67
68%union
69{
70 int val;
71};
72%{
73#ifndef MY_TOKEN
74# error "MY_TOKEN not defined."
75#endif
76%}
77%token MY_TOKEN
78%%
79exp: MY_TOKEN;
80%%
81]])
82
b56471a6 83AT_CHECK([bison -o input.c input.y])
002b9b7d 84AT_COMPILE([input.o], [-c input.c])
69078d4b
AD
85
86AT_CLEANUP
87
88
89
2b25d624
AD
90## ---------------- ##
91## Braces parsing. ##
92## ---------------- ##
93
94
69078d4b 95AT_SETUP([Braces parsing])
2b25d624
AD
96
97AT_DATA([input.y],
98[[/* Bison used to swallow the character after `}'. */
99
100%%
bfcf1f3a 101exp: { tests = {{{{{{{{{{}}}}}}}}}}; };
2b25d624
AD
102%%
103]])
104
b56471a6 105AT_CHECK([bison -v -o input.c input.y])
2b25d624 106
a4bf0390 107AT_CHECK([grep 'tests = {{{{{{{{{{}}}}}}}}}};' input.c], 0, [ignore])
2b25d624
AD
108
109AT_CLEANUP
110
111
c95f2d78
AD
112## ------------------ ##
113## Duplicate string. ##
114## ------------------ ##
115
116
117AT_SETUP([Duplicate string])
118
f499b062 119AT_DATA([input.y],
c95f2d78
AD
120[[/* `Bison -v' used to dump core when two tokens are defined with the same
121 string, as LE and GE below. */
122
123%token NUM
124%token LE "<="
125%token GE "<="
126
127%%
128exp: '(' exp ')' | NUM ;
129%%
130]])
131
b56471a6 132AT_CHECK([bison -v -o input.c input.y], 0, [],
a5d50994 133[[input.y:6.8-14: warning: symbol `"<="' used more than once as a literal string
69078d4b 134]])
c95f2d78 135
d803322e 136AT_CLEANUP
c95f2d78
AD
137
138
2ca209c1
AD
139## ------------------- ##
140## Rule Line Numbers. ##
141## ------------------- ##
142
143AT_SETUP([Rule Line Numbers])
144
6b98e4b5
AD
145AT_KEYWORDS([report])
146
2ca209c1
AD
147AT_DATA([input.y],
148[[%%
149expr:
150'a'
151
152{
153
154}
155
156'b'
157
158{
159
160}
161
162|
163
164
165{
166
167
168}
169
170'c'
171
172{
173
bfcf1f3a 174};
2ca209c1
AD
175]])
176
b56471a6 177AT_CHECK([bison -o input.c -v input.y])
2ca209c1
AD
178
179# Check the contents of the report.
180AT_CHECK([cat input.output], [],
d2d1b42b 181[[Grammar
2ca209c1 182
88bce5a2 183 0 $accept: expr $end
6b98e4b5
AD
184
185 1 @1: /* empty */
186
187 2 expr: 'a' @1 'b'
188
189 3 @2: /* empty */
190
191 4 expr: @2 'c'
2ca209c1 192
d2d1b42b 193
2ca209c1
AD
194Terminals, with rules where they appear
195
88bce5a2 196$end (0) 0
2ca209c1
AD
197'a' (97) 2
198'b' (98) 2
199'c' (99) 4
200error (256)
201
d2d1b42b 202
2ca209c1
AD
203Nonterminals, with rules where they appear
204
88bce5a2 205$accept (6)
b365aa05
AD
206 on left: 0
207expr (7)
208 on left: 2 4, on right: 0
209@1 (8)
2ca209c1 210 on left: 1, on right: 2
b365aa05 211@2 (9)
2ca209c1
AD
212 on left: 3, on right: 4
213
214
215state 0
216
88bce5a2 217 0 $accept: . expr $end
643a5994 218
87675353 219 'a' shift, and go to state 1
2ca209c1 220
87675353 221 $default reduce using rule 3 (@2)
2ca209c1 222
87675353
AD
223 expr go to state 2
224 @2 go to state 3
2ca209c1
AD
225
226
227state 1
228
ce4ccb4b 229 2 expr: 'a' . @1 'b'
2ca209c1 230
87675353 231 $default reduce using rule 1 (@1)
2ca209c1 232
87675353 233 @1 go to state 4
2ca209c1
AD
234
235
236state 2
237
88bce5a2 238 0 $accept: expr . $end
2ca209c1 239
88bce5a2 240 $end shift, and go to state 5
2ca209c1
AD
241
242
243state 3
244
ce4ccb4b 245 4 expr: @2 . 'c'
2ca209c1 246
87675353 247 'c' shift, and go to state 6
2ca209c1
AD
248
249
250state 4
251
ce4ccb4b 252 2 expr: 'a' @1 . 'b'
2ca209c1 253
87675353 254 'b' shift, and go to state 7
2ca209c1
AD
255
256
257state 5
258
88bce5a2 259 0 $accept: expr $end .
2ca209c1 260
e8832397 261 $default accept
2ca209c1
AD
262
263
264state 6
265
ce4ccb4b 266 4 expr: @2 'c' .
b365aa05 267
87675353 268 $default reduce using rule 4 (expr)
2ca209c1
AD
269
270
271state 7
272
ce4ccb4b 273 2 expr: 'a' @1 'b' .
b365aa05 274
87675353 275 $default reduce using rule 2 (expr)
2ca209c1
AD
276]])
277
278AT_CLEANUP
279
280
281
cd5aafcf
AD
282## ---------------------- ##
283## Mixing %token styles. ##
284## ---------------------- ##
285
286
287AT_SETUP([Mixing %token styles])
288
289# Taken from the documentation.
290AT_DATA([input.y],
291[[%token <operator> OR "||"
292%token <operator> LE 134 "<="
293%left OR "<="
294%%
295exp: ;
296%%
297]])
298
b56471a6 299AT_CHECK([bison -v -o input.c input.y])
cd5aafcf 300
d803322e 301AT_CLEANUP
cd5aafcf
AD
302
303
304
29ae55f1
AD
305## ---------------- ##
306## Invalid inputs. ##
307## ---------------- ##
561f9a30
AD
308
309
29ae55f1 310AT_SETUP([Invalid inputs])
561f9a30
AD
311
312AT_DATA([input.y],
313[[%%
314?
561f9a30 315default: 'a' }
29ae55f1 316%&
2dfbfc12 317%a-does-not-exist
29ae55f1 318%-
e9955c83 319%{
561f9a30
AD
320]])
321
322AT_CHECK([bison input.y], [1], [],
e9955c83
AD
323[[input.y:2.1: invalid character: `?'
324input.y:3.14: invalid character: `}'
325input.y:4.1: invalid character: `%'
326input.y:4.2: invalid character: `&'
2dfbfc12 327input.y:5.1-17: invalid directive: `%a-does-not-exist'
e9955c83
AD
328input.y:6.1: invalid character: `%'
329input.y:6.2: invalid character: `-'
2115939b 330input.y:7.1-8.0: missing `%}' at end of file
e0c40012 331]])
561f9a30
AD
332
333AT_CLEANUP
334
335
fc01665e
PE
336AT_SETUP([Invalid inputs with {}])
337
338AT_DATA([input.y],
339[[
340%destructor
341%initial-action
342%lex-param
343%parse-param
344%printer
345%union
346]])
347
348AT_CHECK([bison input.y], [1], [],
349[[input.y:3.1: missing `{' in "%destructor {...}"
350input.y:4.1: missing `{' in "%initial-action {...}"
351input.y:4.1: syntax error, unexpected %initial-action {...}, expecting string or identifier
352]])
353
354AT_CLEANUP
355
356
270a173c 357
b87f8b21
AD
358## ------------------- ##
359## Token definitions. ##
360## ------------------- ##
361
362
363AT_SETUP([Token definitions])
364
365# Bison managed, when fed with `%token 'f' "f"' to #define 'f'!
9501dc6e 366AT_DATA_GRAMMAR([input.y],
db7c8e9a 367[%{
ca407bdf 368#include <stdio.h>
db7c8e9a
AD
369void yyerror (const char *s);
370int yylex (void);
371%}
ca407bdf
PE
372[%error-verbose
373%token MYEOF 0 "end of file"
b87f8b21 374%token 'a' "a"
4f136612
PE
375%token B_TOKEN "b"
376%token C_TOKEN 'c'
377%token 'd' D_TOKEN
3d54b576 378%token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"
b87f8b21 379%%
3d54b576 380exp: "a" "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!";
ca407bdf
PE
381%%
382void
383yyerror (char const *s)
384{
385 fprintf (stderr, "%s\n", s);
386}
387
388int
389yylex (void)
390{
391 return SPECIAL;
392}
393
394int
395main (void)
396{
397 return yyparse ();
398}
b87f8b21
AD
399]])
400
b56471a6 401AT_CHECK([bison -o input.c input.y])
ca407bdf 402AT_COMPILE([input])
3d54b576
PE
403AT_DATA([experr],
404[[syntax error, unexpected "\\'?\"\a\b\f\n\r\t\v\001\201\001\201?\?!", expecting a
405]])
406AT_PARSER_CHECK([./input], 1, [], [experr])
b87f8b21
AD
407AT_CLEANUP
408
409
410
eb714592
AD
411## -------------------- ##
412## Characters Escapes. ##
413## -------------------- ##
414
415
416AT_SETUP([Characters Escapes])
417
9501dc6e 418AT_DATA_GRAMMAR([input.y],
eb714592
AD
419[%{
420void yyerror (const char *s);
421int yylex (void);
422%}
423[%%
424exp:
425 '\'' "\'"
426| '\"' "\""
427| '"' "'"
428;
429]])
9501dc6e 430# Pacify font-lock-mode: "
eb714592 431
b56471a6 432AT_CHECK([bison -o input.c input.y])
eb714592
AD
433AT_COMPILE([input.o], [-c input.c])
434AT_CLEANUP
435
436
437
b9752825
AD
438## -------------- ##
439## Web2c Report. ##
440## -------------- ##
776209d6
AD
441
442# The generation of the reduction was once wrong in Bison, and made it
443# miss some reductions. In the following test case, the reduction on
444# `undef_id_tok' in state 1 was missing. This is stripped down from
445# the actual web2c.y.
446
b9752825 447AT_SETUP([Web2c Report])
776209d6 448
6b98e4b5
AD
449AT_KEYWORDS([report])
450
776209d6
AD
451AT_DATA([input.y],
452[[%token undef_id_tok const_id_tok
453
454%start CONST_DEC_PART
455\f
456%%
457CONST_DEC_PART:
458 CONST_DEC_LIST
459 ;
460
461CONST_DEC_LIST:
462 CONST_DEC
463 | CONST_DEC_LIST CONST_DEC
464 ;
465
466CONST_DEC:
467 { } undef_id_tok '=' const_id_tok ';'
468 ;
469%%
776209d6
AD
470]])
471
472AT_CHECK([bison -v input.y])
87675353 473AT_CHECK([cat input.output], 0,
776209d6 474[[Grammar
87675353 475
88bce5a2 476 0 $accept: CONST_DEC_PART $end
87675353 477
6b98e4b5 478 1 CONST_DEC_PART: CONST_DEC_LIST
87675353 479
6b98e4b5
AD
480 2 CONST_DEC_LIST: CONST_DEC
481 3 | CONST_DEC_LIST CONST_DEC
87675353 482
6b98e4b5 483 4 @1: /* empty */
87675353 484
6b98e4b5 485 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';'
87675353
AD
486
487
776209d6 488Terminals, with rules where they appear
87675353 489
88bce5a2 490$end (0) 0
776209d6
AD
491';' (59) 5
492'=' (61) 5
493error (256)
007a50a4
AD
494undef_id_tok (258) 5
495const_id_tok (259) 5
87675353
AD
496
497
776209d6 498Nonterminals, with rules where they appear
87675353 499
88bce5a2 500$accept (7)
78d5bae9
AD
501 on left: 0
502CONST_DEC_PART (8)
503 on left: 1, on right: 0
504CONST_DEC_LIST (9)
776209d6 505 on left: 2 3, on right: 1 3
78d5bae9 506CONST_DEC (10)
776209d6 507 on left: 5, on right: 2 3
78d5bae9 508@1 (11)
776209d6 509 on left: 4, on right: 5
87675353
AD
510
511
776209d6 512state 0
87675353 513
88bce5a2 514 0 $accept: . CONST_DEC_PART $end
87675353
AD
515
516 $default reduce using rule 4 (@1)
517
518 CONST_DEC_PART go to state 1
519 CONST_DEC_LIST go to state 2
520 CONST_DEC go to state 3
521 @1 go to state 4
522
523
776209d6 524state 1
87675353 525
88bce5a2 526 0 $accept: CONST_DEC_PART . $end
87675353 527
88bce5a2 528 $end shift, and go to state 5
87675353
AD
529
530
78d5bae9 531state 2
87675353 532
ce4ccb4b
AD
533 1 CONST_DEC_PART: CONST_DEC_LIST .
534 3 CONST_DEC_LIST: CONST_DEC_LIST . CONST_DEC
87675353
AD
535
536 undef_id_tok reduce using rule 4 (@1)
537 $default reduce using rule 1 (CONST_DEC_PART)
538
539 CONST_DEC go to state 6
540 @1 go to state 4
541
542
78d5bae9 543state 3
87675353 544
ce4ccb4b 545 2 CONST_DEC_LIST: CONST_DEC .
87675353
AD
546
547 $default reduce using rule 2 (CONST_DEC_LIST)
548
549
776209d6 550state 4
87675353 551
ce4ccb4b 552 5 CONST_DEC: @1 . undef_id_tok '=' const_id_tok ';'
87675353
AD
553
554 undef_id_tok shift, and go to state 7
555
556
78d5bae9 557state 5
87675353 558
88bce5a2 559 0 $accept: CONST_DEC_PART $end .
87675353 560
e8832397 561 $default accept
87675353
AD
562
563
78d5bae9 564state 6
87675353 565
ce4ccb4b 566 3 CONST_DEC_LIST: CONST_DEC_LIST CONST_DEC .
87675353
AD
567
568 $default reduce using rule 3 (CONST_DEC_LIST)
569
570
78d5bae9 571state 7
87675353 572
ce4ccb4b 573 5 CONST_DEC: @1 undef_id_tok . '=' const_id_tok ';'
87675353
AD
574
575 '=' shift, and go to state 8
576
577
78d5bae9 578state 8
87675353 579
ce4ccb4b 580 5 CONST_DEC: @1 undef_id_tok '=' . const_id_tok ';'
87675353
AD
581
582 const_id_tok shift, and go to state 9
583
584
78d5bae9 585state 9
87675353 586
ce4ccb4b 587 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok . ';'
87675353
AD
588
589 ';' shift, and go to state 10
590
591
78d5bae9 592state 10
87675353 593
ce4ccb4b 594 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';' .
87675353
AD
595
596 $default reduce using rule 5 (CONST_DEC)
776209d6
AD
597]])
598
599AT_CLEANUP
b9752825
AD
600
601
602## --------------- ##
603## Web2c Actions. ##
604## --------------- ##
605
606# The generation of the mapping `state -> action' was once wrong in
607# extremely specific situations. web2c.y exhibits this situation.
608# Below is a stripped version of the grammar. It looks like one can
609# simplify it further, but just don't: it is tuned to exhibit a bug,
610# which disapears when applying sane grammar transformations.
611#
612# It used to be wrong on yydefact only:
613#
d42cf844 614# static const yytype_uint8 yydefact[] =
b9752825
AD
615# {
616# - 2, 0, 1, 0, 0, 2, 3, 2, 5, 4,
617# + 2, 0, 1, 0, 0, 0, 3, 2, 5, 4,
618# 0, 0
619# };
620#
621# but let's check all the tables.
622
623
624AT_SETUP([Web2c Actions])
625
6b98e4b5
AD
626AT_KEYWORDS([report])
627
b9752825
AD
628AT_DATA([input.y],
629[[%%
630statement: struct_stat;
631struct_stat: /* empty. */ | if else;
632if: "if" "const" "then" statement;
633else: "else" statement;
634%%
635]])
636
b56471a6 637AT_CHECK([bison -v -o input.c input.y])
b9752825
AD
638
639# Check only the tables. We don't use --no-parser, because it is
640# still to be implemented in the experimental branch of Bison.
ce4ccb4b
AD
641[sed -n 's/ *$//;/^static const.*\[\] =/,/^}/p' input.c >tables.c]
642
643AT_CHECK([[cat tables.c]], 0,
d42cf844 644[[static const yytype_uint8 yytranslate[] =
b9752825
AD
645{
646 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
647 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
648 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
649 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
650 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
651 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
652 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
653 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
654 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
655 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
656 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
657 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
658 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
659 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
660 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
661 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
662 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
663 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
664 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
665 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
666 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
667 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
668 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
669 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
670 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
007a50a4
AD
671 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
672 5, 6
b9752825 673};
d42cf844 674static const yytype_uint8 yyprhs[] =
b9752825 675{
e7b8bef1 676 0, 0, 3, 5, 6, 9, 14
b9752825 677};
d42cf844 678static const yytype_int8 yyrhs[] =
b9752825 679{
e7b8bef1
AD
680 8, 0, -1, 9, -1, -1, 10, 11, -1, 3,
681 4, 5, 8, -1, 6, 8, -1
b9752825 682};
d42cf844 683static const yytype_uint8 yyrline[] =
b9752825 684{
e7b8bef1 685 0, 2, 2, 3, 3, 4, 5
b9752825
AD
686};
687static const char *const yytname[] =
688{
9e0876fb
PE
689 "$end", "error", "$undefined", "\"if\"", "\"const\"", "\"then\"",
690 "\"else\"", "$accept", "statement", "struct_stat", "if", "else", 0
b9752825 691};
d42cf844 692static const yytype_uint16 yytoknum[] =
b9752825 693{
3650b4b8 694 0, 256, 257, 258, 259, 260, 261
b9752825 695};
d42cf844 696static const yytype_uint8 yyr1[] =
b9752825 697{
e7b8bef1 698 0, 7, 8, 9, 9, 10, 11
b9752825 699};
d42cf844 700static const yytype_uint8 yyr2[] =
b9752825 701{
e7b8bef1 702 0, 2, 1, 0, 2, 4, 2
b9752825 703};
d42cf844 704static const yytype_uint8 yydefact[] =
b9752825 705{
e8832397 706 3, 0, 0, 2, 0, 0, 1, 3, 4, 3,
e7b8bef1 707 6, 5
b9752825 708};
d42cf844 709static const yytype_int8 yydefgoto[] =
b9752825 710{
e7b8bef1 711 -1, 2, 3, 4, 8
b9752825 712};
d42cf844 713static const yytype_int8 yypact[] =
b9752825 714{
12b0043a
AD
715 -2, -1, 4, -8, 0, 2, -8, -2, -8, -2,
716 -8, -8
b9752825 717};
d42cf844 718static const yytype_int8 yypgoto[] =
b9752825 719{
12b0043a 720 -8, -7, -8, -8, -8
b9752825 721};
d42cf844 722static const yytype_uint8 yytable[] =
b9752825 723{
e7b8bef1 724 10, 1, 11, 5, 6, 0, 7, 9
b9752825 725};
d42cf844 726static const yytype_int8 yycheck[] =
b9752825 727{
e7b8bef1 728 7, 3, 9, 4, 0, -1, 6, 5
b9752825 729};
d42cf844 730static const yytype_uint8 yystos[] =
5504898e
AD
731{
732 0, 3, 8, 9, 10, 4, 0, 6, 11, 5,
733 8, 8
734};
b9752825
AD
735]])
736
737AT_CLEANUP
22e304a6
AD
738
739
740## ------------------------- ##
741## yycheck Bound Violation. ##
742## ------------------------- ##
743
744
745# _AT_DATA_DANCER_Y(BISON-OPTIONS)
746# --------------------------------
747# The following grammar, taken from Andrew Suffield's GPL'd implementation
748# of DGMTP, the Dancer Generic Message Transport Protocol, used to violate
749# yycheck's bounds where issuing a verbose error message. Keep this test
750# so that possible bound checking compilers could check all the skeletons.
751m4_define([_AT_DATA_DANCER_Y],
752[AT_DATA_GRAMMAR([dancer.y],
753[%{
848dc439
PE
754static int yylex (AT_LALR1_CC_IF([int *], [void]));
755AT_LALR1_CC_IF([],
22e304a6 756[#include <stdio.h>
848dc439 757static void yyerror (const char *);])
22e304a6
AD
758%}
759$1
760%token ARROW INVALID NUMBER STRING DATA
761%defines
762%verbose
763%error-verbose
764/* Grammar follows */
765%%
766line: header body
767 ;
768
769header: '<' from ARROW to '>' type ':'
770 | '<' ARROW to '>' type ':'
771 | ARROW to type ':'
772 | type ':'
773 | '<' '>'
774 ;
775
776from: DATA
777 | STRING
778 | INVALID
779 ;
780
781to: DATA
782 | STRING
783 | INVALID
784 ;
785
786type: DATA
787 | STRING
788 | INVALID
789 ;
790
791body: /* empty */
792 | body member
793 ;
794
795member: STRING
796 | DATA
797 | '+' NUMBER
798 | '-' NUMBER
799 | NUMBER
800 | INVALID
801 ;
802%%
803AT_LALR1_CC_IF(
68e11668 804[/* A C++ error reporting function. */
22e304a6 805void
99880de5 806yy::parser::error (const location&, const std::string& m)
22e304a6 807{
efeed023 808 std::cerr << m << std::endl;
22e304a6
AD
809}
810
811int
99880de5 812yyparse ()
22e304a6 813{
99880de5 814 yy::parser parser;
a3cb6248 815 parser.set_debug_level (!!YYDEBUG);
22e304a6
AD
816 return parser.parse ();
817}
818],
819[static void
820yyerror (const char *s)
821{
822 fprintf (stderr, "%s\n", s);
823}])
824
825static int
848dc439 826yylex (AT_LALR1_CC_IF([int *lval], [void]))
22e304a6
AD
827[{
828 static int toknum = 0;
d6645148 829 static int tokens[] =
22e304a6
AD
830 {
831 ':', -1
832 };
848dc439 833 ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[
22e304a6
AD
834 return tokens[toknum++];
835}]
836
837int
838main (void)
839{
840 return yyparse ();
841}
842])
843])# _AT_DATA_DANCER_Y
844
845
846# AT_CHECK_DANCER(BISON-OPTIONS)
847# ------------------------------
848# Generate the grammar, compile it, run it.
849m4_define([AT_CHECK_DANCER],
850[AT_SETUP([Dancer $1])
851AT_BISON_OPTION_PUSHDEFS([$1])
852_AT_DATA_DANCER_Y([$1])
853AT_CHECK([bison -o dancer.c dancer.y])
07971983
PE
854AT_LALR1_CC_IF(
855 [AT_CHECK([bison -o dancer.cc dancer.y])
856 AT_COMPILE_CXX([dancer])],
857 [AT_CHECK([bison -o dancer.c dancer.y])
858 AT_COMPILE([dancer])])
22e304a6 859AT_PARSER_CHECK([./dancer], 1, [],
d5286af1 860[syntax error, unexpected ':'
22e304a6
AD
861])
862AT_BISON_OPTION_POPDEFS
863AT_CLEANUP
864])
865
866AT_CHECK_DANCER()
867AT_CHECK_DANCER([%glr-parser])
868AT_CHECK_DANCER([%skeleton "lalr1.cc"])
d6645148
PE
869
870
871## ------------------------------------------ ##
872## Diagnostic that expects two alternatives. ##
873## ------------------------------------------ ##
874
875
876# _AT_DATA_EXPECT2_Y(BISON-OPTIONS)
877# --------------------------------
878m4_define([_AT_DATA_EXPECT2_Y],
879[AT_DATA_GRAMMAR([expect2.y],
880[%{
881static int yylex (AT_LALR1_CC_IF([int *], [void]));
882AT_LALR1_CC_IF([],
883[#include <stdio.h>
884static void yyerror (const char *);])
885%}
886$1
887%defines
888%error-verbose
889%token A 1000
890%token B
891
892%%
893program: /* empty */
894 | program e ';'
895 | program error ';';
896
897e: e '+' t | t;
898t: A | B;
899
900%%
901AT_LALR1_CC_IF(
902[/* A C++ error reporting function. */
903void
904yy::parser::error (const location&, const std::string& m)
905{
906 std::cerr << m << std::endl;
907}
908
909int
910yyparse ()
911{
912 yy::parser parser;
913 return parser.parse ();
914}
915],
916[static void
917yyerror (const char *s)
918{
919 fprintf (stderr, "%s\n", s);
920}])
921
922static int
923yylex (AT_LALR1_CC_IF([int *lval], [void]))
924[{
925 static int toknum = 0;
926 static int tokens[] =
927 {
928 1000, '+', '+', -1
929 };
930 ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[
931 return tokens[toknum++];
932}]
933
934int
935main (void)
936{
937 return yyparse ();
938}
939])
940])# _AT_DATA_EXPECT2_Y
941
942
943# AT_CHECK_EXPECT2(BISON-OPTIONS)
944# ------------------------------
945# Generate the grammar, compile it, run it.
946m4_define([AT_CHECK_EXPECT2],
947[AT_SETUP([Expecting two tokens $1])
948AT_BISON_OPTION_PUSHDEFS([$1])
949_AT_DATA_EXPECT2_Y([$1])
950AT_CHECK([bison -o expect2.c expect2.y])
951AT_LALR1_CC_IF(
952 [AT_CHECK([bison -o expect2.cc expect2.y])
953 AT_COMPILE_CXX([expect2])],
954 [AT_CHECK([bison -o expect2.c expect2.y])
955 AT_COMPILE([expect2])])
956AT_PARSER_CHECK([./expect2], 1, [],
957[syntax error, unexpected '+', expecting A or B
958])
959AT_BISON_OPTION_POPDEFS
960AT_CLEANUP
961])
962
963AT_CHECK_EXPECT2()
964AT_CHECK_EXPECT2([%glr-parser])
965AT_CHECK_EXPECT2([%skeleton "lalr1.cc"])