OLD | NEW |
(Empty) | |
| 1 # Checking the Bison scanner. -*- Autotest -*- |
| 2 # Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, |
| 3 # Inc. |
| 4 |
| 5 # This program is free software: you can redistribute it and/or modify |
| 6 # it under the terms of the GNU General Public License as published by |
| 7 # the Free Software Foundation, either version 3 of the License, or |
| 8 # (at your option) any later version. |
| 9 # |
| 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. |
| 14 # |
| 15 # You should have received a copy of the GNU General Public License |
| 16 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 |
| 18 AT_BANNER([[Input Processing.]]) |
| 19 |
| 20 # Mostly test that we are robust to mistakes. |
| 21 |
| 22 |
| 23 ## ------------ ## |
| 24 ## Invalid $n. ## |
| 25 ## ------------ ## |
| 26 |
| 27 AT_SETUP([Invalid $n and @n]) |
| 28 |
| 29 AT_DATA([input.y], |
| 30 [[%% |
| 31 exp: { $$ = $1 ; }; |
| 32 exp: { @$ = @1 ; }; |
| 33 ]]) |
| 34 |
| 35 AT_BISON_CHECK([input.y], [1], [], |
| 36 [[input.y:2.13-14: integer out of range: `$1' |
| 37 input.y:3.13-14: integer out of range: `@1' |
| 38 ]]) |
| 39 |
| 40 AT_CLEANUP |
| 41 |
| 42 |
| 43 ## -------------- ## |
| 44 ## Type Clashes. ## |
| 45 ## -------------- ## |
| 46 |
| 47 AT_SETUP([Type Clashes]) |
| 48 |
| 49 AT_DATA([input.y], |
| 50 [[%union { int bar; } |
| 51 %token foo |
| 52 %type <bar> exp |
| 53 %% |
| 54 exp: foo { $$; } foo { $2; } foo |
| 55 | foo |
| 56 | /* Empty. */ |
| 57 ; |
| 58 ]]) |
| 59 |
| 60 AT_BISON_CHECK([input.y], [1], [], |
| 61 [[input.y:5.12-13: $$ for the midrule at $2 of `exp' has no declared type |
| 62 input.y:5.24-25: $2 of `exp' has no declared type |
| 63 input.y:5.6-32: warning: type clash on default action: <bar> != <> |
| 64 input.y:6.6-8: warning: type clash on default action: <bar> != <> |
| 65 input.y:7.5: warning: empty rule for typed nonterminal, and no action |
| 66 ]]) |
| 67 |
| 68 AT_CLEANUP |
| 69 |
| 70 |
| 71 # _AT_UNUSED_VALUES_DECLARATIONS() |
| 72 # -------------------------------------------- |
| 73 # Generate the token, type, and destructor |
| 74 # declarations for the unused values tests. |
| 75 |
| 76 m4_define([_AT_UNUSED_VALUES_DECLARATIONS], |
| 77 [[[%token <integer> INT; |
| 78 %type <integer> a b c d e f g h i j k l; |
| 79 %destructor { destroy ($$); } INT a b c d e f g h i j k l;]]]) |
| 80 |
| 81 |
| 82 # AT_CHECK_UNUSED_VALUES(DECLARATIONS_AFTER, CHECK_MIDRULE_VALUES) |
| 83 # ------------------------------------------------------------------ |
| 84 # Generate a grammar to test unused values, |
| 85 # compile it, run it. If DECLARATIONS_AFTER |
| 86 # is set, then the token, type, and destructor |
| 87 # declarations are generated after the rules |
| 88 # rather than before. If CHECK_MIDRULE_VALUES |
| 89 # is set, then --warnings=midrule-values is |
| 90 # set. |
| 91 |
| 92 m4_define([AT_CHECK_UNUSED_VALUES], |
| 93 [AT_DATA([input.y], |
| 94 m4_ifval($1, [ |
| 95 |
| 96 |
| 97 ], [_AT_UNUSED_VALUES_DECLARATIONS |
| 98 ])[[%% |
| 99 start: |
| 100 'a' a { $]2[ } | 'b' b { $]2[ } | 'c' c { $]2[ } | 'd' d { $]2[ } | 'e' e { $]
2[ } |
| 101 | 'f' f { $]2[ } | 'g' g { $]2[ } | 'h' h { $]2[ } | 'i' i { $]2[ } | 'j' j { $]
2[ } |
| 102 | 'k' k { $]2[ } | 'l' l { $]2[ } |
| 103 ; |
| 104 |
| 105 a: INT | INT { } INT { } INT { }; |
| 106 b: INT | /* empty */; |
| 107 c: INT | INT { $]1[ } INT { $<integer>2 } INT { $<integer>4 }; |
| 108 d: INT | INT { } INT { $]1[ } INT { $<integer>2 }; |
| 109 e: INT | INT { } INT { } INT { $]1[ }; |
| 110 f: INT | INT { } INT { } INT { $]$[ = $]1[ + $]3[ + $]5[; }; |
| 111 g: INT | INT { $<integer>$; } INT { $<integer>$; } INT { }; |
| 112 h: INT | INT { $<integer>$; } INT { $<integer>$ = $<integer>2; } INT { }; |
| 113 i: INT | INT INT { } { $]$[ = $]1[ + $]2[; }; |
| 114 j: INT | INT INT { $<integer>$ = 1; } { $]$[ = $]1[ + $]2[; }; |
| 115 k: INT | INT INT { $<integer>$; } { $<integer>$ = $<integer>3; } { }; |
| 116 l: INT | INT { $<integer>$ = $<integer>1; } INT { $<integer>$ = $<integer>2 + $<
integer>3; } INT { $<integer>$ = $<integer>4 + $<integer>5; };]]m4_ifval($1, [ |
| 117 _AT_UNUSED_VALUES_DECLARATIONS]) |
| 118 ) |
| 119 |
| 120 AT_BISON_CHECK(m4_ifval($2, [ --warnings=midrule-values ])[ input.y], [0], [], |
| 121 [[input.y:11.10-32: warning: unset value: $]$[ |
| 122 input.y:11.10-32: warning: unused value: $]1[ |
| 123 input.y:11.10-32: warning: unused value: $]3[ |
| 124 input.y:11.10-32: warning: unused value: $]5[ |
| 125 input.y:12.9: warning: empty rule for typed nonterminal, and no action |
| 126 ]]m4_ifval($2, [[[input.y:13.14-19: warning: unset value: $$ |
| 127 input.y:13.25-39: warning: unset value: $$ |
| 128 ]]])[[input.y:13.10-59: warning: unset value: $]$[ |
| 129 input.y:13.10-59: warning: unused value: $]3[ |
| 130 input.y:13.10-59: warning: unused value: $]5[ |
| 131 ]]m4_ifval($2, [[[input.y:14.14-16: warning: unset value: $$ |
| 132 ]]])[[input.y:14.10-47: warning: unset value: $]$[ |
| 133 input.y:14.10-47: warning: unused value: $]3[ |
| 134 input.y:14.10-47: warning: unused value: $]5[ |
| 135 input.y:15.10-36: warning: unset value: $]$[ |
| 136 input.y:15.10-36: warning: unused value: $]3[ |
| 137 input.y:15.10-36: warning: unused value: $]5[ |
| 138 input.y:17.10-58: warning: unset value: $]$[ |
| 139 input.y:17.10-58: warning: unused value: $]1[ |
| 140 ]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]2[ |
| 141 ]]])[[input.y:17.10-58: warning: unused value: $]3[ |
| 142 ]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]4[ |
| 143 ]]])[[input.y:17.10-58: warning: unused value: $]5[ |
| 144 input.y:18.10-72: warning: unset value: $]$[ |
| 145 input.y:18.10-72: warning: unused value: $]1[ |
| 146 input.y:18.10-72: warning: unused value: $]3[ |
| 147 ]]m4_ifval($2, [[[input.y:18.10-72: warning: unused value: $]4[ |
| 148 ]]])[[input.y:18.10-72: warning: unused value: $]5[ |
| 149 ]]m4_ifval($2, [[[input.y:20.10-55: warning: unused value: $]3[ |
| 150 ]]])[[input.y:21.10-68: warning: unset value: $]$[ |
| 151 input.y:21.10-68: warning: unused value: $]1[ |
| 152 input.y:21.10-68: warning: unused value: $]2[ |
| 153 ]]m4_ifval($2, [[[input.y:21.10-68: warning: unused value: $]4[ |
| 154 ]]]))]) |
| 155 |
| 156 |
| 157 ## --------------- ## |
| 158 ## Unused values. ## |
| 159 ## --------------- ## |
| 160 |
| 161 AT_SETUP([Unused values]) |
| 162 AT_CHECK_UNUSED_VALUES |
| 163 AT_CHECK_UNUSED_VALUES(, [1]) |
| 164 AT_CLEANUP |
| 165 |
| 166 |
| 167 ## ------------------------------------------ ## |
| 168 ## Unused values before symbol declarations. ## |
| 169 ## ------------------------------------------ ## |
| 170 |
| 171 AT_SETUP([Unused values before symbol declarations]) |
| 172 AT_CHECK_UNUSED_VALUES([1]) |
| 173 AT_CHECK_UNUSED_VALUES([1], [1]) |
| 174 AT_CLEANUP |
| 175 |
| 176 |
| 177 ## --------------------------------------------- ## |
| 178 ## Default %printer and %destructor redeclared. ## |
| 179 ## --------------------------------------------- ## |
| 180 |
| 181 AT_SETUP([Default %printer and %destructor redeclared]) |
| 182 |
| 183 AT_DATA([[input.y]], |
| 184 [[%destructor { destroy ($$); } <*> <*> |
| 185 %printer { destroy ($$); } <*> <*> |
| 186 |
| 187 %destructor { destroy ($$); } <*> |
| 188 %printer { destroy ($$); } <*> |
| 189 |
| 190 %destructor { destroy ($$); } <> <> |
| 191 %printer { destroy ($$); } <> <> |
| 192 |
| 193 %destructor { destroy ($$); } <> |
| 194 %printer { destroy ($$); } <> |
| 195 |
| 196 %% |
| 197 |
| 198 start: ; |
| 199 |
| 200 %destructor { destroy ($$); } <*>; |
| 201 %printer { destroy ($$); } <*>; |
| 202 |
| 203 %destructor { destroy ($$); } <>; |
| 204 %printer { destroy ($$); } <>; |
| 205 ]]) |
| 206 |
| 207 AT_BISON_CHECK([input.y], [1], [], |
| 208 [[input.y:1.13-29: redeclaration for default tagged %destructor |
| 209 input.y:1.13-29: previous declaration |
| 210 input.y:2.10-26: redeclaration for default tagged %printer |
| 211 input.y:2.10-26: previous declaration |
| 212 input.y:4.13-29: redeclaration for default tagged %destructor |
| 213 input.y:1.13-29: previous declaration |
| 214 input.y:5.10-26: redeclaration for default tagged %printer |
| 215 input.y:2.10-26: previous declaration |
| 216 input.y:7.13-29: redeclaration for default tagless %destructor |
| 217 input.y:7.13-29: previous declaration |
| 218 input.y:8.10-26: redeclaration for default tagless %printer |
| 219 input.y:8.10-26: previous declaration |
| 220 input.y:10.13-29: redeclaration for default tagless %destructor |
| 221 input.y:7.13-29: previous declaration |
| 222 input.y:11.10-26: redeclaration for default tagless %printer |
| 223 input.y:8.10-26: previous declaration |
| 224 input.y:17.13-29: redeclaration for default tagged %destructor |
| 225 input.y:4.13-29: previous declaration |
| 226 input.y:18.10-26: redeclaration for default tagged %printer |
| 227 input.y:5.10-26: previous declaration |
| 228 input.y:20.13-29: redeclaration for default tagless %destructor |
| 229 input.y:10.13-29: previous declaration |
| 230 input.y:21.10-26: redeclaration for default tagless %printer |
| 231 input.y:11.10-26: previous declaration |
| 232 ]]) |
| 233 |
| 234 AT_CLEANUP |
| 235 |
| 236 |
| 237 ## ---------------------------------------------- ## |
| 238 ## Per-type %printer and %destructor redeclared. ## |
| 239 ## ---------------------------------------------- ## |
| 240 |
| 241 AT_SETUP([Per-type %printer and %destructor redeclared]) |
| 242 |
| 243 AT_DATA([[input.y]], |
| 244 [[%destructor { destroy ($$); } <field1> <field2> |
| 245 %printer { destroy ($$); } <field1> <field2> |
| 246 |
| 247 %destructor { destroy ($$); } <field1> <field1> |
| 248 %printer { destroy ($$); } <field2> <field2> |
| 249 |
| 250 %% |
| 251 |
| 252 start: ; |
| 253 |
| 254 %destructor { destroy ($$); } <field2> <field1>; |
| 255 %printer { destroy ($$); } <field2> <field1>; |
| 256 ]]) |
| 257 |
| 258 AT_BISON_CHECK([input.y], [1], [], |
| 259 [[input.y:4.13-29: %destructor redeclaration for <field1> |
| 260 input.y:1.13-29: previous declaration |
| 261 input.y:4.13-29: %destructor redeclaration for <field1> |
| 262 input.y:4.13-29: previous declaration |
| 263 input.y:5.10-26: %printer redeclaration for <field2> |
| 264 input.y:2.10-26: previous declaration |
| 265 input.y:5.10-26: %printer redeclaration for <field2> |
| 266 input.y:5.10-26: previous declaration |
| 267 input.y:11.13-29: %destructor redeclaration for <field1> |
| 268 input.y:4.13-29: previous declaration |
| 269 input.y:11.13-29: %destructor redeclaration for <field2> |
| 270 input.y:1.13-29: previous declaration |
| 271 input.y:12.10-26: %printer redeclaration for <field1> |
| 272 input.y:2.10-26: previous declaration |
| 273 input.y:12.10-26: %printer redeclaration for <field2> |
| 274 input.y:5.10-26: previous declaration |
| 275 ]]) |
| 276 |
| 277 AT_CLEANUP |
| 278 |
| 279 |
| 280 ## ---------------------------------------- ## |
| 281 ## Unused values with default %destructor. ## |
| 282 ## ---------------------------------------- ## |
| 283 |
| 284 AT_SETUP([Unused values with default %destructor]) |
| 285 |
| 286 AT_DATA([[input.y]], |
| 287 [[%destructor { destroy ($$); } <> |
| 288 %type <tag> tagged |
| 289 |
| 290 %% |
| 291 |
| 292 start: end end tagged tagged { $<tag>1; $3; } ; |
| 293 end: { } ; |
| 294 tagged: { } ; |
| 295 ]]) |
| 296 |
| 297 AT_BISON_CHECK([input.y], [0], [], |
| 298 [[input.y:6.8-45: warning: unset value: $$ |
| 299 input.y:6.8-45: warning: unused value: $2 |
| 300 input.y:7.6-8: warning: unset value: $$ |
| 301 ]]) |
| 302 |
| 303 AT_DATA([[input.y]], |
| 304 [[%destructor { destroy ($$); } <*> |
| 305 %type <tag> tagged |
| 306 |
| 307 %% |
| 308 |
| 309 start: end end tagged tagged { $<tag>1; $3; } ; |
| 310 end: { } ; |
| 311 tagged: { } ; |
| 312 ]]) |
| 313 |
| 314 AT_BISON_CHECK([input.y], [0], [], |
| 315 [[input.y:6.8-45: warning: unused value: $4 |
| 316 input.y:8.9-11: warning: unset value: $$ |
| 317 ]]) |
| 318 |
| 319 AT_CLEANUP |
| 320 |
| 321 |
| 322 ## ----------------------------------------- ## |
| 323 ## Unused values with per-type %destructor. ## |
| 324 ## ----------------------------------------- ## |
| 325 |
| 326 AT_SETUP([Unused values with per-type %destructor]) |
| 327 |
| 328 AT_DATA([[input.y]], |
| 329 [[%destructor { destroy ($$); } <field1> |
| 330 %type <field1> start end |
| 331 |
| 332 %% |
| 333 |
| 334 start: end end { $1; } ; |
| 335 end: { } ; |
| 336 ]]) |
| 337 |
| 338 AT_BISON_CHECK([input.y], [0], [], |
| 339 [[input.y:6.8-22: warning: unset value: $$ |
| 340 input.y:6.8-22: warning: unused value: $2 |
| 341 input.y:7.6-8: warning: unset value: $$ |
| 342 ]]) |
| 343 |
| 344 AT_CLEANUP |
| 345 |
| 346 |
| 347 ## ---------------------- ## |
| 348 ## Incompatible Aliases. ## |
| 349 ## ---------------------- ## |
| 350 |
| 351 AT_SETUP([Incompatible Aliases]) |
| 352 |
| 353 AT_DATA([input.y], |
| 354 [[%token foo "foo" |
| 355 |
| 356 %type <bar> foo |
| 357 %printer {bar} foo |
| 358 %destructor {bar} foo |
| 359 %left foo |
| 360 |
| 361 %type <baz> "foo" |
| 362 %printer {baz} "foo" |
| 363 %destructor {baz} "foo" |
| 364 %left "foo" |
| 365 |
| 366 %% |
| 367 exp: foo; |
| 368 ]]) |
| 369 |
| 370 AT_BISON_CHECK([input.y], [1], [], |
| 371 [[input.y:8.7-11: %type redeclaration for foo |
| 372 input.y:3.7-11: previous declaration |
| 373 input.y:10.13-17: %destructor redeclaration for foo |
| 374 input.y:5.13-17: previous declaration |
| 375 input.y:9.10-14: %printer redeclaration for foo |
| 376 input.y:4.10-14: previous declaration |
| 377 input.y:11.1-5: %left redeclaration for foo |
| 378 input.y:6.1-5: previous declaration |
| 379 ]]) |
| 380 |
| 381 AT_CLEANUP |
| 382 |
| 383 |
| 384 |
| 385 ## ----------------------- ## |
| 386 ## Torturing the Scanner. ## |
| 387 ## ----------------------- ## |
| 388 |
| 389 # Be sure to compile and run, so that the C compiler checks what |
| 390 # we do. |
| 391 |
| 392 AT_SETUP([Torturing the Scanner]) |
| 393 |
| 394 |
| 395 AT_DATA([input.y], []) |
| 396 AT_BISON_CHECK([input.y], [1], [], |
| 397 [[input.y:1.1: syntax error, unexpected end of file |
| 398 ]]) |
| 399 |
| 400 |
| 401 AT_DATA([input.y], |
| 402 [{} |
| 403 ]) |
| 404 AT_BISON_CHECK([input.y], [1], [], |
| 405 [[input.y:1.1-2: syntax error, unexpected {...} |
| 406 ]]) |
| 407 |
| 408 |
| 409 AT_DATA_GRAMMAR([input.y], |
| 410 [[%{ |
| 411 /* This is seen in GCC: a %{ and %} in middle of a comment. */ |
| 412 const char *foo = "So %{ and %} can be here too."; |
| 413 |
| 414 #if 0 |
| 415 /* These examples test Bison while not stressing C compilers too much. |
| 416 Many C compilers mishandle backslash-newlines, so this part of the |
| 417 test is inside "#if 0". The comment and string are written so that |
| 418 the "#endif" will be seen regardless of the C compiler bugs that we |
| 419 know about, namely: |
| 420 |
| 421 HP C (as of late 2002) mishandles *\[newline]\[newline]/ within a |
| 422 comment. |
| 423 |
| 424 The Apple Darwin compiler (as of late 2002) mishandles |
| 425 \\[newline]' within a character constant. |
| 426 |
| 427 */ |
| 428 |
| 429 /\ |
| 430 * A comment with backslash-newlines in it. %} *\ |
| 431 \ |
| 432 / |
| 433 /* { Close the above comment, if the C compiler mishandled it. */ |
| 434 |
| 435 char str[] = "\\ |
| 436 " A string with backslash-newlines in it %{ %} \\ |
| 437 \ |
| 438 ""; |
| 439 |
| 440 char apostrophe = '\''; |
| 441 #endif |
| 442 |
| 443 #include <stdio.h> |
| 444 #include <stdlib.h> |
| 445 %} |
| 446 /* %{ and %} can be here too. */ |
| 447 |
| 448 %{ |
| 449 /* Exercise pre-prologue dependency to %union. */ |
| 450 typedef int value; |
| 451 %} |
| 452 |
| 453 /* Exercise M4 quoting: '@:>@@:>@', 0. */ |
| 454 |
| 455 /* Also exercise %union. */ |
| 456 %union |
| 457 { |
| 458 value ival; /* A comment to exercise an old bug. */ |
| 459 }; |
| 460 |
| 461 |
| 462 /* Exercise post-prologue dependency to %union. */ |
| 463 %{ |
| 464 static YYSTYPE value_as_yystype (value val); |
| 465 |
| 466 /* Exercise quotes in declarations. */ |
| 467 char quote[] = "@:>@@:>@,"; |
| 468 %} |
| 469 |
| 470 %{ |
| 471 static void yyerror (const char *s); |
| 472 static int yylex (void); |
| 473 %} |
| 474 |
| 475 %type <ival> '@<:@' |
| 476 |
| 477 /* Exercise quotes in strings. */ |
| 478 %token FAKE "fake @<:@@:>@ \a\b\f\n\r\t\v\"\'\?\\\u005B\U0000005c ??!??'??(??)??
-??/??<??=??> \x1\1" |
| 479 |
| 480 %% |
| 481 /* Exercise M4 quoting: '@:>@@:>@', @<:@, 1. */ |
| 482 exp: '@<:@' '\1' two '$' '@' '{' oline output.or.oline.opt |
| 483 { |
| 484 /* Exercise quotes in braces. */ |
| 485 char tmp[] = "@<:@%c@:>@,\n"; |
| 486 printf (tmp, $1); |
| 487 } |
| 488 ; |
| 489 |
| 490 two: '\x000000000000000000000000000000000000000000000000000000000000000000002'; |
| 491 oline: '@' 'o' 'l' 'i' 'n' 'e' '@' '_' '_' 'o' 'l' 'i' 'n' 'e' '_' '_'; |
| 492 output.or.oline.opt: ;|oline;;|output;;; |
| 493 output: '#' 'o' 'u' 't' 'p' 'u' 't' ' '; |
| 494 %% |
| 495 /* Exercise M4 quoting: '@:>@@:>@', @<:@, 2. */ |
| 496 |
| 497 static YYSTYPE |
| 498 value_as_yystype (value val) |
| 499 { |
| 500 YYSTYPE res; |
| 501 res.ival = val; |
| 502 return res; |
| 503 } |
| 504 |
| 505 static int |
| 506 yylex (void) |
| 507 { |
| 508 static char const input[] = "@<:@\1\2$@{@oline@__@&t@oline__\ |
| 509 #output "; /* " |
| 510 */ |
| 511 static size_t toknum; |
| 512 if (! (toknum < sizeof input)) |
| 513 abort (); |
| 514 yylval = value_as_yystype (input[toknum]); |
| 515 return input[toknum++]; |
| 516 } |
| 517 |
| 518 static void |
| 519 yyerror (const char *msg) |
| 520 { |
| 521 fprintf (stderr, "%s\n", msg); |
| 522 } |
| 523 ]]) |
| 524 |
| 525 # Pacify Emacs'font-lock-mode: " |
| 526 |
| 527 AT_DATA([main.c], |
| 528 [[typedef int value; |
| 529 #include "input.h" |
| 530 |
| 531 int yyparse (void); |
| 532 |
| 533 int |
| 534 main (void) |
| 535 { |
| 536 return yyparse (); |
| 537 } |
| 538 ]]) |
| 539 |
| 540 AT_BISON_CHECK([-d -v -o input.c input.y]) |
| 541 AT_COMPILE([input.o], [-c input.c]) |
| 542 AT_COMPILE([main.o], [-c main.c]) |
| 543 AT_COMPILE([input], [input.o main.o]) |
| 544 AT_PARSER_CHECK([./input], 0, |
| 545 [[[@<:@], |
| 546 ]]) |
| 547 |
| 548 AT_CLEANUP |
| 549 |
| 550 |
| 551 ## ---------------------- ## |
| 552 ## Typed symbol aliases. ## |
| 553 ## ---------------------- ## |
| 554 |
| 555 AT_SETUP([Typed symbol aliases]) |
| 556 |
| 557 # Bison 2.0 broke typed symbol aliases - ensure they work. |
| 558 |
| 559 AT_DATA_GRAMMAR([input.y], |
| 560 [[%union |
| 561 { |
| 562 int val; |
| 563 }; |
| 564 %token <val> MY_TOKEN "MY TOKEN" |
| 565 %type <val> exp |
| 566 %% |
| 567 exp: "MY TOKEN"; |
| 568 %% |
| 569 ]]) |
| 570 |
| 571 AT_BISON_CHECK([-o input.c input.y]) |
| 572 |
| 573 AT_CLEANUP |
| 574 |
| 575 |
| 576 ## --------- ## |
| 577 ## Require. ## |
| 578 ## --------- ## |
| 579 |
| 580 m4_define([AT_CHECK_REQUIRE], |
| 581 [AT_SETUP([Require $1]) |
| 582 AT_DATA_GRAMMAR([input.y], |
| 583 [[%require "$1"; |
| 584 %% |
| 585 empty_file:; |
| 586 ]]) |
| 587 AT_BISON_CHECK([-o input.c input.y], $2, [], ignore) |
| 588 AT_CLEANUP |
| 589 ]) |
| 590 |
| 591 AT_CHECK_REQUIRE(1.0, 0) |
| 592 AT_CHECK_REQUIRE(AT_PACKAGE_VERSION, 0) |
| 593 ## FIXME: Some day augment this version number. |
| 594 AT_CHECK_REQUIRE(100.0, 63) |
| 595 |
| 596 |
| 597 ## ------------------------------------- ## |
| 598 ## String aliases for character tokens. ## |
| 599 ## ------------------------------------- ## |
| 600 |
| 601 AT_SETUP([String aliases for character tokens]) |
| 602 |
| 603 # Bison once thought a character token and its alias were different symbols |
| 604 # with the same user token number. |
| 605 |
| 606 AT_DATA_GRAMMAR([input.y], |
| 607 [[%token 'a' "a" |
| 608 %% |
| 609 start: 'a'; |
| 610 %% |
| 611 ]]) |
| 612 |
| 613 AT_BISON_CHECK([-o input.c input.y]) |
| 614 |
| 615 AT_CLEANUP |
| 616 |
| 617 |
| 618 ## --------------------- ## |
| 619 ## Unclosed constructs. ## |
| 620 ## --------------------- ## |
| 621 |
| 622 AT_SETUP([Unclosed constructs]) |
| 623 |
| 624 # Bison's scan-gram.l once forgot to STRING_FINISH some unclosed constructs, so |
| 625 # they were prepended to whatever it STRING_GROW'ed next. It also threw them |
| 626 # away rather than returning them to the parser. The effect was confusing |
| 627 # subsequent error messages. |
| 628 |
| 629 AT_DATA([input.y], |
| 630 [[%token A "a |
| 631 %token B "b" |
| 632 %token AB "ab" // Used to complain that "ab" was already used. |
| 633 %token C '1 |
| 634 %token TWO "2" |
| 635 %token TICK_TWELVE "'12" // Used to complain that "'12" was already used. |
| 636 |
| 637 %% |
| 638 |
| 639 start: ; |
| 640 |
| 641 // Used to report a syntax error because it didn't see any kind of symbol |
| 642 // identifier. |
| 643 %type <f> 'a |
| 644 ; |
| 645 %type <f> "a |
| 646 ; |
| 647 // Used to report a syntax error because it didn't see braced code. |
| 648 %destructor { free ($$) |
| 649 ]]) |
| 650 |
| 651 AT_BISON_CHECK([-o input.c input.y], 1, [], |
| 652 [[input.y:1.10-2.0: missing `"' at end of line |
| 653 input.y:4.10-5.0: missing `'' at end of line |
| 654 input.y:14.11-15.0: missing `'' at end of line |
| 655 input.y:16.11-17.0: missing `"' at end of line |
| 656 input.y:19.13-20.0: missing `}' at end of file |
| 657 input.y:20.1: syntax error, unexpected end of file |
| 658 ]]) |
| 659 |
| 660 AT_CLEANUP |
| 661 |
| 662 |
| 663 ## ------------------------- ## |
| 664 ## %start after first rule. ## |
| 665 ## ------------------------- ## |
| 666 |
| 667 AT_SETUP([%start after first rule]) |
| 668 |
| 669 # Bison once complained that a %start after the first rule was a redeclaration |
| 670 # of the start symbol. |
| 671 |
| 672 AT_DATA([input.y], |
| 673 [[%% |
| 674 false_start: ; |
| 675 start: false_start ; |
| 676 %start start; |
| 677 ]]) |
| 678 |
| 679 AT_BISON_CHECK([-o input.c input.y]) |
| 680 |
| 681 AT_CLEANUP |
| 682 |
| 683 |
| 684 ## --------------------- ## |
| 685 ## %prec takes a token. ## |
| 686 ## --------------------- ## |
| 687 |
| 688 AT_SETUP([%prec takes a token]) |
| 689 |
| 690 # Bison once allowed %prec sym where sym was a nonterminal. |
| 691 |
| 692 AT_DATA([input.y], |
| 693 [[%% |
| 694 start: PREC %prec PREC ; |
| 695 PREC: ; |
| 696 ]]) |
| 697 |
| 698 AT_BISON_CHECK([input.y], [1], [], |
| 699 [[input.y:3.1-4: rule given for PREC, which is a token |
| 700 ]]) |
| 701 |
| 702 AT_CLEANUP |
| 703 |
| 704 |
| 705 ## -------------------------------- ## |
| 706 ## Reject unused %code qualifiers. ## |
| 707 ## -------------------------------- ## |
| 708 |
| 709 AT_SETUP([Reject unused %code qualifiers]) |
| 710 |
| 711 AT_DATA([input-c.y], |
| 712 [[%code q {} |
| 713 %code bad {} |
| 714 %code bad {} |
| 715 %code format {} |
| 716 %% |
| 717 start: ; |
| 718 ]]) |
| 719 AT_BISON_CHECK([[input-c.y]], [0], [], |
| 720 [[input-c.y:1.7: warning: %code qualifier `q' is not used |
| 721 input-c.y:2.7-9: warning: %code qualifier `bad' is not used |
| 722 input-c.y:3.7-9: warning: %code qualifier `bad' is not used |
| 723 input-c.y:4.7-12: warning: %code qualifier `format' is not used |
| 724 ]]) |
| 725 |
| 726 AT_DATA([input-c-glr.y], |
| 727 [[%code q {} |
| 728 %code bad {} |
| 729 %code bad {} |
| 730 %% |
| 731 start: ; |
| 732 ]]) |
| 733 AT_BISON_CHECK([[input-c-glr.y]], [0], [], |
| 734 [[input-c-glr.y:1.7: warning: %code qualifier `q' is not used |
| 735 input-c-glr.y:2.7-9: warning: %code qualifier `bad' is not used |
| 736 input-c-glr.y:3.8-10: warning: %code qualifier `bad' is not used |
| 737 ]]) |
| 738 |
| 739 AT_DATA([input-c++.y], |
| 740 [[%code q {} |
| 741 %code bad {} |
| 742 %code q {} |
| 743 %% |
| 744 start: ; |
| 745 ]]) |
| 746 AT_BISON_CHECK([[input-c++.y]], [0], [], |
| 747 [[input-c++.y:1.7: warning: %code qualifier `q' is not used |
| 748 input-c++.y:2.7-9: warning: %code qualifier `bad' is not used |
| 749 input-c++.y:3.8: warning: %code qualifier `q' is not used |
| 750 ]]) |
| 751 |
| 752 AT_DATA([input-c++-glr.y], |
| 753 [[%code bad {} |
| 754 %code q {} |
| 755 %code q {} |
| 756 %% |
| 757 start: ; |
| 758 ]]) |
| 759 AT_BISON_CHECK([[input-c++-glr.y]], [0], [], |
| 760 [[input-c++-glr.y:1.7-9: warning: %code qualifier `bad' is not used |
| 761 input-c++-glr.y:2.7: warning: %code qualifier `q' is not used |
| 762 input-c++-glr.y:3.7: warning: %code qualifier `q' is not used |
| 763 ]]) |
| 764 |
| 765 AT_DATA([special-char-@@.y], |
| 766 [[%code bad {} |
| 767 %code q {} |
| 768 %code q {} |
| 769 %% |
| 770 start: ; |
| 771 ]]) |
| 772 AT_BISON_CHECK([[special-char-@@.y]], [0], [], |
| 773 [[special-char-@@.y:1.7-9: warning: %code qualifier `bad' is not used |
| 774 special-char-@@.y:2.7: warning: %code qualifier `q' is not used |
| 775 special-char-@@.y:3.7: warning: %code qualifier `q' is not used |
| 776 ]]) |
| 777 |
| 778 AT_DATA([special-char-@:>@.y], |
| 779 [[%code bad {} |
| 780 %code q {} |
| 781 %code q {} |
| 782 %% |
| 783 start: ; |
| 784 ]]) |
| 785 AT_BISON_CHECK([[special-char-@:>@.y]], [0], [], |
| 786 [[special-char-@:>@.y:1.7-9: warning: %code qualifier `bad' is not used |
| 787 special-char-@:>@.y:2.7: warning: %code qualifier `q' is not used |
| 788 special-char-@:>@.y:3.7: warning: %code qualifier `q' is not used |
| 789 ]]) |
| 790 |
| 791 AT_CLEANUP |
| 792 |
| 793 |
| 794 ## ---------------- ## |
| 795 ## %define errors. ## |
| 796 ## ---------------- ## |
| 797 |
| 798 AT_SETUP([%define errors]) |
| 799 |
| 800 AT_DATA([input.y], |
| 801 [[%define var "value1" |
| 802 %define var "value1" |
| 803 %define var "value2" |
| 804 %define special1 "@:>@" |
| 805 %define special2 "@<:@" |
| 806 %% |
| 807 start: ; |
| 808 ]]) |
| 809 |
| 810 AT_BISON_CHECK([[input.y]], [0], [], |
| 811 [[input.y:2.9-11: warning: %define variable `var' redefined |
| 812 input.y:1.9-11: warning: previous definition |
| 813 input.y:3.10-12: warning: %define variable `var' redefined |
| 814 input.y:2.9-11: warning: previous definition |
| 815 input.y:1.9-11: warning: %define variable `var' is not used |
| 816 input.y:2.9-11: warning: %define variable `var' is not used |
| 817 input.y:3.10-12: warning: %define variable `var' is not used |
| 818 input.y:4.9-16: warning: %define variable `special1' is not used |
| 819 input.y:5.9-16: warning: %define variable `special2' is not used |
| 820 ]]) |
| 821 |
| 822 AT_CLEANUP |
| 823 |
| 824 ## --------------------------- ## |
| 825 ## %define Boolean variables. ## |
| 826 ## --------------------------- ## |
| 827 |
| 828 AT_SETUP([[%define Boolean variables]]) |
| 829 |
| 830 AT_DATA([Input.y], |
| 831 [[%language "Java" |
| 832 %define public "maybe" |
| 833 %define parser_class_name "Input" |
| 834 %% |
| 835 start: ; |
| 836 ]]) |
| 837 |
| 838 AT_BISON_CHECK([[Input.y]], [1], [], |
| 839 [[Input.y:2.9-14: invalid value for %define Boolean variable `public' |
| 840 ]]) |
| 841 |
| 842 AT_CLEANUP |
| 843 |
| 844 ## ------------------------ ## |
| 845 ## %define enum variables. ## |
| 846 ## ------------------------ ## |
| 847 |
| 848 AT_SETUP([[%define enum variables]]) |
| 849 |
| 850 AT_DATA([[input.y]], |
| 851 [[%define api.push_pull "neither" |
| 852 %% |
| 853 start: ; |
| 854 ]]) |
| 855 |
| 856 AT_BISON_CHECK([[input.y]], [1], [], |
| 857 [[input.y:1.9-21: invalid value for %define variable `api.push_pull': `neither' |
| 858 ]]) |
| 859 |
| 860 AT_CLEANUP |
| 861 |
| 862 ## ------------------------- ## |
| 863 ## Unused %define api.pure. ## |
| 864 ## ------------------------- ## |
| 865 |
| 866 AT_SETUP([[Unused %define api.pure]]) |
| 867 |
| 868 # AT_CHECK_API_PURE(DECLS, VALUE) |
| 869 # ------------------------------- |
| 870 # Make sure Bison reports that `%define api.pure VALUE' is unused when DECLS |
| 871 # are specified. |
| 872 m4_define([AT_CHECK_API_PURE], |
| 873 [ |
| 874 AT_DATA([[input.y]], |
| 875 [[%define api.pure ]$2[ |
| 876 ]$1[ |
| 877 %% |
| 878 start: ; |
| 879 ]]) |
| 880 |
| 881 AT_BISON_CHECK([[input.y]], [0], [], |
| 882 [[input.y:1.9-16: warning: %define variable `api.pure' is not used |
| 883 ]]) |
| 884 ]) |
| 885 |
| 886 AT_CHECK_API_PURE([[%language "c++" %defines]], [[]]) |
| 887 AT_CHECK_API_PURE([[%language "c++" %defines]], [["false"]]) |
| 888 AT_CHECK_API_PURE([[%language "c++" %defines %glr-parser]], [[""]]) |
| 889 AT_CHECK_API_PURE([[%language "c++" %defines %glr-parser]], [["false"]]) |
| 890 AT_CHECK_API_PURE([[%language "java"]], [["true"]]) |
| 891 AT_CHECK_API_PURE([[%language "java"]], [["false"]]) |
| 892 |
| 893 AT_CLEANUP |
| 894 |
| 895 ## -------------------------------- ## |
| 896 ## C++ namespace reference errors. ## |
| 897 ## -------------------------------- ## |
| 898 |
| 899 AT_SETUP([[C++ namespace reference errors]]) |
| 900 |
| 901 # AT_CHECK_NAMESPACE_ERROR(NAMESPACE-DECL, ERROR, [ERROR], ...) |
| 902 # ------------------------------------------------------------- |
| 903 # Make sure Bison reports all ERROR's for %define namespace "NAMESPACE-DECL". |
| 904 m4_define([AT_CHECK_NAMESPACE_ERROR], |
| 905 [ |
| 906 AT_DATA([[input.y]], |
| 907 [[%language "C++" |
| 908 %defines |
| 909 %define namespace "]$1[" |
| 910 %% |
| 911 start: ; |
| 912 ]]) |
| 913 |
| 914 AT_BISON_CHECK([[input.y]], [1], [], |
| 915 [m4_foreach([b4_arg], m4_dquote(m4_shift($@)), |
| 916 [[input.y:3.9-17: ]b4_arg[ |
| 917 ]])]) |
| 918 ]) |
| 919 |
| 920 AT_CHECK_NAMESPACE_ERROR([[]], |
| 921 [[namespace reference is empty]]) |
| 922 AT_CHECK_NAMESPACE_ERROR([[ ]], |
| 923 [[namespace reference is empty]]) |
| 924 AT_CHECK_NAMESPACE_ERROR([[foo::::bar]], |
| 925 [[namespace reference has consecutive "::"]]) |
| 926 AT_CHECK_NAMESPACE_ERROR([[foo:: ::bar]], |
| 927 [[namespace reference has consecutive "::"]]) |
| 928 AT_CHECK_NAMESPACE_ERROR([[::::bar]], |
| 929 [[namespace reference has consecutive "::"]]) |
| 930 AT_CHECK_NAMESPACE_ERROR([[:: ::bar]], |
| 931 [[namespace reference has consecutive "::"]]) |
| 932 AT_CHECK_NAMESPACE_ERROR([[foo::bar:: ::]], |
| 933 [[namespace reference has consecutive "::"]], |
| 934 [[namespace reference has a trailing "::"]]) |
| 935 AT_CHECK_NAMESPACE_ERROR([[foo::bar::]], |
| 936 [[namespace reference has a trailing "::"]]) |
| 937 AT_CHECK_NAMESPACE_ERROR([[foo::bar:: ]], |
| 938 [[namespace reference has a trailing "::"]]) |
| 939 AT_CHECK_NAMESPACE_ERROR([[::]], |
| 940 [[namespace reference has a trailing "::"]]) |
| 941 |
| 942 AT_CLEANUP |
OLD | NEW |