# Value type. -*- Autotest -*-
-# Copyright (C) 2013 Free Software Foundation, Inc.
+# Copyright (C) 2013-2015 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
AT_DATA([[input.y]],
[[%union { int ival; }
-%define api.value.type "%union"
+%define api.value.type union-directive
%%
exp: %empty;
]])
AT_CLEANUP
+## ---------------------------------------- ##
+## %yacc vs. %define api.value.type union. ##
+## ---------------------------------------- ##
+
+AT_SETUP([[%yacc vs. %define api.value.type union]])
+
+AT_DATA([[input.y]],
+[[%yacc
+%define api.value.type union
+%%
+exp: %empty;
+]])
+
+AT_BISON_CHECK([[input.y]], [[1]], [[]],
+[[input.y:2.9-22: error: '%yacc' and '%define api.value.type "union"' cannot be used together
+]])
+
+AT_CLEANUP
+
+
## ---------------- ##
## api.value.type. ##
## ---------------- ##
-# AT_TEST($1: BISON-DIRECTIVES,
-# $2: MORE-BISON-DIRECTIVES,
-# $3: PARSER-ACTION,
-# $4: INPUT, $5: SCANNER-ACTION,
-# $6: RESULT)
+# _AT_TEST($1: BISON-DIRECTIVES,
+# $2: MORE-BISON-DIRECTIVES,
+# $3: PARSER-ACTION,
+# $4: INPUT,
+# $5: SCANNER-ACTION,
+# $6: RESULT)
# --------------------------------------
# Compile the grammar and check the expected result.
# BISON-DIRECTIVES are passed to AT_SETUP, contrary to MORE-BISON-DIRECTIVES.
-m4_pushdef([AT_TEST],
+m4_pushdef([_AT_TEST],
[
AT_SETUP([$1])
AT_KEYWORDS([api.value.type])
AT_CLEANUP
])
+# AT_TEST($1: BISON-DIRECTIVES,
+# $2: MORE-BISON-DIRECTIVES,
+# $3: PARSER-ACTION,
+# $4: INPUT,
+# $5: SCANNER-ACTION,
+# $6: RESULT)
+# --------------------------------------
+# Check with and without %defines, to avoid regressions. It turns out
+# that in that case yacc.c calls the set-up of the %union twice,
+# because YYSTYPE is defined once in the header, and once in the
+# implementation file (eventually it'd be better to include the header
+# file, but that's another story). Unfortunately running these macros
+# a second time doubled the side-effects and resulted in a double
+# definition of the union members.
+m4_pushdef([AT_TEST],
+[_AT_TEST([$1], [$2], [$3], [$4], [$5], [$6])
+ _AT_TEST([$1 %defines], [$2], [$3], [$4], [$5], [$6])
+])
+
m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc]],
[# A built-in type.
AT_TEST([%skeleton "]b4_skel["
- %define api.value.type double],
+ %define api.value.type {double}],
[],
['1' '2' { printf ("%2.1f\n", $1 + $2); }],
["12"],
[AT_VAL = (res - '0') / 10.0],
[0.3])
+ # A typedef which looks like a Bison keyword, but it's using braces.
+ AT_TEST([%skeleton "]b4_skel["
+ %define api.value.type {variant}],
+ [%code requires { typedef double variant; }],
+ ['1' '2' { printf ("%2.1f\n", $1 + $2); }],
+ ["12"],
+ [AT_VAL = (res - '0') / 10.0],
+ [0.3])
+
# A user defined struct.
AT_TEST([%skeleton "]b4_skel["
- %define api.value.type "struct foo"],
+ %define api.value.type {struct foo}],
[%code requires { struct foo { float fval; int ival; }; }],
['1' '2'
{ printf ("%d %2.1f\n", $1.ival + $2.ival, $1.fval + $2.fval); }],
# A user defined struct that uses pointers.
AT_TEST([%skeleton "]b4_skel["
- %define api.value.type "struct bar"],
+ %define api.value.type {struct bar}],
[%code requires
{
struct u
# A user defined union.
AT_TEST([%skeleton "]b4_skel["
- %define api.value.type "union foo"],
+ %define api.value.type {union foo}],
[%code requires { union foo { float fval; int ival; }; }],
['1' '2' { printf ("%d %2.1f\n", $1.ival, $2.fval); }],
["12"],
AT_VAL.fval = .2f],
[10 0.2])
- # A %union.
- AT_TEST([%skeleton "]b4_skel["
- %union { float fval; int ival; };],
- [%token <ival> '1';
- %token <fval> '2';],
- ['1' '2' { printf ("%d %2.1f\n", $1, $2); }],
- ["12"],
- [if (res == '1')
- AT_VAL.ival = 10;
- else
- AT_VAL.fval = 0.2f],
- [10 0.2])
+ # A %union and a named %union. In C++ named %union is an error.
+ m4_foreach([b4_union],
+ [m4_bmatch(b4_skel, [\.cc$],
+ [[%union]],
+ [[%union], [%union foo],
+ [%define api.value.union.name foo; %union]])],
+ [AT_TEST([%skeleton "]b4_skel["
+ ]b4_union[ { float fval; int ival; };],
+ [%token <ival> '1';
+ %token <fval> '2';],
+ ['1' '2' { printf ("%d %2.1f\n", $1, $2); }],
+ ["12"],
+ [if (res == '1')
+ AT_VAL.ival = 10;
+ else
+ AT_VAL.fval = 0.2f],
+ [10 0.2])])
# A Bison-defined union.
# The tokens names are not available directly in C++, we use their
])
m4_popdef([AT_TEST])
+m4_popdef([_AT_TEST])
+
+
+## ------------------- ##
+## C++: Named %union. ##
+## ------------------- ##
+
+m4_foreach([b4_skel], [[lalr1.cc], [glr.cc]],
+[AT_SETUP([b4_skel: Named %union])
+AT_DATA([input.y],
+[%skeleton "]b4_skel["
+%union foo { float fval; int ival; };
+%%
+exp: %empty;
+])
+AT_BISON_CHECK([input.y], 1, [],
+[[input.y:2.8-10: error: named %union is invalid in C++
+]])
+AT_CLEANUP
+])