AT_SETUP([Symbols])
-# Bison once thought a character token and its alias were different
-# symbols with the same user token number.
-
AT_DATA_GRAMMAR([input.y],
[[%token WITH-DASH
%token WITHOUT_DASH "WITHOUT-DASH"
%token WITH.PERIOD
%token WITHOUT_PERIOD "WITHOUT.PERIOD"
+%code {
+ void yyerror (char const *);
+ int yylex (void);
+}
%%
start: with-dash without_dash with.period without_period;
with-dash: WITH-DASH;
# POSIX Yacc accept periods, but not dashes.
AT_BISON_CHECK([--yacc input.y], [1], [],
[[input.y:9.8-16: POSIX Yacc forbids dashes in symbol names: WITH-DASH
-input.y:14.8-16: POSIX Yacc forbids dashes in symbol names: with-dash
+input.y:18.8-16: POSIX Yacc forbids dashes in symbol names: with-dash
]])
# So warn about them.
AT_BISON_CHECK([-Wyacc input.y], [], [],
[[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: WITH-DASH
-input.y:14.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash
+input.y:18.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash
]])
# Dashes are fine for GNU Bison.
AT_COMPILE([input.o], [-c input.c])
-# Period are genuine letters, they can start identifiers. Dashes
-# and digits can't.
+# Periods and dashes are genuine letters, they can start identifiers.
+# Digits cannot.
AT_DATA_GRAMMAR([input.y],
-[[%token .good
-%token -wrong
-%token 1nv4l1d
+[[%token .GOOD
+ -GOOD
+ 1NV4L1D
%%
-start: .good
+start: .GOOD -GOOD
]])
AT_BISON_CHECK([-o input.c input.y], [1], [],
-[[input.y:10.8: invalid character: `-'
-input.y:11.8: syntax error, unexpected integer, expecting char or identifier or <tag>
+[[input.y:11.10-16: invalid identifier: `1NV4L1D'
+]])
+
+AT_CLEANUP
+
+
+## ----------------- ##
+## Numbered tokens. ##
+## ----------------- ##
+
+AT_SETUP([Numbered tokens])
+
+AT_DATA_GRAMMAR([redecl.y],
+[[%token DECIMAL_1 11259375
+ HEXADECIMAL_1 0xabcdef
+ HEXADECIMAL_2 0xFEDCBA
+ DECIMAL_2 16702650
+%%
+start: DECIMAL_1 HEXADECIMAL_2;
+]])
+
+AT_BISON_CHECK([redecl.y], [1], [],
+[[redecl.y:10.10-22: user token number 11259375 redeclaration for HEXADECIMAL_1
+redecl.y:9.8-16: previous declaration for DECIMAL_1
+redecl.y:12.10-18: user token number 16702650 redeclaration for DECIMAL_2
+redecl.y:11.10-22: previous declaration for HEXADECIMAL_2
+]])
+
+AT_DATA_GRAMMAR([too-large.y],
+[[%token TOO_LARGE_DEC 999999999999999999999
+ TOO_LARGE_HEX 0xFFFFFFFFFFFFFFFFFFF
+%%
+start: TOO_LARGE_DEC TOO_LARGE_HEX
+%%
+]])
+
+AT_BISON_CHECK([too-large.y], [1], [],
+[[too-large.y:9.22-42: integer out of range: `999999999999999999999'
+too-large.y:10.24-44: integer out of range: `0xFFFFFFFFFFFFFFFFFFF'
]])
AT_CLEANUP
AT_SETUP([%define errors])
-AT_DATA([input.y],
+AT_DATA([input-redefined.y],
[[%define var "value1"
%define var "value1"
%define var "value2"
start: ;
]])
-AT_BISON_CHECK([[input.y]], [0], [],
-[[input.y:2.9-11: warning: %define variable `var' redefined
-input.y:1.9-11: warning: previous definition
-input.y:3.10-12: warning: %define variable `var' redefined
-input.y:2.9-11: warning: previous definition
-input.y:1.9-11: warning: %define variable `var' is not used
-input.y:2.9-11: warning: %define variable `var' is not used
-input.y:3.10-12: warning: %define variable `var' is not used
-input.y:4.9-16: warning: %define variable `special1' is not used
-input.y:5.9-16: warning: %define variable `special2' is not used
+AT_BISON_CHECK([[input-redefined.y]], [[1]], [],
+[[input-redefined.y:2.9-11: %define variable `var' redefined
+input-redefined.y:1.9-11: previous definition
+input-redefined.y:3.10-12: %define variable `var' redefined
+input-redefined.y:2.9-11: previous definition
+]])
+
+AT_DATA([input-unused.y],
+[[%define var "value"
+%%
+start: ;
+]])
+
+AT_BISON_CHECK([[input-unused.y]], [[0]], [],
+[[input-unused.y:1.9-11: warning: %define variable `var' is not used
]])
AT_CLEANUP
-## ------------------- ##
-## %define, --define. ##
-## ------------------- ##
+## ----------------------------------- ##
+## %define, --define, --force-define. ##
+## ----------------------------------- ##
-AT_SETUP([%define, --define])
+AT_SETUP([%define, --define, --force-define])
+
+AT_DATA([skel.c],
+[[m4@&t@_divert_push(0)@
+@output(b4_parser_file_name@)@
+[var-dd: ]b4_percent_define_get([[var-dd]])[
+var-ff: ]b4_percent_define_get([[var-ff]])[
+var-dfg: ]b4_percent_define_get([[var-dfg]])[
+var-fd: ]b4_percent_define_get([[var-fd]])
+m4@&t@_divert_pop(0)
+]])
AT_DATA([input.y],
-[[%define var "value1"
+[[%define var-dfg "gram"
+%%
+start: ;
+]])
+
+AT_BISON_CHECK([[-Dvar-dd=cmd-d1 -Dvar-dd=cmd-d2 \
+ -Fvar-ff=cmd-f1 -Fvar-ff=cmd-f2 \
+ -Dvar-dfg=cmd-d -Fvar-dfg=cmd-f \
+ -Fvar-fd=cmd-f -Dvar-fd=cmd-d \
+ -Dunused-d -Funused-f \
+ --skeleton ./skel.c input.y]], [[0]], [],
+[[<command line>:10: warning: %define variable `unused-d' is not used
+<command line>:11: warning: %define variable `unused-f' is not used
+]])
+
+AT_CHECK([[cat input.tab.c]], [[0]],
+[[var-dd: cmd-d2
+var-ff: cmd-f2
+var-dfg: cmd-f
+var-fd: cmd-d
+]])
+
+AT_DATA([input-dg.y],
+[[%define var "gram"
%%
start: ;
]])
-AT_BISON_CHECK([[-DFOO -DFOO -Dvar=value input.y]], [0], [],
-[[<command line>:3: warning: %define variable `FOO' redefined
-<command line>:2: warning: previous definition
-input.y:1.9-11: warning: %define variable `var' redefined
-<command line>:4: warning: previous definition
-<command line>:2: warning: %define variable `FOO' is not used
-<command line>:3: warning: %define variable `FOO' is not used
-<command line>:4: warning: %define variable `var' is not used
-input.y:1.9-11: warning: %define variable `var' is not used
+AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [],
+[[input-dg.y:1.9-11: %define variable `var' redefined
+<command line>:2: previous definition
]])
AT_CLEANUP
AT_CLEANUP
-## ----------------------------------------- ##
-## %define lr.default_rules invalid values. ##
-## ----------------------------------------- ##
+## ------------------------ ##
+## %define enum variables. ##
+## ------------------------ ##
-AT_SETUP([[%define lr.default_rules invalid values]])
+AT_SETUP([[%define enum variables]])
+# Front-end.
AT_DATA([[input.y]],
-[[%define lr.default_rules "bogus"
+[[%define lr.default-reductions "bogus"
%%
start: ;
]])
-
AT_BISON_CHECK([[input.y]], [[1]], [[]],
-[[input.y:1.9-24: invalid value for %define variable `lr.default_rules': `bogus'
+[[input.y:1.9-29: invalid value for %define variable `lr.default-reductions': `bogus'
+input.y:1.9-29: accepted value: `all'
+input.y:1.9-29: accepted value: `consistent'
+input.y:1.9-29: accepted value: `accepting'
+]])
+
+# Back-end.
+AT_DATA([[input.y]],
+[[%define api.push-pull "neither"
+%%
+start: ;
+]])
+AT_BISON_CHECK([[input.y]], [1], [],
+[[input.y:1.9-21: invalid value for %define variable `api.push-pull': `neither'
+input.y:1.9-21: accepted value: `pull'
+input.y:1.9-21: accepted value: `push'
+input.y:1.9-21: accepted value: `both'
]])
AT_CLEANUP
-## ------------------------ ##
-## %define enum variables. ##
-## ------------------------ ##
+## -------------------------------- ##
+## %define backward compatibility. ##
+## -------------------------------- ##
-AT_SETUP([[%define enum variables]])
+AT_SETUP([[%define backward compatibility]])
+
+# The error messages tell us whether underscores in these variables are
+# being converted to dashes.
AT_DATA([[input.y]],
[[%define api.push_pull "neither"
%%
start: ;
]])
+AT_BISON_CHECK([[input.y]], [1], [],
+[[input.y:1.9-21: invalid value for %define variable `api.push-pull': `neither'
+input.y:1.9-21: accepted value: `pull'
+input.y:1.9-21: accepted value: `push'
+input.y:1.9-21: accepted value: `both'
+]])
+
+AT_DATA([[input.y]],
+[[%define lr.keep_unreachable_states "maybe"
+%%
+start: ;
+]])
+AT_BISON_CHECK([[input.y]], [1], [],
+[[input.y:1.9-34: invalid value for %define Boolean variable `lr.keep-unreachable-states'
+]])
+AT_DATA([[input.y]],
+[[%define namespace "foo"
+%define api.namespace "foo"
+%%
+start: ;
+]])
AT_BISON_CHECK([[input.y]], [1], [],
-[[input.y:1.9-21: invalid value for %define variable `api.push_pull': `neither'
+[[input.y:2.9-21: %define variable `api.namespace' redefined
+input.y:1.9-17: previous definition
+]])
+
+AT_DATA([[input.y]],
+[[%define foo_bar "baz"
+%%
+start: ;
+]])
+AT_BISON_CHECK([[input.y]], [0], [],
+[[input.y:1.9-15: warning: %define variable `foo_bar' is not used
]])
AT_CLEANUP
AT_DATA([[input.y]],
[[%language "C++"
%defines
-%define namespace "]$1["
+%define api.namespace "]$1["
%%
start: ;
]])
AT_BISON_CHECK([[input.y]], [1], [],
[m4_foreach([b4_arg], m4_dquote(m4_shift($@)),
-[[input.y:3.9-17: ]b4_arg[
+[[input.y:3.9-21: ]b4_arg[
]])])
])
[[namespace reference has a trailing "::"]])
AT_CLEANUP
+
+## ------------------------ ##
+## Bad character literals. ##
+## ------------------------ ##
+
+# Bison used to accept character literals that were empty or contained
+# too many characters.
+
+# FIXME: $ECHO_N and $ECHO_C are not very portable according to the
+# Autoconf manual. Switch to AS_ECHO_N when Autoconf 2.64 is released?
+# Even better, AT_DATA or some variant of AT_DATA may eventually permit
+# a trailing newline. See the threads starting at
+# <http://lists.gnu.org/archive/html/bison-patches/2009-07/msg00019.html>.
+
+AT_SETUP([[Bad character literals]])
+
+AT_DATA([empty.y],
+[[%%
+start: '';
+start: '
+]])
+echo $ECHO_N "start: '$ECHO_C" >> empty.y
+
+AT_BISON_CHECK([empty.y], [1], [],
+[[empty.y:2.8-9: warning: empty character literal
+empty.y:3.8-4.0: warning: empty character literal
+empty.y:3.8-4.0: missing `'' at end of line
+empty.y:4.8: warning: empty character literal
+empty.y:4.8: missing `'' at end of file
+]])
+
+AT_DATA([two.y],
+[[%%
+start: 'ab';
+start: 'ab
+]])
+echo $ECHO_N "start: 'ab$ECHO_C" >> two.y
+
+AT_BISON_CHECK([two.y], [1], [],
+[[two.y:2.8-11: warning: extra characters in character literal
+two.y:3.8-4.0: warning: extra characters in character literal
+two.y:3.8-4.0: missing `'' at end of line
+two.y:4.8-10: warning: extra characters in character literal
+two.y:4.8-10: missing `'' at end of file
+]])
+
+AT_DATA([three.y],
+[[%%
+start: 'abc';
+start: 'abc
+]])
+echo $ECHO_N "start: 'abc$ECHO_C" >> three.y
+
+AT_BISON_CHECK([three.y], [1], [],
+[[three.y:2.8-12: warning: extra characters in character literal
+three.y:3.8-4.0: warning: extra characters in character literal
+three.y:3.8-4.0: missing `'' at end of line
+three.y:4.8-11: warning: extra characters in character literal
+three.y:4.8-11: missing `'' at end of file
+]])
+
+AT_CLEANUP
+
+## ------------------------- ##
+## Bad escapes in literals. ##
+## ------------------------- ##
+
+AT_SETUP([[Bad escapes in literals]])
+
+AT_DATA([input.y],
+[[%%
+start: '\777' '\0' '\xfff' '\x0'
+ '\uffff' '\u0000' '\Uffffffff' '\U00000000'
+ '\ ' '\A';
+]])
+echo 'start: "\T\F\0\1" ;' | tr 'TF01' '\011\014\0\1' >> input.y
+
+AT_BISON_CHECK([input.y], [1], [],
+[[input.y:2.9-12: invalid number after \-escape: 777
+input.y:2.8-13: warning: empty character literal
+input.y:2.16-17: invalid number after \-escape: 0
+input.y:2.15-18: warning: empty character literal
+input.y:2.21-25: invalid number after \-escape: xfff
+input.y:2.20-26: warning: empty character literal
+input.y:2.29-31: invalid number after \-escape: x0
+input.y:2.28-32: warning: empty character literal
+input.y:3.9-14: invalid number after \-escape: uffff
+input.y:3.8-15: warning: empty character literal
+input.y:3.18-23: invalid number after \-escape: u0000
+input.y:3.17-24: warning: empty character literal
+input.y:3.27-36: invalid number after \-escape: Uffffffff
+input.y:3.26-37: warning: empty character literal
+input.y:3.40-49: invalid number after \-escape: U00000000
+input.y:3.39-50: warning: empty character literal
+input.y:4.9-10: invalid character after \-escape: ` '
+input.y:4.8-11: warning: empty character literal
+input.y:4.14-15: invalid character after \-escape: A
+input.y:4.13-16: warning: empty character literal
+input.y:5.9-16: invalid character after \-escape: \t
+input.y:5.17: invalid character after \-escape: \f
+input.y:5.18: invalid character after \-escape: \0
+input.y:5.19: invalid character after \-escape: \001
+]])
+
+AT_CLEANUP