1# Bison Regressions. -*- Autotest -*- 2 3# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software 4# Foundation, Inc. 5 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. 10 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. 15 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 18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19# 02110-1301, USA. 20 21AT_BANNER([[Regression tests.]]) 22 23 24## ------------------ ## 25## Trivial grammars. ## 26## ------------------ ## 27 28AT_SETUP([Trivial grammars]) 29 30AT_DATA_GRAMMAR([input.y], 31[[%{ 32void yyerror (char const *); 33int yylex (void); 34#define YYSTYPE int * 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]) 46AT_COMPILE([input.o], [-DYYDEBUG -c input.c]) 47 48AT_CLEANUP 49 50 51 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 62AT_DATA_GRAMMAR([input.y], 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 83AT_CHECK([bison -o input.c input.y]) 84AT_COMPILE([input.o], [-c input.c]) 85 86AT_CLEANUP 87 88 89 90## ---------------- ## 91## Braces parsing. ## 92## ---------------- ## 93 94 95AT_SETUP([Braces parsing]) 96 97AT_DATA([input.y], 98[[/* Bison used to swallow the character after `}'. */ 99 100%% 101exp: { tests = {{{{{{{{{{}}}}}}}}}}; }; 102%% 103]]) 104 105AT_CHECK([bison -v -o input.c input.y]) 106 107AT_CHECK([grep 'tests = {{{{{{{{{{}}}}}}}}}};' input.c], 0, [ignore]) 108 109AT_CLEANUP 110 111 112## ------------------ ## 113## Duplicate string. ## 114## ------------------ ## 115 116 117AT_SETUP([Duplicate string]) 118 119AT_DATA([input.y], 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 132AT_CHECK([bison -v -o input.c input.y], 0, [], 133[[input.y:6.8-14: warning: symbol `"<="' used more than once as a literal string 134]]) 135 136AT_CLEANUP 137 138 139## ------------------- ## 140## Rule Line Numbers. ## 141## ------------------- ## 142 143AT_SETUP([Rule Line Numbers]) 144 145AT_KEYWORDS([report]) 146 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 174}; 175]]) 176 177AT_CHECK([bison -o input.c -v input.y]) 178 179# Check the contents of the report. 180AT_CHECK([cat input.output], [], 181[[Grammar 182 183 0 $accept: expr $end 184 185 1 @1: /* empty */ 186 187 2 expr: 'a' @1 'b' 188 189 3 @2: /* empty */ 190 191 4 expr: @2 'c' 192 193 194Terminals, with rules where they appear 195 196$end (0) 0 197'a' (97) 2 198'b' (98) 2 199'c' (99) 4 200error (256) 201 202 203Nonterminals, with rules where they appear 204 205$accept (6) 206 on left: 0 207expr (7) 208 on left: 2 4, on right: 0 209@1 (8) 210 on left: 1, on right: 2 211@2 (9) 212 on left: 3, on right: 4 213 214 215state 0 216 217 0 $accept: . expr $end 218 219 'a' shift, and go to state 1 220 221 $default reduce using rule 3 (@2) 222 223 expr go to state 2 224 @2 go to state 3 225 226 227state 1 228 229 2 expr: 'a' . @1 'b' 230 231 $default reduce using rule 1 (@1) 232 233 @1 go to state 4 234 235 236state 2 237 238 0 $accept: expr . $end 239 240 $end shift, and go to state 5 241 242 243state 3 244 245 4 expr: @2 . 'c' 246 247 'c' shift, and go to state 6 248 249 250state 4 251 252 2 expr: 'a' @1 . 'b' 253 254 'b' shift, and go to state 7 255 256 257state 5 258 259 0 $accept: expr $end . 260 261 $default accept 262 263 264state 6 265 266 4 expr: @2 'c' . 267 268 $default reduce using rule 4 (expr) 269 270 271state 7 272 273 2 expr: 'a' @1 'b' . 274 275 $default reduce using rule 2 (expr) 276]]) 277 278AT_CLEANUP 279 280 281 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 299AT_CHECK([bison -v -o input.c input.y]) 300 301AT_CLEANUP 302 303 304 305## ---------------- ## 306## Invalid inputs. ## 307## ---------------- ## 308 309 310AT_SETUP([Invalid inputs]) 311 312AT_DATA([input.y], 313[[%% 314? 315default: 'a' } 316%& 317%a-does-not-exist 318%- 319%{ 320]]) 321 322AT_CHECK([bison input.y], [1], [], 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: `&' 327input.y:5.1-17: invalid directive: `%a-does-not-exist' 328input.y:6.1: invalid character: `%' 329input.y:6.2: invalid character: `-' 330input.y:7.1-8.0: missing `%}' at end of file 331]]) 332 333AT_CLEANUP 334 335 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 357 358## ------------------- ## 359## Token definitions. ## 360## ------------------- ## 361 362 363AT_SETUP([Token definitions]) 364 365# Bison managed, when fed with `%token 'f' "f"' to #define 'f'! 366AT_DATA_GRAMMAR([input.y], 367[%{ 368#include <stdio.h> 369void yyerror (const char *s); 370int yylex (void); 371%} 372[%error-verbose 373%token MYEOF 0 "end of file" 374%token 'a' "a" 375%token B_TOKEN "b" 376%token C_TOKEN 'c' 377%token 'd' D_TOKEN 378%token SPECIAL "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!" 379%% 380exp: "a" "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"; 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} 399]]) 400 401AT_CHECK([bison -o input.c input.y]) 402AT_COMPILE([input]) 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]) 407AT_CLEANUP 408 409 410 411## -------------------- ## 412## Characters Escapes. ## 413## -------------------- ## 414 415 416AT_SETUP([Characters Escapes]) 417 418AT_DATA_GRAMMAR([input.y], 419[%{ 420void yyerror (const char *s); 421int yylex (void); 422%} 423[%% 424exp: 425 '\'' "\'" 426| '\"' "\"" 427| '"' "'" 428; 429]]) 430# Pacify font-lock-mode: " 431 432AT_CHECK([bison -o input.c input.y]) 433AT_COMPILE([input.o], [-c input.c]) 434AT_CLEANUP 435 436 437 438## -------------- ## 439## Web2c Report. ## 440## -------------- ## 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 447AT_SETUP([Web2c Report]) 448 449AT_KEYWORDS([report]) 450 451AT_DATA([input.y], 452[[%token undef_id_tok const_id_tok 453 454%start CONST_DEC_PART 455 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%% 470]]) 471 472AT_CHECK([bison -v input.y]) 473AT_CHECK([cat input.output], 0, 474[[Grammar 475 476 0 $accept: CONST_DEC_PART $end 477 478 1 CONST_DEC_PART: CONST_DEC_LIST 479 480 2 CONST_DEC_LIST: CONST_DEC 481 3 | CONST_DEC_LIST CONST_DEC 482 483 4 @1: /* empty */ 484 485 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';' 486 487 488Terminals, with rules where they appear 489 490$end (0) 0 491';' (59) 5 492'=' (61) 5 493error (256) 494undef_id_tok (258) 5 495const_id_tok (259) 5 496 497 498Nonterminals, with rules where they appear 499 500$accept (7) 501 on left: 0 502CONST_DEC_PART (8) 503 on left: 1, on right: 0 504CONST_DEC_LIST (9) 505 on left: 2 3, on right: 1 3 506CONST_DEC (10) 507 on left: 5, on right: 2 3 508@1 (11) 509 on left: 4, on right: 5 510 511 512state 0 513 514 0 $accept: . CONST_DEC_PART $end 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 524state 1 525 526 0 $accept: CONST_DEC_PART . $end 527 528 $end shift, and go to state 5 529 530 531state 2 532 533 1 CONST_DEC_PART: CONST_DEC_LIST . 534 3 CONST_DEC_LIST: CONST_DEC_LIST . CONST_DEC 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 543state 3 544 545 2 CONST_DEC_LIST: CONST_DEC . 546 547 $default reduce using rule 2 (CONST_DEC_LIST) 548 549 550state 4 551 552 5 CONST_DEC: @1 . undef_id_tok '=' const_id_tok ';' 553 554 undef_id_tok shift, and go to state 7 555 556 557state 5 558 559 0 $accept: CONST_DEC_PART $end . 560 561 $default accept 562 563 564state 6 565 566 3 CONST_DEC_LIST: CONST_DEC_LIST CONST_DEC . 567 568 $default reduce using rule 3 (CONST_DEC_LIST) 569 570 571state 7 572 573 5 CONST_DEC: @1 undef_id_tok . '=' const_id_tok ';' 574 575 '=' shift, and go to state 8 576 577 578state 8 579 580 5 CONST_DEC: @1 undef_id_tok '=' . const_id_tok ';' 581 582 const_id_tok shift, and go to state 9 583 584 585state 9 586 587 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok . ';' 588 589 ';' shift, and go to state 10 590 591 592state 10 593 594 5 CONST_DEC: @1 undef_id_tok '=' const_id_tok ';' . 595 596 $default reduce using rule 5 (CONST_DEC) 597]]) 598 599AT_CLEANUP 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# 614# static const yytype_uint8 yydefact[] = 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 626AT_KEYWORDS([report]) 627 628AT_DATA([input.y], 629[[%% 630statement: struct_stat; 631struct_stat: /* empty. */ | if else; 632if: "if" "const" "then" statement; 633else: "else" statement; 634%% 635]]) 636 637AT_CHECK([bison -v -o input.c input.y]) 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. 641[sed -n 's/ *$//;/^static const.*\[\] =/,/^}/p' input.c >tables.c] 642 643AT_CHECK([[cat tables.c]], 0, 644[[static const yytype_uint8 yytranslate[] = 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, 671 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 672 5, 6 673}; 674static const yytype_uint8 yyprhs[] = 675{ 676 0, 0, 3, 5, 6, 9, 14 677}; 678static const yytype_int8 yyrhs[] = 679{ 680 8, 0, -1, 9, -1, -1, 10, 11, -1, 3, 681 4, 5, 8, -1, 6, 8, -1 682}; 683static const yytype_uint8 yyrline[] = 684{ 685 0, 2, 2, 3, 3, 4, 5 686}; 687static const char *const yytname[] = 688{ 689 "$end", "error", "$undefined", "\"if\"", "\"const\"", "\"then\"", 690 "\"else\"", "$accept", "statement", "struct_stat", "if", "else", 0 691}; 692static const yytype_uint16 yytoknum[] = 693{ 694 0, 256, 257, 258, 259, 260, 261 695}; 696static const yytype_uint8 yyr1[] = 697{ 698 0, 7, 8, 9, 9, 10, 11 699}; 700static const yytype_uint8 yyr2[] = 701{ 702 0, 2, 1, 0, 2, 4, 2 703}; 704static const yytype_uint8 yydefact[] = 705{ 706 3, 0, 0, 2, 0, 0, 1, 3, 4, 3, 707 6, 5 708}; 709static const yytype_int8 yydefgoto[] = 710{ 711 -1, 2, 3, 4, 8 712}; 713static const yytype_int8 yypact[] = 714{ 715 -2, -1, 4, -8, 0, 2, -8, -2, -8, -2, 716 -8, -8 717}; 718static const yytype_int8 yypgoto[] = 719{ 720 -8, -7, -8, -8, -8 721}; 722static const yytype_uint8 yytable[] = 723{ 724 10, 1, 11, 5, 6, 0, 7, 9 725}; 726static const yytype_int8 yycheck[] = 727{ 728 7, 3, 9, 4, 0, -1, 6, 5 729}; 730static const yytype_uint8 yystos[] = 731{ 732 0, 3, 8, 9, 10, 4, 0, 6, 11, 5, 733 8, 8 734}; 735]]) 736 737AT_CLEANUP 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[%{ 754static int yylex (AT_LALR1_CC_IF([int *], [void])); 755AT_LALR1_CC_IF([], 756[#include <stdio.h> 757static void yyerror (const char *);]) 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( 804[/* A C++ error reporting function. */ 805void 806yy::parser::error (const location&, const std::string& m) 807{ 808 std::cerr << m << std::endl; 809} 810 811int 812yyparse () 813{ 814 yy::parser parser; 815 parser.set_debug_level (!!YYDEBUG); 816 return parser.parse (); 817} 818], 819[static void 820yyerror (const char *s) 821{ 822 fprintf (stderr, "%s\n", s); 823}]) 824 825static int 826yylex (AT_LALR1_CC_IF([int *lval], [void])) 827[{ 828 static int toknum = 0; 829 static int tokens[] = 830 { 831 ':', -1 832 }; 833 ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[ 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]) 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])]) 859AT_PARSER_CHECK([./dancer], 1, [], 860[syntax error, unexpected ':' 861]) 862AT_BISON_OPTION_POPDEFS 863AT_CLEANUP 864]) 865 866AT_CHECK_DANCER() 867AT_CHECK_DANCER([%glr-parser]) 868AT_CHECK_DANCER([%skeleton "lalr1.cc"]) 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"]) 966