mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 20:33:03 +00:00
Previously, for this special case of an invalid reference, the
usual "symbol not found in production:" was printed. However,
because the symbol name was parsed as the empty string, that
message was followed immediately by a newline instead of a symbol
name. In reality, this is a syntax error, so the reference is
invalid regardless of the symbols actually appearing in the
production. Discussed at
<http://lists.gnu.org/archive/html/bison-patches/2011-01/msg00012.html>.
* src/scan-code.l (parse_ref): Report the above case as a syntax
error. Other than that, continue to handle this case like any
other invalid reference that Bison manages to parse because
"possibly meant" messages can still be helpful to the user.
* tests/named-refs.at ($ or @ followed by . or -): New test group.
(cherry picked from commit 5c9efc755e)
593 lines
16 KiB
Plaintext
593 lines
16 KiB
Plaintext
# Named references test. -*- Autotest -*-
|
|
|
|
# Copyright (C) 2009-2011 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
|
|
|
|
#######################################################################
|
|
|
|
AT_SETUP([[$ or @ followed by . or -]])
|
|
AT_DATA([[test.y]],
|
|
[[
|
|
%%
|
|
start:
|
|
.field { $.field; }
|
|
| -field { @-field; }
|
|
| 'a' { @.field; }
|
|
| 'a' { $-field; }
|
|
;
|
|
.field: ;
|
|
-field: ;
|
|
]])
|
|
AT_BISON_CHECK([[test.y]], [[1]], [],
|
|
[[test.y:4.12-18: invalid reference: `$.field'
|
|
test.y:4.13: syntax error after `$', expecting integer, letter, `_', `@<:@', or `$'
|
|
test.y:4.3-8: possibly meant: $[.field] at $1
|
|
test.y:5.12-18: invalid reference: `@-field'
|
|
test.y:5.13: syntax error after `@', expecting integer, letter, `_', `@<:@', or `$'
|
|
test.y:5.3-8: possibly meant: @[-field] at $1
|
|
test.y:6.12-18: invalid reference: `@.field'
|
|
test.y:6.13: syntax error after `@', expecting integer, letter, `_', `@<:@', or `$'
|
|
test.y:7.12-18: invalid reference: `$-field'
|
|
test.y:7.13: syntax error after `$', expecting integer, letter, `_', `@<:@', or `$'
|
|
]])
|
|
AT_CLEANUP
|