Files
bison/tests/named-refs.at
Paul Eggert 6e30ede87a Do not use date ranges in copyright notices.
See http://www.gnu.org/prep/maintain/maintain.html#Copyright-Notices

* HACKING, Makefile.am, NEWS, PACKAGING, README, README-alpha:
* TODO, bootstrap, bootstrap.conf:
* build-aux/update-b4-copyright, cfg.mk, configure.ac:
* data/README, data/bison.m4, data/c++-skel.m4, data/c++.m4:
* data/c-skel.m4, data/c.m4, data/glr.c, data/glr.cc:
* data/java-skel.m4, data/java.m4, data/lalr1.cc:
* data/lalr1.java, data/location.cc:
* data/xslt/bison.xsl:
* data/xslt/xml2dot.xsl, data/xslt/xml2text.xsl:
* data/xslt/xml2xhtml.xsl, data/yacc.c, djgpp/Makefile.maint:
* djgpp/README.in, djgpp/config.bat, djgpp/config.sed:
* djgpp/config.site, djgpp/config_h.sed, djgpp/djunpack.bat:
* djgpp/subpipe.c, djgpp/subpipe.h:
* djgpp/testsuite.sed, doc/bison.texinfo:
* doc/refcard.tex, etc/README, etc/bench.pl.in:
* examples/calc++/Makefile.am, examples/extexi:
* lib/abitset.c, lib/abitset.h:
* lib/bbitset.h, lib/bitset.c, lib/bitset.h:
* lib/bitset_stats.c, lib/bitset_stats.h, lib/bitsetv-print.c:
* lib/bitsetv-print.h, lib/bitsetv.c, lib/bitsetv.h:
* lib/ebitset.c, lib/ebitset.h, lib/get-errno.c:
* lib/get-errno.h, lib/lbitset.c, lib/lbitset.h:
* lib/libiberty.h, lib/main.c, lib/timevar.c:
* lib/timevar.def, lib/timevar.h, lib/vbitset.c:
* lib/vbitset.h, lib/yyerror.c, m4/bison-i18n.m4:
* m4/c-working.m4, m4/cxx.m4, m4/subpipe.m4, m4/timevar.m4:
* src/AnnotationList.c, src/AnnotationList.h:
* src/InadequacyList.c, src/InadequacyList.h, src/LR0.c:
* src/LR0.h, src/Sbitset.c, src/Sbitset.h, src/assoc.c:
* src/assoc.h, src/closure.c, src/closure.h, src/complain.c:
* src/complain.h, src/conflicts.c, src/conflicts.h:
* src/derives.c, src/derives.h, src/files.c, src/files.h:
* src/flex-scanner.h, src/getargs.c, src/getargs.h:
* src/gram.c, src/gram.h, src/graphviz.c, src/ielr.c:
* src/ielr.h, src/lalr.c, src/lalr.h:
* src/location.c, src/location.h, src/main.c:
* src/muscle-tab.c, src/muscle-tab.h, src/named-ref.c:
* src/named-ref.h, src/nullable.c, src/nullable.h:
* src/output.c, src/output.h, src/parse-gram.y:
* src/print-xml.c, src/print-xml.h, src/print.c, src/print.h:
* src/print_graph.c, src/print_graph.h, src/reader.c:
* src/reader.h, src/reduce.c, src/reduce.h, src/relation.c:
* src/relation.h, src/scan-code.h, src/scan-code.l:
* src/scan-gram.h, src/scan-gram.l, src/scan-skel.h:
* src/scan-skel.l, src/state.c, src/state.h, src/symlist.c:
* src/symlist.h, src/symtab.c, src/symtab.h, src/system.h:
* src/tables.c, src/tables.h, src/uniqstr.c, src/uniqstr.h:
* tests/actions.at, tests/atlocal.in, tests/c++.at:
* tests/calc.at, tests/conflicts.at, tests/cxx-type.at:
* tests/existing.at, tests/glr-regression.at:
* tests/headers.at, tests/input.at, tests/java.at:
* tests/local.at, tests/named-refs.at:
* tests/output.at, tests/push.at, tests/reduce.at:
* tests/regression.at, tests/sets.at, tests/skeletons.at:
* tests/synclines.at, tests/testsuite.at, tests/torture.at:
* data/Makefile.am, data/location.cc, doc/Makefile.am, src/Makefile.am:
* tests/Makefile.am, lib/Makefile.am, examples/Makefile.am:
* etc/Makefile.am:
Don't use date ranges in copyright notices.

Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996,
1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
2008, 2009, 2010 Free Software Foundation, Inc.
2010-06-23 13:07:29 -07:00

564 lines
15 KiB
Plaintext

# Named references test. -*- Autotest -*-
# Copyright (C) 2009, 2010 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
AT_BANNER([[Named references tests.]])
AT_SETUP([Tutorial calculator])
AT_DATA_GRAMMAR([test.y],
[[
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef int semantic_value;
FILE *input;
static semantic_value global_result = 0;
static int global_count = 0;
static int power (int base, int exponent);
static void yyerror (const char *s);
int yylex (void);
%}
%union
{
semantic_value ival;
};
%token CALC_EOF 0 "end of input"
%token <ival> NUM "number"
%type <ival> exp
%nonassoc '=' /* comparison */
%left '-' '+'
%left '*' '/'
%left NEG /* negation--unary minus */
%right '^' /* exponentiation */
%%
input:
line
| input line { }
;
line:
'\n'
| exp '\n' { }
;
exp:
NUM { $$ = $NUM; }
| exp[l] '=' exp[r]
{
if ($l != $r)
fprintf (stderr, "calc: error: %d != %d\n", $l, $r);
$$ = $l;
}
| exp[x] '+' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>l + $r; }
| exp[l] '-' exp[r] { $$ = $l - $r; }
| exp[l] '*' exp[r] { $$ = $l * $r; }
| exp[l] '/' exp[r] { $$ = $l / $r; }
| '-' exp %prec NEG { $$ = -$2; }
| exp[l] '^' exp[r] { $$ = power ($l, $r); }
| '(' exp[e] ')' { $$ = $e; }
| '(' error ')' { $$ = 1111; yyerrok; }
| '!' { $$ = 0; YYERROR; }
| '-' error { $$ = 0; YYERROR; }
;
%%
static void yyerror (const char *s)
{
fprintf (stderr, "%s\n", s);
}
static int get_char (void)
{
int res = getc (input);
return res;
}
static void unget_char (int c)
{
ungetc (c, input);
}
static int read_signed_integer (void)
{
int c = get_char ();
int sign = 1;
int n = 0;
if (c == '-')
{
c = get_char ();
sign = -1;
}
while (isdigit (c))
{
n = 10 * n + (c - '0');
c = get_char ();
}
unget_char ( c);
return sign * n;
}
int yylex (void)
{
int c;
/* Skip white space. */
while ((c = get_char ()) == ' ' || c == '\t') {}
/* process numbers */
if (c == '.' || isdigit (c))
{
unget_char ( c);
(yylval).ival = read_signed_integer ();
return NUM;
}
/* Return end-of-file. */
if (c == EOF)
return CALC_EOF;
/* Return single chars. */
return c;
}
static int power (int base, int exponent)
{
int res = 1;
if (exponent < 0)
exit (3);
for (/* Niente */; exponent; --exponent)
res *= base;
return res;
}
int main (int argc, const char **argv)
{
semantic_value result = 0;
int count = 0;
int status;
if (argc == 2)
input = fopen (argv[1], "r");
else
input = stdin;
if (!input)
{
perror (argv[1]);
return 3;
}
status = yyparse ();
fclose (input);
if (global_result != result)
abort ();
if (global_count != count)
abort ();
return status;
}
]])
AT_DATA([input.txt],
[[
1 + 2 * 3 = 7
1 + 2 * -3 = -5
-1^2 = -1
(-1)^2 = 1
---1 = -1
1 - 2 - 3 = -4
1 - (2 - 3) = 2
2^2^3 = 256
(2^2)^3 = 64
]])
AT_BISON_CHECK([-o test.c test.y])
AT_COMPILE([[test]])
AT_PARSER_CHECK([./test input.txt], 0, [], [stderr])
AT_CLEANUP
#######################################################################
AT_SETUP([Undefined and ambiguous references])
AT_DATA_GRAMMAR([test.y],
[[
%{
static int power (int base, int exponent);
static void yyerror (const char *s);
int yylex (void);
%}
%union
{
int ival;
};
%token CALC_EOF 0 "end of input"
%token <ival> NUM "number"
%type <ival> exp
%nonassoc '=' /* comparison */
%left '-' '+'
%left '*' '/'
%left NEG /* negation--unary minus */
%right '^' /* exponentiation */
%%
input:
line
| input line { }
;
line:
'\n'
| exp '\n' { }
;
exp:
NUM { $$ = $NUM; }
| exp[l] '=' exp[r]
{
if ($l != $r)
fprintf (stderr, "calc: error: %d != %d\n", $l, $r);
$$ = $l;
}
| exp[x] '+' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>lo9 + $r; }
| exp[x] '-' { $<ival>$ = $x; } [l] exp[r] { $$ = $<ival>exp - $r; }
| exp[x] '*' { $<ival>$ = $x; } [l] exp[r] { $$ = $l * $r; }
| exp[l] '/' exp[r] { $$ = $l / $r; }
| '-' exp %prec NEG { $$ = -$2; }
| exp[l] '^' exp[r] { $$ = power ($l, $r12); }
| '(' exp ')' { $$ = $expo; }
| '(' error ')' { $$ = 1111; yyerrok; }
| '!' { $$ = 0; YYERROR; }
| '-' error { $$ = 0; YYERROR; }
;
%%
]])
AT_BISON_CHECK([-o test.c test.y], 1, [],
[[test.y:50.51-60: invalid reference: `$<ival>lo9'
test.y:50.3-68: symbol not found in production: lo9
test.y:51.51-60: warning: misleading reference: `$<ival>exp'
test.y:42.1-3: warning: refers to: $exp at $$
test.y:51.7: warning: possibly meant: $x, hiding $exp at $1
test.y:51.41: warning: possibly meant: $r, hiding $exp at $4
test.y:52.51-52: $l of `exp' has no declared type
test.y:55.46-49: invalid reference: `$r12'
test.y:55.3-53: symbol not found in production: r12
test.y:56.29-33: invalid reference: `$expo'
test.y:56.3-46: symbol not found in production: expo
]])
AT_CLEANUP
#######################################################################
AT_SETUP([Misleading references])
AT_DATA_GRAMMAR([test.y],
[[
%%
start: foo foo.bar { $foo.bar; }
foo: '1'
foo.bar: '2'
]])
AT_BISON_CHECK([-o test.c test.y], 0, [],
[[test.y:11.22-29: warning: misleading reference: `$foo.bar'
test.y:11.8-10: warning: refers to: $foo at $1
test.y:11.12-18: warning: possibly meant: $[foo.bar] at $2
]])
AT_CLEANUP
#######################################################################
AT_SETUP([Many kinds of errors])
AT_DATA_GRAMMAR([test.y],
[[
%token IDENT
%token NUMBER
%token ASSIGNOP
%token IF
%token IF1
%token THEN
%token ELSE
%token FI
%token WHILE
%token DO
%token OD
%start program
%%
if_stmt1: IF expr[cond] THEN stmt[then] ELSE stmt.list[else] FI
{ $if_stmt1 = new IfStmt($cond1, $then.f1, $else); };
if_stmt2: IF expr[cond] THEN stmt[then] FI
{ $if_stmt2 = new IfStmt($cond, $stmt.field, 0); };
if_stmt3: IF expr[cond] THEN stmt.list FI
{ $if_stmt3 = new IfStmt($cond, $stmt.list, 0); };
if_stmt4: IF expr[cond] THEN stmt[xyz] ELSE stmt[xyz] FI
{ $if_stmt4 = new IfStmt($cond, $xyz, $cond); };
if_stmt5: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
{ $if_stmt5 = new IfStmt($cond, $stmt.list, $else); };
if_stmt6: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
{ $if_stmt6 = new IfStmt($cond, $stmt.list.field, $else); };
if_stmt7: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
{ $if_stmt7 = new IfStmt($cond, $[stmt.list].field, $else); };
if_stmt8: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
{ $if_stmt8 = new IfStmt($cond, $then.1, $else); };
if_stmt9: IF expr[cond] THEN stmt.list[then.1] ELSE stmt.list[else] FI
{ $if_stmt9 = new IfStmt($cond, $then.1.field, $else); };
if_stmt10: IF expr[cond] THEN stmt[stmt.x] FI
{ $if_stmt10 = new IfStmt($cond, $stmt.x, 0); };
if-stmt-a: IF expr[cond] THEN stmt.list[then] ELSE stmt.list[else] FI
{ $if-stmt-a = new IfStmt($cond, $then, $else); };
if-stmt-b: IF expr[cond] THEN if-stmt-a[then-a] ELSE stmt.list[else] FI
{ $[if-stmt-b] = new IfStmt($cond, $then-a.f, $else); };
program: stmt.list;
stmt.list: stmt ';' stmt.list { $3->insert($stmt); $$ = $3; }
| stmt ';' { SL = new StmtList(); SL->insert($1); $$ = SL; }
;
stmt: assign_stmt { $$ = $1; }
| if_stmt { $$ = $1; }
| if_stmt1 { $$ = $1; }
| while_stmt { $$ = $1; }
;
assign_stmt: IDENT ASSIGNOP expr
{ $$ = new AssignStmt(string($1),$3); };
if_stmt: IF expr[cond] THEN stmt.list FI
{ $if_stmt = new IfStmt($cond, $[stmt.list], 0); };
while_stmt[res]: WHILE expr DO stmt.list OD
{ $res = new WhileStmt($[expr], $[stmt.list]); };
expr: expr '+' term { $$ = new Plus($1,$3); }
| expr '-' term { $$ = new Minus($1,$3); }
| term { $$ = $1; }
;
term: term '*' factor { $$ = new Times($1,$3); }
| factor { $$ = $1; }
;
factor: '(' expr ')' { $$ = $2; }
| NUMBER { $$ = new Number($1); }
| IDENT { $$ = new Ident(string($1)); }
;
]])
AT_BISON_CHECK([-o test.c test.y], 1, [],
[[test.y:24.36-41: invalid reference: `$cond1'
test.y:23.11-24.62: symbol not found in production: cond1
test.y:26.43-53: invalid reference: `$stmt.field'
test.y:25.11-26.60: symbol not found in production: stmt
test.y:25.35-38: possibly meant: $then.field, hiding $stmt.field at $4
test.y:28.43-52: invalid reference: `$stmt.list'
test.y:27.11-28.59: symbol not found in production: stmt
test.y:27.30-38: possibly meant: $[stmt.list] at $4
test.y:30.43-46: ambiguous reference: `$xyz'
test.y:29.35-37: refers to: $xyz at $4
test.y:29.50-52: refers to: $xyz at $6
test.y:32.43-52: invalid reference: `$stmt.list'
test.y:31.11-32.63: symbol not found in production: stmt
test.y:31.40-43: possibly meant: $then, hiding $[stmt.list] at $4
test.y:31.61-64: possibly meant: $else, hiding $[stmt.list] at $6
test.y:34.43-58: invalid reference: `$stmt.list.field'
test.y:33.11-34.69: symbol not found in production: stmt
test.y:33.40-43: possibly meant: $then.field, hiding $[stmt.list].field at $4
test.y:33.61-64: possibly meant: $else.field, hiding $[stmt.list].field at $6
test.y:36.43-54: invalid reference: `$[stmt.list]'
test.y:35.11-36.71: symbol not found in production: stmt.list
test.y:35.40-43: possibly meant: $then, hiding $[stmt.list] at $4
test.y:35.61-64: possibly meant: $else, hiding $[stmt.list] at $6
test.y:38.43-49: invalid reference: `$then.1'
test.y:37.11-38.60: symbol not found in production: then
test.y:37.40-45: possibly meant: $[then.1] at $4
test.y:40.43-55: invalid reference: `$then.1.field'
test.y:39.11-40.66: symbol not found in production: then
test.y:39.40-45: possibly meant: $[then.1].field at $4
test.y:42.44-50: invalid reference: `$stmt.x'
test.y:41.12-42.57: symbol not found in production: stmt
test.y:41.36-41: possibly meant: $[stmt.x].x, hiding $stmt.x at $4
test.y:41.36-41: possibly meant: $[stmt.x] at $4
test.y:44.13-22: invalid reference: `$if-stmt-a'
test.y:43.12-44.59: symbol not found in production: if
test.y:43.1-9: possibly meant: $[if-stmt-a] at $$
test.y:46.46-54: invalid reference: `$then-a.f'
test.y:45.12-46.65: symbol not found in production: then
test.y:45.41-46: possibly meant: $[then-a].f at $4
]])
AT_CLEANUP
#######################################################################
AT_SETUP([Missing identifiers in brackets])
AT_DATA_GRAMMAR([test.y],
[[
%%
start: foo[] bar
{ s = $foo; }
]])
AT_BISON_CHECK([-o test.c test.y], 1, [],
[[test.y:11.12: an identifier expected
]])
AT_CLEANUP
#######################################################################
AT_SETUP([Redundant words in brackets])
AT_DATA_GRAMMAR([test.y],
[[
%%
start: foo[ a d ] bar
{ s = $foo; }
]])
AT_BISON_CHECK([-o test.c test.y], 1, [],
[[test.y:11.15: unexpected identifier in bracketed name: `d'
]])
AT_CLEANUP
#######################################################################
AT_SETUP([Comments in brackets])
AT_DATA_GRAMMAR([test.y],
[[
%%
start: foo[/* comment */] bar
{ s = $foo; }
]])
AT_BISON_CHECK([-o test.c test.y], 1, [],
[[test.y:11.25: an identifier expected
]])
AT_CLEANUP
#######################################################################
AT_SETUP([Stray symbols in brackets])
AT_DATA_GRAMMAR([test.y],
[[
%%
start: foo[ /* aaa */ *&-+ ] bar
{ s = $foo; }
]])
AT_BISON_CHECK([-o test.c test.y], 1, [],
[[test.y:11.23: invalid character in bracketed name: `*'
test.y:11.24: invalid character in bracketed name: `&'
test.y:11.26: invalid character in bracketed name: `+'
]])
AT_CLEANUP
#######################################################################
AT_SETUP([Redundant words in LHS brackets])
AT_DATA_GRAMMAR([test.y],
[[
%%
start[a s]: foo
]])
AT_BISON_CHECK([-o test.c test.y], 1, [],
[[test.y:11.9: unexpected identifier in bracketed name: `s'
]])
AT_CLEANUP
#######################################################################
AT_SETUP([Unresolved references])
AT_DATA_GRAMMAR([test.y],
[[
%%
stat:
sym_a sym_b
{ func($sym.field); }
|
sym_a sym_b
{ func($<aa>sym.field); }
|
sym_a sym_b
{ func($[sym.field]); }
|
sym_a sym_b
{ func($<aa>[sym.field]); }
|
sym_a sym_b
{ func($sym); }
|
sym_a sym_b
{ func($<aa>sym); }
|
sym_a sym_b
{ func($[sym]); }
sym_a sym_b
{ func($<aa>[sym]); }
;
stat1:
sym_a sym_b
{ func($sym-field); }
|
sym_a sym_b
{ func($<aa>sym-field); }
|
sym_a sym_b
{ func($[sym-field]); }
|
sym_a sym_b
{ func($<aa>[sym-field]); }
|
sym_a sym_b
{ func($sym); }
|
sym_a sym_b
{ func($<aa>sym); }
|
sym_a sym_b
{ func($[sym]); }
sym_a sym_b
{ func($<aa>[sym]); }
;
sym_a : 'a';
sym_b : 'b';
]])
AT_BISON_CHECK([-o test.c test.y], 1, [],
[[test.y:13.8-17: invalid reference: `$sym.field'
test.y:12.1-13.21: symbol not found in production: sym
test.y:16.8-21: invalid reference: `$<aa>sym.field'
test.y:15.1-16.25: symbol not found in production: sym
test.y:19.8-19: invalid reference: `$[sym.field]'
test.y:18.1-19.23: symbol not found in production: sym.field
test.y:22.8-23: invalid reference: `$<aa>[sym.field]'
test.y:21.1-22.27: symbol not found in production: sym.field
test.y:25.8-11: invalid reference: `$sym'
test.y:24.1-25.15: symbol not found in production: sym
test.y:28.8-15: invalid reference: `$<aa>sym'
test.y:27.1-28.19: symbol not found in production: sym
test.y:31.8-13: invalid reference: `$[sym]'
test.y:30.1-33.21: symbol not found in production before $3: sym
test.y:33.8-17: invalid reference: `$<aa>[sym]'
test.y:30.1-33.21: symbol not found in production: sym
test.y:37.8-17: invalid reference: `$sym-field'
test.y:36.1-37.21: symbol not found in production: sym
test.y:40.8-21: invalid reference: `$<aa>sym-field'
test.y:39.1-40.25: symbol not found in production: sym
test.y:43.8-19: invalid reference: `$[sym-field]'
test.y:42.1-43.23: symbol not found in production: sym-field
test.y:46.8-23: invalid reference: `$<aa>[sym-field]'
test.y:45.1-46.27: symbol not found in production: sym-field
test.y:49.8-11: invalid reference: `$sym'
test.y:48.1-49.15: symbol not found in production: sym
test.y:52.8-15: invalid reference: `$<aa>sym'
test.y:51.1-52.19: symbol not found in production: sym
test.y:55.8-13: invalid reference: `$[sym]'
test.y:54.1-57.21: symbol not found in production before $3: sym
test.y:57.8-17: invalid reference: `$<aa>[sym]'
test.y:54.1-57.21: symbol not found in production: sym
]])
AT_CLEANUP