From: Akim Demaille Date: Tue, 26 Jun 2012 14:43:22 +0000 (+0200) Subject: Merge remote-tracking branch 'origin/maint' X-Git-Tag: v2.7.90~419 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/297e263a0050959e0fd139ad66e71383fc9ac4db?hp=-c Merge remote-tracking branch 'origin/maint' * origin/maint: tests: do not output m4 set up. tests: use the generic yyerror function. tests: use assert instead of plain abort. tests: improve the generic yylex implementation. tests: generalize the compilation macros. tests: fix confusion between api.prefix and name-prefix. maint: gitignores. yacc: work around the ylwrap limitation. Conflicts: NEWS tests/local.at --- 297e263a0050959e0fd139ad66e71383fc9ac4db diff --combined NEWS index 28654769,10829f54..41e68519 --- a/NEWS +++ b/NEWS @@@ -2,130 -2,33 +2,144 @@@ GNU Bison NEW * Noteworthy changes in release ?.? (????-??-??) [?] +** Warnings about useless semantic types + + Bison now warns about useless (uninhabited) semantic types. Since + semantic types are not declared to Bison (they are defined in the opaque + %union structure), it is %printer/%destructor directives about useless + types that trigger the warning: + + %token term + %type nterm + %printer {} + %destructor {} + %% + nterm: term { $$ = $1; }; + + 3.28-34: warning: type is used, but is not associated to any symbol + 4.28-34: warning: type is used, but is not associated to any symbol + +** Warnings about undeclared symbols + + Bison used to raise an error for %printer and %destructor directives for + undefined symbols. + + %printer {} symbol1 + %destructor {} symbol2 + %% + exp: "a"; + + This is now only a warning. + +** Warnings about useless destructors or printers + + Bison now warns about useless destructors or printers. In the following + example, the printer for , and the destructor for are + useless: all symbols of (token1) already have a printer, and all + symbols of type (token2) already have a destructor. + + %token token1 + token2 + token3 + token4 + %printer {} token1 + %destructor {} token2 + +** Additional yylex/yyparse arguments + + The new directive %param declares additional arguments to both yylex and + yyparse. The %lex-param, %parse-param, and %param directives support one + or more arguments. Instead of + + %lex-param {arg1_type *arg1} + %lex-param {arg2_type *arg2} + %parse-param {arg1_type *arg1} + %parse-param {arg2_type *arg2} + + one may now declare + + %param {arg1_type *arg1} {arg2_type *arg2} + +** Java skeleton improvements + + The constants for token names were moved to the Lexer interface. + Also, it is possible to add code to the parser's constructors using + "%code init" and "%define init_throws". + +** C++ skeleton improvements + + The C++ parser features a syntax_error exception, which can be + thrown from the scanner or from user rules to raise syntax errors. + This facilitates reporting errors caught in sub-functions (e.g., + rejecting too large integral literals from a conversion function + used by the scanner, or rejecting invalid combinations from a + factory invoked by the user actions). + +** Variable api.tokens.prefix + + The variable api.tokens.prefix changes the way tokens are identified in + the generated files. This is especially useful to avoid collisions + with identifiers in the target language. For instance + + %token FILE for ERROR + %define api.tokens.prefix "TOK_" + %% + start: FILE for ERROR; + + will generate the definition of the symbols TOK_FILE, TOK_for, and + TOK_ERROR in the generated sources. In particular, the scanner must + use these prefixed token names, although the grammar itself still + uses the short names (as in the sample rule given above). + +** Variable api.namespace + + The "namespace" variable is renamed "api.namespace". Backward + compatibility is ensured, but upgrading is recommended. + +** Variable parse.error + + The variable error controls the verbosity of error messages. The + use of the %error-verbose directive is deprecated in favor of + %define parse.error "verbose". + +** Semantic predicates + + The new, experimental, semantic-predicate feature allows actions of + the form %?{ BOOLEAN-EXPRESSION }, which cause syntax errors (as for + YYERROR) if the expression evaluates to 0, and are evaluated immediately + in GLR parsers, rather than being deferred. The result is that they + allow the programmer to prune possible parses based on the values of + runtime expressions. + +* Noteworthy changes in release ?.? (????-??-??) [?] + - ** Future changes: + ** Future changes + + The next major release of Bison will drop support for the following + deprecated features. Please report disagreements to bug-bison@gnu.org. + + *** K&C parsers + + Support for generating parsers in K&R C will be removed. Parsers + generated for C supprt ISO C90, and are tested with ISO C99 and ISO C11 + compilers. + + *** Deprecated features - The next major release will drop support for generating parsers in K&R C, - and remove the definitions of yystype and yyltype (removal announced since - Bison 1.875). YYPARSE_PARAM and YYLEX_PARAM, which were deprecated in - favor of %parse-param and %lex-param (introduced in Bison 1.875 too), will - no longer be supported. + The definitions of yystype and yyltype will be removed, as announced since + Bison 1.875. Use YYSTYPE and YYLTYPE only. - ** The generated header is included (yacc.c) + YYPARSE_PARAM and YYLEX_PARAM, which were deprecated in favor of + %parse-param and %lex-param (introduced in Bison 1.875), will no longer be + supported. + + *** The generated header will be included (yacc.c) Instead of duplicating the content of the generated header (definition of - YYSTYPE, yyltype etc.), the generated parser now includes it, as was - already the case for GLR or C++ parsers. + YYSTYPE, yyparse declaration etc.), the generated parser will include it, + as is already the case for GLR or C++ parsers. This change is deferred + because existing versions of ylwrap (e.g., Automake 1.12.1) do not support + it. ** Headers (yacc.c, glr.c, glr.cc) @@@ -191,10 -94,10 +205,10 @@@ The header files such as "parser.hh", "location.hh", etc. used a constant name for preprocessor guards, for instance: - #ifndef BISON_LOCATION_HH - # define BISON_LOCATION_HH - ... - #endif // !BISON_LOCATION_HH + #ifndef BISON_LOCATION_HH + # define BISON_LOCATION_HH + ... + #endif // !BISON_LOCATION_HH The inclusion guard is now computed from "PREFIX/FILE-NAME", where lower case characters are converted to upper case, and series of @@@ -202,10 -105,10 +216,10 @@@ With "bison -o lang++/parser.cc", "location.hh" would now include: - #ifndef YY_LANG_LOCATION_HH - # define YY_LANG_LOCATION_HH - ... - #endif // !YY_LANG_LOCATION_HH + #ifndef YY_LANG_LOCATION_HH + # define YY_LANG_LOCATION_HH + ... + #endif // !YY_LANG_LOCATION_HH *** C++ locations: @@@ -436,33 -339,33 +450,33 @@@ to use it. If, for instance, your location structure has "first" and "last" members, instead of - # define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (N) \ - { \ - (Current).first = (Rhs)[1].location.first; \ - (Current).last = (Rhs)[N].location.last; \ - } \ - else \ - { \ - (Current).first = (Current).last = (Rhs)[0].location.last; \ - } \ - while (false) + # define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).first = (Rhs)[1].location.first; \ + (Current).last = (Rhs)[N].location.last; \ + } \ + else \ + { \ + (Current).first = (Current).last = (Rhs)[0].location.last; \ + } \ + while (false) use: - # define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (N) \ - { \ - (Current).first = YYRHSLOC (Rhs, 1).first; \ - (Current).last = YYRHSLOC (Rhs, N).last; \ - } \ - else \ - { \ - (Current).first = (Current).last = YYRHSLOC (Rhs, 0).last; \ - } \ - while (false) + # define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).first = YYRHSLOC (Rhs, 1).first; \ + (Current).last = YYRHSLOC (Rhs, N).last; \ + } \ + else \ + { \ + (Current).first = (Current).last = YYRHSLOC (Rhs, 0).last; \ + } \ + while (false) ** YYLLOC_DEFAULT in C++: @@@ -1462,9 -1365,9 +1476,9 @@@ ** Incorrect "Token not used" On a grammar such as - %token useless useful - %% - exp: '0' %prec useful; + %token useless useful + %% + exp: '0' %prec useful; where a token was used to set the precedence of the last rule, bison reported both "useful" and "useless" as useless tokens. @@@ -1483,9 -1386,9 +1497,9 @@@ the user symbol is used in the reports, the graphs, and the verbose error messages instead of "$end", which remains being the default. For instance - %token MYEOF 0 + %token MYEOF 0 or - %token MYEOF 0 "end of file" + %token MYEOF 0 "end of file" ** Semantic parser This old option, which has been broken for ages, is removed. @@@ -1521,9 -1424,9 +1535,9 @@@ Previous versions don't complain when there is a type clash on the default action if the rule has a mid-rule action, such as in: - %type bar - %% - bar: '0' {} '0'; + %type bar + %% + bar: '0' {} '0'; This is fixed. diff --combined data/yacc.c index 0c442ae0,57f3dace..b57794f0 --- a/data/yacc.c +++ b/data/yacc.c @@@ -1,12 -1,10 +1,12 @@@ -*- C -*- - # Yacc compatible skeleton for Bison # Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, # Inc. +m4_pushdef([b4_copyright_years], + [1984, 1989-1990, 2000-2012]) + # 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 @@@ -76,8 -74,8 +76,8 @@@ m4_define([b4_pure_flag] # Expand IF-TRUE, if %pure-parser and %parse-param, IF-FALSE otherwise. m4_define([b4_yacc_pure_if], [b4_pure_if([m4_ifset([b4_parse_param], - [$1], [$2])], - [$2])]) + [$1], [$2])], + [$2])]) # b4_yyerror_args @@@ -117,7 -115,7 +117,7 @@@ m4_define([b4_int_type] m4_eval([0 <= $1]), [1], [unsigned int], - [int])]) + [int])]) ## ----------------- ## @@@ -129,7 -127,7 +129,7 @@@ # -------------------- # Expansion of $$. m4_define([b4_lhs_value], -[(yyval[]m4_ifval([$1], [.$1]))]) +[b4_symbol_value(yyval, [$1])]) # b4_rhs_value(RULE-LENGTH, NUM, [TYPE]) @@@ -137,7 -135,7 +137,7 @@@ # Expansion of $NUM, where the current rule has RULE-LENGTH # symbols on RHS. m4_define([b4_rhs_value], -[(yyvsp@{($2) - ($1)@}m4_ifval([$3], [.$3]))]) + [b4_symbol_value([yyvsp@{b4_subtract([$2], [$1])@}], [$3])]) @@@ -157,7 -155,7 +157,7 @@@ m4_define([b4_lhs_location] # Expansion of @NUM, where the current rule has RULE-LENGTH symbols # on RHS. m4_define([b4_rhs_location], -[(yylsp@{($2) - ($1)@})]) + [(yylsp@{b4_subtract([$2], [$1])@})]) ## -------------- ## @@@ -229,6 -227,8 +229,8 @@@ m4_define([b4_declare_parser_state_vari # b4_declare_yyparse_push_ # ------------------------ + # Declaration of yyparse (and dependencies) when using the push parser + # (including in pull mode). m4_define([b4_declare_yyparse_push_], [[typedef struct ]b4_prefix[pstate ]b4_prefix[pstate; enum { YYPUSH_MORE = 4 }; @@@ -274,12 -274,14 +276,14 @@@ m4_define([b4_declare_yyparse] # Declaration that might either go into the header (if --defines) # or open coded in the parser body. m4_define([b4_shared_declarations], - [b4_declare_yydebug[ + [b4_cpp_guard_open([b4_spec_defines_file])[ + ]b4_declare_yydebug[ ]b4_percent_code_get([[requires]])[ ]b4_token_enums_defines(b4_tokens)[ ]b4_declare_yylstype[ ]b4_declare_yyparse[ - ]b4_percent_code_get([[provides]])[]dnl + ]b4_percent_code_get([[provides]])[ + ]b4_cpp_guard_close([b4_spec_defines_file])[]dnl ]) ## -------------- ## @@@ -290,7 -292,8 +294,7 @@@ m4_changecom() m4_divert_push(0)dnl @output(b4_parser_file_name@)@ -b4_copyright([Bison implementation for Yacc-like parsers in C], - [1984, 1989-1990, 2000-2012])[ +b4_copyright([Bison implementation for Yacc-like parsers in C])[ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ @@@ -330,7 -333,7 +334,7 @@@ m4_if(b4_prefix, [yy], [] # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else -# define YYERROR_VERBOSE ]b4_error_verbose_flag[ +# define YYERROR_VERBOSE ]b4_error_verbose_if([1], [0])[ #endif /* Enabling the token table. */ @@@ -338,8 -341,9 +342,9 @@@ # define YYTOKEN_TABLE ]b4_token_table[ #endif - ]b4_defines_if([[#include "@basename(]b4_spec_defines_file[@)"]], - [b4_shared_declarations])[ + /* In a future release of Bison, this section will be replaced + by #include "@basename(]b4_spec_defines_file[@)". */ + ]b4_shared_declarations[ /* Copy the second part of user declarations. */ ]b4_user_post_prologue @@@ -466,7 -470,7 +471,7 @@@ b4_push_if([], [b4_lac_if([], [ # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) + && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 @@@ -491,8 -495,8 +496,8 @@@ void free (void *); /* INFRINGES ON USE #if (! defined yyoverflow \ && (! defined __cplusplus \ - || (]b4_locations_if([[defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && ]])[defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + || (]b4_locations_if([[defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ + && ]])[defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc @@@ -522,15 -526,15 +527,15 @@@ elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ while (YYID (0)) #endif @@@ -566,27 -570,41 +571,27 @@@ #define YYNNTS ]b4_nterms_number[ /* YYNRULES -- Number of rules. */ #define YYNRULES ]b4_rules_number[ -/* YYNRULES -- Number of states. */ +/* YYNSTATES -- Number of states. */ #define YYNSTATES ]b4_states_number[ -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned + by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK ]b4_undef_token_number[ #define YYMAXUTOK ]b4_user_token_number_max[ -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, without out-of-bounds checking. */ static const ]b4_int_type_for([b4_translate])[ yytranslate[] = { ]b4_translate[ }; #if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const ]b4_int_type_for([b4_prhs])[ yyprhs[] = -{ - ]b4_prhs[ -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const ]b4_int_type_for([b4_rhs])[ yyrhs[] = -{ - ]b4_rhs[ -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const ]b4_int_type_for([b4_rline])[ yyrline[] = -{ - ]b4_rline[ -}; +]b4_integral_parser_table_define([rline], [b4_rline], + [YYRLINE[YYN] -- Source line where rule number YYN was defined.])[ #endif #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE @@@ -599,34 -617,89 +604,34 @@@ static const char *const yytname[] #endif # ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ static const ]b4_int_type_for([b4_toknum])[ yytoknum[] = { ]b4_toknum[ }; # endif -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const ]b4_int_type_for([b4_r1])[ yyr1[] = -{ - ]b4_r1[ -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const ]b4_int_type_for([b4_r2])[ yyr2[] = -{ - ]b4_r2[ -}; - -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const ]b4_int_type_for([b4_defact])[ yydefact[] = -{ - ]b4_defact[ -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const ]b4_int_type_for([b4_defgoto])[ yydefgoto[] = -{ - ]b4_defgoto[ -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ #define YYPACT_NINF ]b4_pact_ninf[ -static const ]b4_int_type_for([b4_pact])[ yypact[] = -{ - ]b4_pact[ -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const ]b4_int_type_for([b4_pgoto])[ yypgoto[] = -{ - ]b4_pgoto[ -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF ]b4_table_ninf[ -static const ]b4_int_type_for([b4_table])[ yytable[] = -{ - ]b4_table[ -}; #define yypact_value_is_default(yystate) \ ]b4_table_value_equals([[pact]], [[yystate]], [b4_pact_ninf])[ +#define YYTABLE_NINF ]b4_table_ninf[ + #define yytable_value_is_error(yytable_value) \ ]b4_table_value_equals([[table]], [[yytable_value]], [b4_table_ninf])[ -static const ]b4_int_type_for([b4_check])[ yycheck[] = -{ - ]b4_check[ -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const ]b4_int_type_for([b4_stos])[ yystos[] = -{ - ]b4_stos[ -}; +]b4_parser_tables_define[ -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab /* Like YYERROR except do call yyerror. This remains here temporarily @@@ -636,7 -709,7 +641,7 @@@ in Bison 2.4.2's NEWS entry, where a plan to phase it out is discussed. */ -#define YYFAIL goto yyerrlab +#define YYFAIL goto yyerrlab #if defined YYFAIL /* This is here to suppress warnings from the GCC cpp's -Wunused-macros. Normally we don't worry about that warning, but @@@ -660,13 -733,13 +665,13 @@@ d else \ { \ yyerror (]b4_yyerror_args[YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ + YYERROR; \ + } \ while (YYID (0)) -#define YYTERROR 1 -#define YYERRCODE 256 +#define YYTERROR 1 +#define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. @@@ -675,22 -748,22 +680,22 @@@ #define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ while (YYID (0)) #endif]b4_locations_if([[ @@@ -701,10 -774,10 +706,10 @@@ #ifndef YY_LOCATION_PRINT # if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) # else # define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif @@@ -734,21 -807,21 +739,21 @@@ # define YYFPRINTF fprintf # endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ } while (YYID (0)) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value]b4_locations_if([, Location])[]b4_user_args[); \ - YYFPRINTF (stderr, "\n"); \ - } \ +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value]b4_locations_if([, Location])[]b4_user_args[); \ + YYFPRINTF (stderr, "\n"); \ + } \ } while (YYID (0)) ]b4_yy_symbol_print_generate([b4_c_function_def])[ @@@ -759,8 -832,8 +764,8 @@@ `------------------------------------------------------------------*/ ]b4_c_function_def([yy_stack_print], [static void], - [[yytype_int16 *yybottom], [yybottom]], - [[yytype_int16 *yytop], [yytop]])[ + [[yytype_int16 *yybottom], [yybottom]], + [[yytype_int16 *yytop], [yytop]])[ { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) @@@ -771,10 -844,10 +776,10 @@@ YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ } while (YYID (0)) @@@ -783,34 -856,32 +788,34 @@@ `------------------------------------------------*/ ]b4_c_function_def([yy_reduce_print], [static void], - [[YYSTYPE *yyvsp], [yyvsp]], + [[yytype_int16 *yyssp], [yyssp]], + [[YYSTYPE *yyvsp], [yyvsp]], b4_locations_if([[[YYLTYPE *yylsp], [yylsp]], - ])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [, - b4_parse_param]))[ + ])[[int yyrule], [yyrule]]m4_ifset([b4_parse_param], [, + b4_parse_param]))[ { + unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; - unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); + yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &]b4_rhs_value(yynrhs, yyi + 1)[ - ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl - b4_user_args[); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &]b4_rhs_value(yynrhs, yyi + 1)[ + ]b4_locations_if([, &]b4_rhs_location(yynrhs, yyi + 1))[]dnl + b4_user_args[); YYFPRINTF (stderr, "\n"); } } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, ]b4_locations_if([yylsp, ])[Rule]b4_user_args[); \ +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, ]b4_locations_if([yylsp, ])[Rule]b4_user_args[); \ } while (YYID (0)) /* Nonzero means print parse trace. It is left uninitialized so that @@@ -825,7 -896,7 +830,7 @@@ int yydebug /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH ]b4_stack_depth_init[ #endif @@@ -1132,27 -1203,27 +1137,27 @@@ yytnamerr (char *yyres, const char *yys char const *yyp = yystr; for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } do_not_strip_quotes: ; } @@@ -1547,26 -1618,26 +1552,26 @@@ m4_ifdef([b4_at_dollar_used], [[ yylsp #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss;]b4_locations_if([ - YYLTYPE *yyls1 = yyls;])[ - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp),]b4_locations_if([ - &yyls1, yysize * sizeof (*yylsp),])[ - &yystacksize); + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss;]b4_locations_if([ + YYLTYPE *yyls1 = yyls;])[ + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp),]b4_locations_if([ + &yyls1, yysize * sizeof (*yylsp),])[ + &yystacksize); ]b4_locations_if([ - yyls = yyls1;])[ - yyss = yyss1; - yyvs = yyvs1; + yyls = yyls1;])[ + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@@ -1574,23 -1645,23 +1579,23 @@@ # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; + goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([ - YYSTACK_RELOCATE (yyls_alloc, yyls);])[ + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs);]b4_locations_if([ + YYSTACK_RELOCATE (yyls_alloc, yyls);])[ # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ @@@ -1600,10 -1671,10 +1605,10 @@@ yylsp = yyls + yysize - 1;])[ YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@@ -1839,20 -1910,20 +1844,20 @@@ yyerrlab if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + error, discard it. */ if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } else - { - yydestruct ("Error: discarding", - yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[); - yychar = YYEMPTY; - } + { + yydestruct ("Error: discarding", + yytoken, &yylval]b4_locations_if([, &yylloc])[]b4_user_args[); + yychar = YYEMPTY; + } } /* Else will try to reuse lookahead token after shifting the error @@@ -1885,29 -1956,29 +1890,29 @@@ yyerrorlab | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; ]b4_locations_if([[ yyerror_range[1] = *yylsp;]])[ yydestruct ("Error: popping", - yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[); + yystos[yystate], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); @@@ -1972,7 -2043,7 +1977,7 @@@ yyreturn while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[); + yystos[*yyssp], yyvsp]b4_locations_if([, yylsp])[]b4_user_args[); YYPOPSTACK (1); } #ifndef yyoverflow @@@ -1992,14 -2063,13 +1997,12 @@@ yypushreturn:]]) return YYID (yyresult); } - -]b4_epilogue +]b4_epilogue[]dnl b4_defines_if( [@output(b4_spec_defines_file@)@ -b4_copyright([Bison interface for Yacc-like parsers in C], - [1984, 1989-1990, 2000-2012])[ +b4_copyright([Bison interface for Yacc-like parsers in C])[ - ]b4_cpp_guard_open([b4_spec_defines_file])[ ]b4_shared_declarations[ - ]b4_cpp_guard_close([b4_spec_defines_file])[ ]])dnl b4_defines_if m4_divert_pop(0) +m4_popdef([b4_copyright_years]) diff --combined src/symtab.c index c65bd201,002f6e37..124da372 --- a/src/symtab.c +++ b/src/symtab.c @@@ -33,7 -33,6 +33,7 @@@ `-------------------------------------------------------------------*/ static symbol **symbols_sorted = NULL; +static symbol **semantic_types_sorted = NULL; /*------------------------. | Distinguished symbols. | @@@ -50,16 -49,10 +50,16 @@@ location startsymbol_location | Default %destructor's and %printer's. | `---------------------------------------*/ -static code_props default_tagged_destructor = CODE_PROPS_NONE_INIT; -static code_props default_tagless_destructor = CODE_PROPS_NONE_INIT; -static code_props default_tagged_printer = CODE_PROPS_NONE_INIT; -static code_props default_tagless_printer = CODE_PROPS_NONE_INIT; +static code_props default_tagged_code_props[CODE_PROPS_SIZE] = + { + CODE_PROPS_NONE_INIT, + CODE_PROPS_NONE_INIT, + }; +static code_props default_tagless_code_props[CODE_PROPS_SIZE] = + { + CODE_PROPS_NONE_INIT, + CODE_PROPS_NONE_INIT, + }; /*---------------------------------. | Create a new symbol, named TAG. | @@@ -74,7 -67,7 +74,7 @@@ symbol_new (uniqstr tag, location loc /* If the tag is not a string (starts with a double quote), check that it is valid for Yacc. */ - if (tag[0] != '\"' && tag[0] != '\'' && mbschr (tag, '-')) + if (tag[0] != '\"' && tag[0] != '\'' && strchr (tag, '-')) yacc_at (loc, _("POSIX Yacc forbids dashes in symbol names: %s"), tag); @@@ -82,8 -75,8 +82,8 @@@ res->location = loc; res->type_name = NULL; - code_props_none_init (&res->destructor); - code_props_none_init (&res->printer); + for (int i = 0; i < CODE_PROPS_SIZE; ++i) + code_props_none_init (&res->props[i]); res->number = NUMBER_UNDEFINED; res->prec = 0; @@@ -92,43 -85,28 +92,43 @@@ res->alias = NULL; res->class = unknown_sym; - res->declared = false; + res->status = undeclared; if (nsyms == SYMBOL_NUMBER_MAXIMUM) fatal (_("too many symbols in input grammar (limit is %d)"), - SYMBOL_NUMBER_MAXIMUM); + SYMBOL_NUMBER_MAXIMUM); nsyms++; return res; } +char const * +code_props_type_string (code_props_type kind) +{ + switch (kind) + { + case destructor: + return "%destructor"; + case printer: + return "%printer"; + } + assert (0); +} + /*----------------------------------------. | Create a new semantic type, named TAG. | `----------------------------------------*/ static semantic_type * -semantic_type_new (uniqstr tag) +semantic_type_new (uniqstr tag, const location *loc) { semantic_type *res = xmalloc (sizeof *res); uniqstr_assert (tag); res->tag = tag; - code_props_none_init (&res->destructor); - code_props_none_init (&res->printer); + if (loc) + res->location = *loc; + for (int i = 0; i < CODE_PROPS_SIZE; ++i) + code_props_none_init (&res->props[i]); return res; } @@@ -138,13 -116,13 +138,13 @@@ | Print a symbol. | `-----------------*/ -#define SYMBOL_ATTR_PRINT(Attr) \ - if (s->Attr) \ +#define SYMBOL_ATTR_PRINT(Attr) \ + if (s->Attr) \ fprintf (f, " %s { %s }", #Attr, s->Attr) -#define SYMBOL_CODE_PRINT(Attr) \ - if (s->Attr.code) \ - fprintf (f, " %s { %s }", #Attr, s->Attr.code) +#define SYMBOL_CODE_PRINT(Attr) \ + if (s->props[Attr].code) \ + fprintf (f, " %s { %s }", #Attr, s->props[Attr].code) void symbol_print (symbol *s, FILE *f) @@@ -163,41 -141,6 +163,41 @@@ #undef SYMBOL_ATTR_PRINT #undef SYMBOL_CODE_PRINT + +/*----------------------------------. +| Whether S is a valid identifier. | +`----------------------------------*/ + +static bool +is_identifier (uniqstr s) +{ + static char const alphanum[26 + 26 + 1 + 10] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "_" + "0123456789"; + if (!s || ! memchr (alphanum, *s, sizeof alphanum - 10)) + return false; + for (++s; *s; ++s) + if (! memchr (alphanum, *s, sizeof alphanum)) + return false; + return true; +} + + +/*-----------------------------------------------. +| Get the identifier associated to this symbol. | +`-----------------------------------------------*/ +uniqstr +symbol_id_get (symbol const *sym) +{ + aver (sym->user_token_number != USER_NUMBER_HAS_STRING_ALIAS); + if (sym->alias) + sym = sym->alias; + return is_identifier (sym->tag) ? sym->tag : 0; +} + + /*------------------------------------------------------------------. | Complain that S's WHAT is redeclared at SECOND, and was first set | | at FIRST. | @@@ -232,72 -175,122 +232,72 @@@ symbol_type_set (symbol *sym, uniqstr t if (type_name) { if (sym->type_name) - symbol_redeclaration (sym, "%type", sym->type_location, loc); + symbol_redeclaration (sym, "%type", sym->type_location, loc); uniqstr_assert (type_name); sym->type_name = type_name; sym->type_location = loc; } } -/*-----------------------------------------. -| Set the DESTRUCTOR associated with SYM. | -`-----------------------------------------*/ - -void -symbol_destructor_set (symbol *sym, code_props const *destructor) -{ - if (sym->destructor.code) - symbol_redeclaration (sym, "%destructor", sym->destructor.location, - destructor->location); - sym->destructor = *destructor; -} - -/*------------------------------------------. -| Set the DESTRUCTOR associated with TYPE. | -`------------------------------------------*/ - -void -semantic_type_destructor_set (semantic_type *type, - code_props const *destructor) -{ - if (type->destructor.code) - semantic_type_redeclaration (type, "%destructor", - type->destructor.location, - destructor->location); - type->destructor = *destructor; -} - -/*---------------------------------------. -| Get the computed %destructor for SYM. | -`---------------------------------------*/ - -code_props const * -symbol_destructor_get (symbol const *sym) -{ - /* Per-symbol %destructor. */ - if (sym->destructor.code) - return &sym->destructor; - - /* Per-type %destructor. */ - if (sym->type_name) - { - code_props const *destructor = - &semantic_type_get (sym->type_name)->destructor; - if (destructor->code) - return destructor; - } - - /* Apply default %destructor's only to user-defined symbols. */ - if (sym->tag[0] == '$' || sym == errtoken) - return &code_props_none; - - if (sym->type_name) - return &default_tagged_destructor; - return &default_tagless_destructor; -} - -/*--------------------------------------. -| Set the PRINTER associated with SYM. | -`--------------------------------------*/ +/*--------------------------------------------------------. +| Set the DESTRUCTOR or PRINTER associated with the SYM. | +`--------------------------------------------------------*/ void -symbol_printer_set (symbol *sym, code_props const *printer) +symbol_code_props_set (symbol *sym, code_props_type kind, + code_props const *code) { - if (sym->printer.code) - symbol_redeclaration (sym, "%printer", - sym->printer.location, printer->location); - sym->printer = *printer; + if (sym->props[kind].code) + symbol_redeclaration (sym, code_props_type_string (kind), + sym->props[kind].location, + code->location); + sym->props[kind] = *code; } -/*---------------------------------------. -| Set the PRINTER associated with TYPE. | -`---------------------------------------*/ +/*-----------------------------------------------------. +| Set the DESTRUCTOR or PRINTER associated with TYPE. | +`-----------------------------------------------------*/ void -semantic_type_printer_set (semantic_type *type, code_props const *printer) +semantic_type_code_props_set (semantic_type *type, + code_props_type kind, + code_props const *code) { - if (type->printer.code) - semantic_type_redeclaration (type, "%printer", - type->printer.location, printer->location); - type->printer = *printer; + if (type->props[kind].code) + semantic_type_redeclaration (type, code_props_type_string (kind), + type->props[kind].location, + code->location); + type->props[kind] = *code; } -/*------------------------------------. -| Get the computed %printer for SYM. | -`------------------------------------*/ +/*---------------------------------------------------. +| Get the computed %destructor or %printer for SYM. | +`---------------------------------------------------*/ code_props const * -symbol_printer_get (symbol const *sym) +symbol_code_props_get (symbol const *sym, + code_props_type kind) { - /* Per-symbol %printer. */ - if (sym->printer.code) - return &sym->printer; + /* Per-symbol code props. */ + if (sym->props[kind].code) + return &sym->props[kind]; - /* Per-type %printer. */ + /* Per-type code props. */ if (sym->type_name) { - code_props const *printer = &semantic_type_get (sym->type_name)->printer; - if (printer->code) - return printer; + code_props const *code = + &semantic_type_get (sym->type_name, NULL)->props[kind]; + if (code->code) + return code; } - /* Apply the default %printer only to user-defined symbols. */ + /* Apply default code props's only to user-defined symbols. */ if (sym->tag[0] == '$' || sym == errtoken) return &code_props_none; if (sym->type_name) - return &default_tagged_printer; - return &default_tagless_printer; + return &default_tagged_code_props[kind]; + return &default_tagless_code_props[kind]; } /*-----------------------------------------------------------------. @@@ -311,7 -304,7 +311,7 @@@ symbol_precedence_set (symbol *sym, in if (a != undef_assoc) { if (sym->prec != 0) - symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location, + symbol_redeclaration (sym, assoc_to_string (a), sym->prec_location, loc); sym->prec = prec; sym->assoc = a; @@@ -330,12 -323,10 +330,12 @@@ void symbol_class_set (symbol *sym, symbol_class class, location loc, bool declaring) { + bool warned = false; if (sym->class != unknown_sym && sym->class != class) { complain_at (loc, _("symbol %s redefined"), sym->tag); - sym->declared = false; + // Don't report both "redefined" and "redeclared". + warned = true; } if (class == nterm_sym && sym->class != nterm_sym) @@@ -347,9 -338,9 +347,9 @@@ if (declaring) { - if (sym->declared) - warn_at (loc, _("symbol %s redeclared"), sym->tag); - sym->declared = true; + if (sym->status == declared && !warned) + warn_at (loc, _("symbol %s redeclared"), sym->tag); + sym->status = declared; } } @@@ -377,7 -368,7 +377,7 @@@ symbol_user_token_number_set (symbol *s { endtoken = sym; /* It is always mapped to 0, so it was already counted in - NTOKENS. */ + NTOKENS. */ if (endtoken->number != NUMBER_UNDEFINED) --ntokens; endtoken->number = 0; @@@ -395,68 -386,14 +395,68 @@@ symbol_check_defined (symbol *sym { if (sym->class == unknown_sym) { - complain_at - (sym->location, - _("symbol %s is used, but is not defined as a token and has no rules"), - sym->tag); + switch (sym->status) + { + case used: + warn_at (sym->location, + _("symbol %s is used, but is not defined as a token" + " and has no rules"), + sym->tag); + break; + case undeclared: + case needed: + complain_at (sym->location, + _("symbol %s is used, but is not defined as a token" + " and has no rules"), + sym->tag); + break; + case declared: + /* If declared, then sym->class != unknown_sym. */ + assert (0); + } + sym->class = nterm_sym; sym->number = nvars++; } + for (int i = 0; i < 2; ++i) + if (sym->props[i].kind == CODE_PROPS_NONE && sym->type_name) + { + semantic_type *sem_type = semantic_type_get (sym->type_name, NULL); + if (sem_type + && sem_type->props[i].kind != CODE_PROPS_NONE) + sem_type->props[i].is_used = true; + } + + /* Set the semantic type status associated to the current symbol to + 'declared' so that we could check semantic types unnecessary uses. */ + if (sym->type_name) + { + semantic_type *sem_type = semantic_type_get (sym->type_name, NULL); + if (sem_type) + sem_type->status = declared; + } + + return true; +} + +static inline bool +semantic_type_check_defined (semantic_type *sem_type) +{ + if (sem_type->status == declared) + { + for (int i = 0; i < 2; ++i) + if (sem_type->props[i].kind != CODE_PROPS_NONE + && ! sem_type->props[i].is_used) + warn_at (sem_type->location, + _("useless %s for type <%s>"), + code_props_type_string (i), sem_type->tag); + } + else + warn_at (sem_type->location, + _("type <%s> is used, but is not associated to any symbol"), + sem_type->tag); + return true; } @@@ -466,13 -403,6 +466,13 @@@ symbol_check_defined_processor (void *s return symbol_check_defined (sym); } +static bool +semantic_type_check_defined_processor (void *sem_type, + void *null ATTRIBUTE_UNUSED) +{ + return semantic_type_check_defined (sem_type); +} + void symbol_make_alias (symbol *sym, symbol *str, location loc) @@@ -515,32 -445,42 +515,32 @@@ symbol_check_alias_consistency (symbol if (str->type_name != sym->type_name) { if (str->type_name) - symbol_type_set (sym, str->type_name, str->type_location); + symbol_type_set (sym, str->type_name, str->type_location); else - symbol_type_set (str, sym->type_name, sym->type_location); + symbol_type_set (str, sym->type_name, sym->type_location); } - if (str->destructor.code || sym->destructor.code) - { - if (str->destructor.code) - symbol_destructor_set (sym, &str->destructor); - else - symbol_destructor_set (str, &sym->destructor); - } - - if (str->printer.code || sym->printer.code) - { - if (str->printer.code) - symbol_printer_set (sym, &str->printer); - else - symbol_printer_set (str, &sym->printer); - } + for (int i = 0; i < CODE_PROPS_SIZE; ++i) + if (str->props[i].code) + symbol_code_props_set (sym, i, &str->props[i]); + else if (sym->props[i].code) + symbol_code_props_set (str, i, &sym->props[i]); if (sym->prec || str->prec) { if (str->prec) - symbol_precedence_set (sym, str->prec, str->assoc, - str->prec_location); + symbol_precedence_set (sym, str->prec, str->assoc, + str->prec_location); else - symbol_precedence_set (str, sym->prec, sym->assoc, - sym->prec_location); + symbol_precedence_set (str, sym->prec, sym->assoc, + sym->prec_location); } } static bool symbol_check_alias_consistency_processor (void *this, - void *null ATTRIBUTE_UNUSED) + void *null ATTRIBUTE_UNUSED) { symbol_check_alias_consistency (this); return true; @@@ -606,7 -546,7 +606,7 @@@ symbol_translation (symbol *this { /* A token which translation has already been set? */ if (token_translations[this->user_token_number] != undeftoken->number) - user_token_number_redeclaration + user_token_number_redeclaration (this->user_token_number, symbols[token_translations[this->user_token_number]], this); @@@ -694,15 -634,15 +694,15 @@@ voi symbols_new (void) { symbol_table = hash_initialize (HT_INITIAL_CAPACITY, - NULL, - hash_symbol_hasher, - hash_symbol_comparator, - free); + NULL, + hash_symbol_hasher, + hash_symbol_comparator, + free); semantic_type_table = hash_initialize (HT_INITIAL_CAPACITY, - NULL, - hash_semantic_type_hasher, - hash_semantic_type_comparator, - free); + NULL, + hash_semantic_type_hasher, + hash_semantic_type_comparator, + free); } @@@ -738,7 -678,7 +738,7 @@@ symbol_from_uniqstr (const uniqstr key `-----------------------------------------------------------------------*/ semantic_type * -semantic_type_from_uniqstr (const uniqstr key) +semantic_type_from_uniqstr (const uniqstr key, const location *loc) { semantic_type probe; semantic_type *entry; @@@ -749,7 -689,7 +749,7 @@@ if (!entry) { /* First insertion in the hash. */ - entry = semantic_type_new (key); + entry = semantic_type_new (key, loc); if (!hash_insert (semantic_type_table, entry)) xalloc_die (); } @@@ -775,9 -715,9 +775,9 @@@ symbol_get (const char *key, location l `-----------------------------------------------------------------------*/ semantic_type * -semantic_type_get (const char *key) +semantic_type_get (const char *key, const location *loc) { - return semantic_type_from_uniqstr (uniqstr_new (key)); + return semantic_type_from_uniqstr (uniqstr_new (key), loc); } @@@ -840,20 -780,20 +840,20 @@@ symbols_cmp_qsort (void const *a, void } static void -symbols_do (Hash_processor processor, void *processor_data) +symbols_do (Hash_processor processor, void *processor_data, + struct hash_table *table, symbol **sorted) { - size_t count = hash_get_n_entries (symbol_table); - if (!symbols_sorted) + size_t count = hash_get_n_entries (table); + if (!sorted) { - symbols_sorted = xnmalloc (count, sizeof *symbols_sorted); - hash_get_entries (symbol_table, (void**)symbols_sorted, count); - qsort (symbols_sorted, count, sizeof *symbols_sorted, - symbols_cmp_qsort); + sorted = xnmalloc (count, sizeof *sorted); + hash_get_entries (table, (void**)sorted, count); + qsort (sorted, count, sizeof *sorted, symbols_cmp_qsort); } { size_t i; for (i = 0; i < count; ++i) - processor (symbols_sorted[i], processor_data); + processor (sorted[i], processor_data); } } @@@ -865,10 -805,7 +865,10 @@@ void symbols_check_defined (void) { - symbols_do (symbol_check_defined_processor, NULL); + symbols_do (symbol_check_defined_processor, NULL, + symbol_table, symbols_sorted); + symbols_do (semantic_type_check_defined_processor, NULL, + semantic_type_table, semantic_types_sorted); } /*------------------------------------------------------------------. @@@ -889,12 -826,12 +889,12 @@@ symbols_token_translations_init (void { symbol *this = symbols[i]; if (this->user_token_number != USER_NUMBER_UNDEFINED) - { - if (this->user_token_number > max_user_token_number) - max_user_token_number = this->user_token_number; - if (this->user_token_number == 256) - num_256_available_p = false; - } + { + if (this->user_token_number > max_user_token_number) + max_user_token_number = this->user_token_number; + if (this->user_token_number == 256) + num_256_available_p = false; + } } /* If 256 is not used, assign it to error, to follow POSIX. */ @@@ -910,20 -847,20 +910,20 @@@ { symbol *this = symbols[i]; if (this->user_token_number == USER_NUMBER_UNDEFINED) - this->user_token_number = ++max_user_token_number; + this->user_token_number = ++max_user_token_number; if (this->user_token_number > max_user_token_number) - max_user_token_number = this->user_token_number; + max_user_token_number = this->user_token_number; } token_translations = xnmalloc (max_user_token_number + 1, - sizeof *token_translations); + sizeof *token_translations); - /* Initialize all entries for literal tokens to 2, the internal - token number for $undefined, which represents all invalid inputs. - */ + /* Initialize all entries for literal tokens to the internal token + number for $undefined, which represents all invalid inputs. */ for (i = 0; i < max_user_token_number + 1; i++) token_translations[i] = undeftoken->number; - symbols_do (symbol_translation_processor, NULL); + symbols_do (symbol_translation_processor, NULL, + symbol_table, symbols_sorted); } @@@ -935,11 -872,10 +935,11 @@@ void symbols_pack (void) { - symbols_do (symbol_check_alias_consistency_processor, NULL); + symbols_do (symbol_check_alias_consistency_processor, NULL, + symbol_table, symbols_sorted); symbols = xcalloc (nsyms, sizeof *symbols); - symbols_do (symbol_pack_processor, NULL); + symbols_do (symbol_pack_processor, NULL, symbol_table, symbols_sorted); /* Aliases leave empty slots in symbols, so remove them. */ { @@@ -969,12 -905,12 +969,12 @@@ if (startsymbol->class == unknown_sym) fatal_at (startsymbol_location, - _("the start symbol %s is undefined"), - startsymbol->tag); + _("the start symbol %s is undefined"), + startsymbol->tag); else if (startsymbol->class == token_sym) fatal_at (startsymbol_location, - _("the start symbol %s is a token"), - startsymbol->tag); + _("the start symbol %s is a token"), + startsymbol->tag); } @@@ -983,30 -919,53 +983,29 @@@ `--------------------------------------------------*/ void -default_tagged_destructor_set (code_props const *destructor) -{ - if (default_tagged_destructor.code) - { - complain_at (destructor->location, - _("redeclaration for default tagged %%destructor")); - complain_at (default_tagged_destructor.location, - _("previous declaration")); - } - default_tagged_destructor = *destructor; -} - -void -default_tagless_destructor_set (code_props const *destructor) -{ - if (default_tagless_destructor.code) - { - complain_at (destructor->location, - _("redeclaration for default tagless %%destructor")); - complain_at (default_tagless_destructor.location, - _("previous declaration")); - } - default_tagless_destructor = *destructor; -} - -void -default_tagged_printer_set (code_props const *printer) +default_tagged_code_props_set (code_props_type kind, code_props const *code) { - if (default_tagged_printer.code) + if (default_tagged_code_props[kind].code) { - complain_at (printer->location, - _("redeclaration for default tagged %%printer")); - complain_at (default_tagged_printer.location, - _("previous declaration")); + complain_at (code->location, + _("redeclaration for default tagged %s"), + code_props_type_string (kind)); + complain_at (default_tagged_code_props[kind].location, + _("previous declaration")); } - default_tagged_printer = *printer; + default_tagged_code_props[kind] = *code; } void -default_tagless_printer_set (code_props const *printer) +default_tagless_code_props_set (code_props_type kind, code_props const *code) { - if (default_tagless_printer.code) + if (default_tagless_code_props[kind].code) { - complain_at (printer->location, - _("redeclaration for default tagless %%printer")); - complain_at (default_tagless_printer.location, - _("previous declaration")); + complain_at (code->location, + _("redeclaration for default tagless %s"), + code_props_type_string (kind)); + complain_at (default_tagless_code_props[kind].location, + _("previous declaration")); } - default_tagless_printer = *printer; + default_tagless_code_props[kind] = *code; } - diff --combined tests/actions.at index 4af56153,3f47928a..1f05eb8e --- a/tests/actions.at +++ b/tests/actions.at @@@ -30,7 -30,7 +30,7 @@@ AT_SETUP([Mid-rule actions] AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], -[[%error-verbose +[[%define parse.error verbose %debug %{ ]AT_YYERROR_DECLARE[ @@@ -80,7 -80,7 +80,7 @@@ AT_SETUP([Exotic Dollars] AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], -[[%error-verbose +[[%define parse.error verbose %debug %{ ]AT_YYERROR_DECLARE[ @@@ -136,7 -136,7 +136,7 @@@ AT_PARSER_CHECK([./input], 0 AT_DATA_GRAMMAR([[input.y]], [[ %{ -#include +# include ]AT_YYERROR_DECLARE[ ]AT_YYLEX_DECLARE[ typedef struct { int val; } stype; @@@ -174,11 -174,12 +174,12 @@@ AT_CLEANU ## Printers and Destructors. ## ## -------------------------- ## - # _AT_CHECK_PRINTER_AND_DESTRUCTOR($1, $2, $3, $4, BISON-DIRECTIVE, UNION-FLAG) - # ----------------------------------------------------------------------------- + # _AT_CHECK_PRINTER_AND_DESTRUCTOR($1, $2, $3, $4, + # BISON-DIRECTIVE, UNION-FLAG) + # ------------------------------------------------------------- m4_define([_AT_CHECK_PRINTER_AND_DESTRUCTOR], [# Make sure complex $n work. - m4_if([$1$2$3], $[1]$[2]$[3], [], + m4_if([$1$2$3$4], $[1]$[2]$[3]$[4], [], [m4_fatal([$0: Invalid arguments: $@])])dnl # Be sure to pass all the %directives to this macro to have correct @@@ -193,13 -194,16 +194,16 @@@ AT_DATA_GRAMMAR([[input.y]] #define YYINITDEPTH 10 #define YYMAXDEPTH 10 - ]AT_LALR1_CC_IF( - [#define RANGE(Location) (Location).begin.line, (Location).end.line], - [#define RANGE(Location) (Location).first_line, (Location).last_line]) - [} + #define RANGE(Location) ]AT_LALR1_CC_IF([(Location).begin.line, (Location).end.line], + [(Location).first_line, (Location).last_line])[ + + /* Display the symbol type Symbol. */ + #define V(Symbol, Value, Location, Sep) \ + fprintf (stderr, #Symbol " (%d@%d-%d)" Sep, Value, RANGE(Location)) + } - $5] - m4_ifval([$6], [%union + $5 + ]m4_ifval([$6], [%union { int ival; }]) @@@ -221,28 -225,28 +225,28 @@@ AT_LALR1_CC_IF([typedef yy::location YY input line thing 'x' 'y' %destructor - { printf ("Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); } + { fprintf (stderr, "Freeing nterm input (%d@%d-%d)\n", $$, RANGE (@$)); } input %destructor - { printf ("Freeing nterm line (%d@%d-%d)\n", $$, RANGE (@$)); } + { fprintf (stderr, "Freeing nterm line (%d@%d-%d)\n", $$, RANGE (@$)); } line %destructor - { printf ("Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); } + { fprintf (stderr, "Freeing nterm thing (%d@%d-%d)\n", $$, RANGE (@$)); } thing %destructor - { printf ("Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); } + { fprintf (stderr, "Freeing token 'x' (%d@%d-%d)\n", $$, RANGE (@$)); } 'x' %destructor - { printf ("Freeing token 'y' (%d@%d-%d)\n", $$, RANGE (@$)); } + { fprintf (stderr, "Freeing token 'y' (%d@%d-%d)\n", $$, RANGE (@$)); } 'y' %token END 0 %destructor - { printf ("Freeing token END (%d@%d-%d)\n", $$, RANGE (@$)); } + { fprintf (stderr, "Freeing token END (%d@%d-%d)\n", $$, RANGE (@$)); } END %% @@@ -257,14 -261,15 +261,15 @@@ input /* Nothing. */ { $$ = 0; - printf ("input (%d@%d-%d): /* Nothing */\n", $$, RANGE (@$)); + V(input, $$, @$, ": /* Nothing */\n"); } | line input /* Right recursive to load the stack so that popping at - END can be exercised. */ + END can be exercised. */ { $$ = 2; - printf ("input (%d@%d-%d): line (%d@%d-%d) input (%d@%d-%d)\n", - $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2)); + V(input, $$, @$, ": "); + V(line, $1, @1, " "); + V(input, $2, @2, "\n"); } ; @@@ -272,28 -277,36 +277,36 @@@ line thing thing thing ';' { $$ = $1; - printf ("line (%d@%d-%d): thing (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ';' (%d@%d-%d)\n", - $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), - $3, RANGE (@3), $4, RANGE (@4)); + V(line, $$, @$, ": "); + V(thing, $1, @1, " "); + V(thing, $2, @2, " "); + V(thing, $3, @3, " "); + V(;, $4, @4, "\n"); } | '(' thing thing ')' { $$ = $1; - printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", - $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), - $3, RANGE (@3), $4, RANGE (@4)); + V(line, $$, @$, ": "); + V('(', $1, @1, " "); + V(thing, $2, @2, " "); + V(thing, $3, @3, " "); + V(')', $4, @4, "\n"); } | '(' thing ')' { $$ = $1; - printf ("line (%d@%d-%d): '(' (%d@%d-%d) thing (%d@%d-%d) ')' (%d@%d-%d)\n", - $$, RANGE (@$), $1, RANGE (@1), $2, RANGE (@2), $3, RANGE (@3)); + V(line, $$, @$, ": "); + V('(', $1, @1, " "); + V(thing, $2, @2, " "); + V(')', $3, @3, "\n"); } | '(' error ')' { $$ = -1; - printf ("line (%d@%d-%d): '(' (%d@%d-%d) error (@%d-%d) ')' (%d@%d-%d)\n", - $$, RANGE (@$), $1, RANGE (@1), RANGE (@2), $3, RANGE (@3)); + V(line, $$, @$, ": "); + V('(', $1, @1, " "); + fprintf (stderr, "error (@%d-%d) ", RANGE(@2)); + V(')', $3, @3, "\n"); } ; @@@ -301,14 -314,16 +314,16 @@@ thing 'x' { $$ = $1; - printf ("thing (%d@%d-%d): 'x' (%d@%d-%d)\n", - $$, RANGE (@$), $1, RANGE (@1)); + V(thing, $$, @$, ": "); + V('x', $1, @1, "\n"); } ; %% /* Alias to ARGV[1]. */ const char *source = YY_NULL; + ]AT_YYERROR_DEFINE[ + static ]AT_YYLEX_PROTOTYPE[ { @@@ -316,33 -331,18 +331,18 @@@ int c = ]AT_VAL[]m4_ifval([$6], [.ival])[ = counter++; /* As in BASIC, line numbers go from 10 to 10. */ - ]AT_LALR1_CC_IF( - [ AT_LOC.begin.line = AT_LOC.begin.column = 10 * c; - AT_LOC.end.line = AT_LOC.end.column = AT_LOC.begin.line + 9; - ], - [ AT_LOC.first_line = AT_LOC.first_column = 10 * c; - AT_LOC.last_line = AT_LOC.last_column = AT_LOC.first_line + 9; - ])[ - - if (! (0 <= c && c <= strlen (source))) - abort (); + ]AT_LOC_FIRST_LINE[ = ]AT_LOC_FIRST_COLUMN[ = 10 * c; + ]AT_LOC_LAST_LINE[ = ]AT_LOC_LAST_COLUMN[ = ]AT_LOC_FIRST_LINE[ + 9; + assert (0 <= c && c <= strlen (source)); if (source[c]) - printf ("sending: '%c'", source[c]); + fprintf (stderr, "sending: '%c'", source[c]); else - printf ("sending: END"); - printf (" (%d@%d-%d)\n", c, RANGE (]AT_LOC[)); + fprintf (stderr, "sending: END"); + fprintf (stderr, " (%d@%d-%d)\n", c, RANGE (]AT_LOC[)); return source[c]; } - ]AT_LALR1_CC_IF( - [/* A C++ error reporting function. */ - void - yy::parser::error (const location& l, const std::string& m) - { - printf ("%d-%d: %s\n", RANGE (l), m.c_str()); - } - - static bool yydebug; + [static bool yydebug; int yyparse () { @@@ -350,12 -350,7 +350,7 @@@ parser.set_debug_level (yydebug); return parser.parse (); } - ], - [static void - yyerror (const char *msg) - { - printf ("%d-%d: %s\n", RANGE (yylloc), msg); - }])[ + ])[ int main (int argc, const char *argv[]) @@@ -367,9 -362,9 +362,9 @@@ status = yyparse (); switch (status) { - case 0: printf ("Successful parse.\n"); break; - case 1: printf ("Parsing FAILED.\n"); break; - default: printf ("Parsing FAILED (status %d).\n", status); break; + case 0: fprintf (stderr, "Successful parse.\n"); break; + case 1: fprintf (stderr, "Parsing FAILED.\n"); break; + default: fprintf (stderr, "Parsing FAILED (status %d).\n", status); break; } return status; } @@@ -383,7 -378,7 +378,7 @@@ AT_FULL_COMPILE([input] # I.e., epsilon-reductions, as in "(x)" which ends by reducing # an empty "line" nterm. # FIXME: This location is not satisfying. Depend on the lookahead? - AT_PARSER_CHECK([./input '(x)'], 0, + AT_PARSER_CHECK([./input '(x)'], 0, [], [[sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) @@@ -402,10 -397,10 +397,10 @@@ Successful parse # --------------------------------- # '(y)' is an error, but can be recovered from. But what's the location # of the error itself ('y'), and of the resulting reduction ('(error)'). - AT_PARSER_CHECK([./input '(y)'], 0, + AT_PARSER_CHECK([./input '(y)'], 0, [], [[sending: '(' (0@0-9) sending: 'y' (1@10-19) - 10-19: syntax error, unexpected 'y', expecting 'x' + 10.10-19.18: syntax error, unexpected 'y', expecting 'x' Freeing token 'y' (1@10-19) sending: ')' (2@20-29) line (-1@0-29): '(' (0@0-9) error (@10-19) ')' (2@20-29) @@@ -432,14 -427,14 +427,14 @@@ Successful parse # '(', 'x', ')', # '(', 'x', ')', # 'y' - AT_PARSER_CHECK([./input '(xxxxx)(x)(x)y'], 1, + AT_PARSER_CHECK([./input '(xxxxx)(x)(x)y'], 1, [], [[sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) sending: 'x' (2@20-29) thing (2@20-29): 'x' (2@20-29) sending: 'x' (3@30-39) - 30-39: syntax error, unexpected 'x', expecting ')' + 30.30-39.38: syntax error, unexpected 'x', expecting ')' Freeing nterm thing (2@20-29) Freeing nterm thing (1@10-19) Freeing token 'x' (3@30-39) @@@ -464,7 -459,7 +459,7 @@@ input (0@129-129): /* Nothing * input (2@100-129): line (10@100-129) input (0@129-129) input (2@70-129): line (7@70-99) input (2@100-129) input (2@0-129): line (-1@0-69) input (2@70-129) - 130-139: syntax error, unexpected 'y', expecting END + 130.130-139.138: syntax error, unexpected 'y', expecting END Freeing nterm input (2@0-129) Freeing token 'y' (13@130-139) Parsing FAILED. @@@ -480,7 -475,7 +475,7 @@@ # '(', 'x', ')', # '(', 'x', ')', # 'x' - AT_PARSER_CHECK([./input '(x)(x)x'], 1, + AT_PARSER_CHECK([./input '(x)(x)x'], 1, [], [[sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) @@@ -494,7 -489,7 +489,7 @@@ line (3@30-59): '(' (3@30-39) thing (4@ sending: 'x' (6@60-69) thing (6@60-69): 'x' (6@60-69) sending: END (7@70-79) - 70-79: syntax error, unexpected END, expecting 'x' + 70.70-79.78: syntax error, unexpected END, expecting 'x' Freeing nterm thing (6@60-69) Freeing nterm line (3@30-59) Freeing nterm line (0@0-29) @@@ -508,7 -503,7 +503,7 @@@ Parsing FAILED # Upon stack overflow, all symbols on the stack should be destroyed. # Only check for yacc.c. AT_YACC_IF([ - AT_PARSER_CHECK([./input '(x)(x)(x)(x)(x)(x)(x)'], 2, + AT_PARSER_CHECK([./input '(x)(x)(x)(x)(x)(x)(x)'], 2, [], [[sending: '(' (0@0-9) sending: 'x' (1@10-19) thing (1@10-19): 'x' (1@10-19) @@@ -543,7 -538,7 +538,7 @@@ sending: '(' (18@180-189 sending: 'x' (19@190-199) thing (19@190-199): 'x' (19@190-199) sending: ')' (20@200-209) - 200-209: memory exhausted + 200.200-209.208: memory exhausted Freeing nterm thing (19@190-199) Freeing nterm line (15@150-179) Freeing nterm line (12@120-149) @@@ -566,7 -561,7 +561,7 @@@ m4_define([AT_CHECK_PRINTER_AND_DESTRUC $3 _AT_CHECK_PRINTER_AND_DESTRUCTOR($[1], $[2], $[3], $[4], -[%error-verbose +[%define parse.error verbose %debug %verbose %locations @@@ -597,7 -592,7 +592,7 @@@ AT_CHECK_PRINTER_AND_DESTRUCTOR([%glr-p AT_SETUP([Default tagless %printer and %destructor]) AT_BISON_OPTION_PUSHDEFS([%locations]) AT_DATA_GRAMMAR([[input.y]], -[[%error-verbose +[[%define parse.error verbose %debug %locations %initial-action { @@@ -699,7 -694,7 +694,7 @@@ AT_CLEANU AT_SETUP([Default tagged and per-type %printer and %destructor]) AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], -[[%error-verbose +[[%define parse.error verbose %debug %{ @@@ -831,7 -826,7 +826,7 @@@ m4_define([_AT_CHECK_DEFAULT_PRINTER_AN AT_BISON_OPTION_PUSHDEFS([%locations]) AT_DATA_GRAMMAR([[input]]$1[[.y]], -[[%error-verbose +[[%define parse.error verbose %debug %locations %initial-action { @@@ -1202,7 -1197,7 +1197,7 @@@ AT_DATA_GRAMMAR([[input.y]] %debug ]$1[ { - printf ("%d\n", @$.first_line); + fprintf (stderr, "%d\n", @$.first_line); } ]m4_if($1, [%initial-action], [], [[start]])[ %% @@@ -1250,37 -1245,37 +1245,37 @@@ AT_DATA([input.y] start: test2 test1 test0 testc; test2 -: 'a' { semi; /* TEST:N:2 */ } -| 'b' { if (0) {no_semi} /* TEST:N:2 */ } -| 'c' { if (0) {semi;} /* TEST:N:2 */ } -| 'd' { semi; no_semi /* TEST:Y:2 */ } -| 'e' { semi(); no_semi() /* TEST:Y:2 */ } -| 'f' { semi[]; no_semi[] /* TEST:Y:2 */ } -| 'g' { semi++; no_semi++ /* TEST:Y:2 */ } -| 'h' { {no_semi} no_semi /* TEST:Y:2 */ } -| 'i' { {semi;} no_semi /* TEST:Y:2 */ } +: 'a' { semi; /* TEST:N:2 */ } +| 'b' { if (0) {no_semi} /* TEST:N:2 */ } +| 'c' { if (0) {semi;} /* TEST:N:2 */ } +| 'd' { semi; no_semi /* TEST:Y:2 */ } +| 'e' { semi(); no_semi() /* TEST:Y:2 */ } +| 'f' { semi[]; no_semi[] /* TEST:Y:2 */ } +| 'g' { semi++; no_semi++ /* TEST:Y:2 */ } +| 'h' { {no_semi} no_semi /* TEST:Y:2 */ } +| 'i' { {semi;} no_semi /* TEST:Y:2 */ } ; test1 - : 'a' { semi; // TEST:N:1 ; -} | 'b' { if (0) {no_semi} // TEST:N:1 ; -} | 'c' { if (0) {semi;} // TEST:N:1 ; -} | 'd' { semi; no_semi // TEST:Y:1 ; -} | 'e' { semi(); no_semi() // TEST:Y:1 ; -} | 'f' { semi[]; no_semi[] // TEST:Y:1 ; -} | 'g' { semi++; no_semi++ // TEST:Y:1 ; -} | 'h' { {no_semi} no_semi // TEST:Y:1 ; -} | 'i' { {semi;} no_semi // TEST:Y:1 ; + : 'a' { semi; // TEST:N:1 ; +} | 'b' { if (0) {no_semi} // TEST:N:1 ; +} | 'c' { if (0) {semi;} // TEST:N:1 ; +} | 'd' { semi; no_semi // TEST:Y:1 ; +} | 'e' { semi(); no_semi() // TEST:Y:1 ; +} | 'f' { semi[]; no_semi[] // TEST:Y:1 ; +} | 'g' { semi++; no_semi++ // TEST:Y:1 ; +} | 'h' { {no_semi} no_semi // TEST:Y:1 ; +} | 'i' { {semi;} no_semi // TEST:Y:1 ; } ; test0 - : 'a' { semi; // TEST:N:1 {} -} | 'b' { if (0) {no_semi} // TEST:N:1 {} -} | 'c' { if (0) {semi;} // TEST:N:1 {} -} | 'd' { semi; no_semi // TEST:Y:1 {} -} | 'e' { semi(); no_semi() // TEST:Y:1 {} -} | 'f' { semi[]; no_semi[] // TEST:Y:1 {} -} | 'g' { semi++; no_semi++ // TEST:Y:1 {} -} | 'h' { {no_semi} no_semi // TEST:Y:1 {} -} | 'i' { {semi;} no_semi // TEST:Y:1 {} + : 'a' { semi; // TEST:N:1 {} +} | 'b' { if (0) {no_semi} // TEST:N:1 {} +} | 'c' { if (0) {semi;} // TEST:N:1 {} +} | 'd' { semi; no_semi // TEST:Y:1 {} +} | 'e' { semi(); no_semi() // TEST:Y:1 {} +} | 'f' { semi[]; no_semi[] // TEST:Y:1 {} +} | 'g' { semi++; no_semi++ // TEST:Y:1 {} +} | 'h' { {no_semi} no_semi // TEST:Y:1 {} +} | 'i' { {semi;} no_semi // TEST:Y:1 {} } ; testc diff --combined tests/calc.at index 0a9f9e11,58e7e895..55b91544 --- a/tests/calc.at +++ b/tests/calc.at @@@ -45,7 -45,7 +45,7 @@@ m4_define([_AT_DATA_CALC_Y] [m4_fatal([$0: Invalid arguments: $@])])dnl m4_pushdef([AT_CALC_MAIN], - [#include /* abort */ + [#include #if HAVE_UNISTD_H # include #else @@@ -98,10 -98,8 +98,8 @@@ main (int argc, const char **argv status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[); if (fclose (input)) perror ("fclose"); - if (global_result != result) - abort (); - if (global_count != count) - abort (); + assert (global_result == result); + assert (global_count == count); return status; } ]]) @@@ -207,12 -205,12 +205,12 @@@ read_signed_integer (]AT_YYLEX_FORMALS[ { unget_char (]AT_YYLEX_PRE_ARGS[ c); ]AT_VAL[.ival = read_signed_integer (]AT_YYLEX_ARGS[); - return NUM; + return ]AT_TOKEN_PREFIX[NUM; } /* Return end-of-file. */ if (c == EOF) - return CALC_EOF; + return ]AT_TOKEN_PREFIX[CALC_EOF; /* Return single chars. */ return c; @@@ -294,27 -292,27 +292,27 @@@ static int power (int base, int exponen ]AT_YYLEX_DECLARE_EXTERN[ } -]AT_SKEL_CC_IF([AT_LOCATION_TYPE_IF([], [ +]AT_SKEL_CC_IF([AT_LOCATION_IF([AT_LOCATION_TYPE_IF([], [ /* The lalr1.cc skeleton, for backward compatibility, defines a constructor for position that initializes the filename. The glr.cc skeleton does not (and in fact cannot: location/position are stored in a union, from which objects with constructors are - excluded in C++. */ + excluded in C++). */ %initial-action { @$.initialize (); } -])])[ +])])])[ /* Bison Declarations */ %token CALC_EOF 0 "end of input" %token NUM "number" %type exp -%nonassoc '=' /* comparison */ +%nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' -%left NEG /* negation--unary minus */ -%right '^' /* exponentiation */ +%precedence NEG /* negation--unary minus */ +%right '^' /* exponentiation */ /* Grammar follows */ %% @@@ -456,7 -454,7 +454,7 @@@ AT_PARSER_CHECK([./calc input], 0, [], # If BISON-OPTIONS contains `%location', then make sure the ERROR-LOCATION # is correctly output on stderr. # -# If BISON-OPTIONS contains `%error-verbose', then make sure the +# If BISON-OPTIONS contains `%define parse.error verbose', then make sure the # IF-YYERROR-VERBOSE message is properly output after `syntax error, ' # on STDERR. # @@@ -498,7 -496,7 +496,7 @@@ AT_YYERROR_SEES_LOC_IF([] [[sed 's/^[-0-9.]*: //' expout >at-expout mv at-expout expout]]) # 4. If error-verbose is not used, strip the`, unexpected....' part. -m4_bmatch([$1], [%error-verbose], [], +m4_bmatch([$1], [%define parse.error verbose], [], [[sed 's/syntax error, .*$/syntax error/' expout >at-expout mv at-expout expout]]) # 5. Check @@@ -627,22 -625,21 +625,22 @@@ AT_CHECK_CALC_LALR([%locations] AT_CHECK_CALC_LALR([%name-prefix="calc"]) dnl test deprecated `=' AT_CHECK_CALC_LALR([%verbose]) AT_CHECK_CALC_LALR([%yacc]) -AT_CHECK_CALC_LALR([%error-verbose]) +AT_CHECK_CALC_LALR([%define parse.error verbose]) AT_CHECK_CALC_LALR([%define api.pure %locations]) AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure %locations]) -AT_CHECK_CALC_LALR([%error-verbose %locations]) +AT_CHECK_CALC_LALR([%define parse.error verbose %locations]) -AT_CHECK_CALC_LALR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_LALR([%define parse.error verbose %locations %defines %name-prefix "calc" %define api.tokens.prefix "TOK_" %verbose %yacc]) AT_CHECK_CALC_LALR([%debug]) -AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_LALR([%define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_LALR([%define api.pure %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_LALR([%define api.push-pull both %define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_LALR([%define api.pure %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) +AT_CHECK_CALC_LALR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) # ----------------------- # @@@ -666,20 -663,19 +664,20 @@@ AT_CHECK_CALC_GLR([%locations] AT_CHECK_CALC_GLR([%name-prefix "calc"]) AT_CHECK_CALC_GLR([%verbose]) AT_CHECK_CALC_GLR([%yacc]) -AT_CHECK_CALC_GLR([%error-verbose]) +AT_CHECK_CALC_GLR([%define parse.error verbose]) AT_CHECK_CALC_GLR([%define api.pure %locations]) -AT_CHECK_CALC_GLR([%error-verbose %locations]) +AT_CHECK_CALC_GLR([%define parse.error verbose %locations]) -AT_CHECK_CALC_GLR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_GLR([%define parse.error verbose %locations %defines %name-prefix "calc" %verbose %yacc]) AT_CHECK_CALC_GLR([%debug]) -AT_CHECK_CALC_GLR([%error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_GLR([%define parse.error verbose %debug %locations %defines %name-prefix "calc" %define api.tokens.prefix "TOK_" %verbose %yacc]) -AT_CHECK_CALC_GLR([%define api.pure %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_GLR([%define api.pure %error-verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) +AT_CHECK_CALC_GLR([%define api.pure %define parse.error verbose %debug %locations %defines %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) # ----------------------------- # @@@ -696,19 -692,16 +694,19 @@@ AT_CHECK_CALC([%skeleton "lalr1.cc" %de # Start a testing chunk which compiles `calc' grammar with # the C++ skeleton, and performs several tests over the parser. m4_define([AT_CHECK_CALC_LALR1_CC], -[AT_CHECK_CALC([%language "C++" %defines %locations] $@)]) +[AT_CHECK_CALC([%language "C++" %defines] $@)]) AT_CHECK_CALC_LALR1_CC([]) -AT_CHECK_CALC_LALR1_CC([%define location_type Span]) -AT_CHECK_CALC_LALR1_CC([%error-verbose %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_LALR1_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_LALR1_CC([%locations]) +AT_CHECK_CALC_LALR1_CC([%locations %define location_type Span]) +AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) +AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %name-prefix "calc" %define api.tokens.prefix "TOK_" %verbose %yacc]) + +AT_CHECK_CALC_LALR1_CC([%locations %pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) @@@ -730,12 -723,11 +728,12 @@@ m4_define([AT_CHECK_CALC_GLR_CC] AT_CHECK_CALC_GLR_CC([]) AT_CHECK_CALC_GLR_CC([%define location_type Span]) -AT_CHECK_CALC_GLR_CC([%error-verbose %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_GLR_CC([%define parse.error verbose %name-prefix "calc" %verbose %yacc]) AT_CHECK_CALC_GLR_CC([%debug]) -AT_CHECK_CALC_GLR_CC([%error-verbose %debug %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_GLR_CC([%define parse.error verbose %debug %name-prefix "calc" %verbose %yacc]) -AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc]) +AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %define api.tokens.prefix "TOK_" %verbose %yacc]) -AT_CHECK_CALC_GLR_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) +AT_CHECK_CALC_GLR_CC([%pure-parser %define parse.error verbose %debug %name-prefix "calc" %verbose %yacc %parse-param {semantic_value *result} %parse-param {int *count}]) diff --combined tests/conflicts.at index 6c71a368,cafa3338..3cced5d7 --- a/tests/conflicts.at +++ b/tests/conflicts.at @@@ -1,6 -1,7 +1,6 @@@ # Exercising Bison on conflicts. -*- Autotest -*- -# Copyright (C) 2002-2005, 2007, 2009-2012 Free Software Foundation, -# Inc. +# Copyright (C) 2002-2005, 2007-2012 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 @@@ -56,6 -57,7 +56,7 @@@ AT_DATA_GRAMMAR([input.y] #include #include #include + #include #define YYERROR_VERBOSE 1 ]AT_YYERROR_DEFINE[ @@@ -66,8 -68,7 +67,7 @@@ static in yylex (void) { static size_t toknum; - if (! (toknum <= strlen (input))) - abort (); + assert (toknum <= strlen (input)); return input[toknum++]; } @@@ -141,11 -142,11 +141,11 @@@ AT_CLEANU -## -------------------------------------- ## -## %error-verbose and consistent errors. ## -## -------------------------------------- ## +## ------------------------------------------- ## +## parse.error=verbose and consistent errors. ## +## ------------------------------------------- ## -AT_SETUP([[%error-verbose and consistent errors]]) +AT_SETUP([[parse.error=verbose and consistent errors]]) m4_pushdef([AT_CONSISTENT_ERRORS_CHECK], [ @@@ -163,6 -164,7 +163,6 @@@ AT_SKEL_JAVA_IF([AT_DATA], [AT_DATA_GRA }]], [[ %code {]AT_SKEL_CC_IF([[ - #include #include ]], [[ #include #include @@@ -175,7 -177,7 +175,7 @@@ ]$1[ -%error-verbose +%define parse.error verbose %% @@@ -370,7 -372,7 +370,7 @@@ error-reduce ; consistent-reduction: /*empty*/ { - assert (yychar == ]AT_SKEL_CC_IF([[yyempty_]], [[YYEMPTY]])[); + assert (yychar == YYEMPTY); yylval = 0; yychar = 'b'; } ; @@@ -394,7 -396,11 +394,7 @@@ AT_CONSISTENT_ERRORS_CHECK([[%glr-parse [AT_USER_ACTION_GRAMMAR], [AT_USER_ACTION_INPUT], [['b']], [[none]]) -AT_CONSISTENT_ERRORS_CHECK([[%language "c++"]], - [AT_USER_ACTION_GRAMMAR], - [AT_USER_ACTION_INPUT], - [['b']], [[none]]) -# No Java test because yychar cannot be manipulated by users. +# No C++ or Java test because yychar cannot be manipulated by users. AT_CONSISTENT_ERRORS_CHECK([[%define lr.default-reductions consistent]], [AT_USER_ACTION_GRAMMAR], @@@ -735,62 -741,6 +735,62 @@@ state AT_CLEANUP +## ---------------------- ## +## %precedence suffices. ## +## ---------------------- ## + +AT_SETUP([%precedence suffices]) + +AT_DATA([input.y], +[[%precedence "then" +%precedence "else" +%% +stmt: + "if" cond "then" stmt +| "if" cond "then" stmt "else" stmt +| "stmt" +; + +cond: + "exp" +; +]]) + +AT_BISON_CHECK([-o input.c input.y]) + +AT_CLEANUP + + +## ------------------------------ ## +## %precedence does not suffice. ## +## ------------------------------ ## + +AT_SETUP([%precedence does not suffice]) + +AT_DATA([input.y], +[[%precedence "then" +%precedence "else" +%% +stmt: + "if" cond "then" stmt +| "if" cond "then" stmt "else" stmt +| "stmt" +; + +cond: + "exp" +| cond "then" cond +; +]]) + +AT_BISON_CHECK([-o input.c input.y], 0, [], +[[input.y: conflicts: 1 shift/reduce +input.y:12.3-18: warning: rule useless in parser due to conflicts: cond: cond "then" cond +]]) + +AT_CLEANUP + + ## -------------------------------- ## ## Defaulted Conflicted Reduction. ## ## -------------------------------- ## diff --combined tests/input.at index 053e3583,0ed8635f..356fe92b --- a/tests/input.at +++ b/tests/input.at @@@ -69,9 -69,10 +69,9 @@@ AT_CLEANU # _AT_UNUSED_VALUES_DECLARATIONS() -# -------------------------------------------- +# -------------------------------- # Generate the token, type, and destructor # declarations for the unused values tests. - m4_define([_AT_UNUSED_VALUES_DECLARATIONS], [[[%token INT; %type a b c d e f g h i j k l; @@@ -79,11 -80,15 +79,11 @@@ # AT_CHECK_UNUSED_VALUES(DECLARATIONS_AFTER, CHECK_MIDRULE_VALUES) -# ------------------------------------------------------------------ -# Generate a grammar to test unused values, -# compile it, run it. If DECLARATIONS_AFTER -# is set, then the token, type, and destructor -# declarations are generated after the rules -# rather than before. If CHECK_MIDRULE_VALUES -# is set, then --warnings=midrule-values is -# set. - +# ---------------------------------------------------------------- +# Generate a grammar to test unused values, compile it, run it. If +# DECLARATIONS_AFTER is set, then the token, type, and destructor +# declarations are generated after the rules rather than before. If +# CHECK_MIDRULE_VALUES is set, then --warnings=midrule-values is set. m4_define([AT_CHECK_UNUSED_VALUES], [AT_DATA([input.y], m4_ifval($1, [ @@@ -269,102 -274,6 +269,102 @@@ input.y:12.10-24: %printer redeclaratio input.y:5.10-24: previous declaration ]]) +AT_CLEANUP + +## ----------------------------------------------------- ## +## Undeclared symbols used for a printer or destructor. ## +## ----------------------------------------------------- ## + +AT_SETUP([Undeclared symbols used for a printer or destructor]) + +AT_DATA([[input.y]], +[[%printer {} foo baz +%destructor {} bar + +%% +exp: bar; +]]) + +AT_BISON_CHECK([input.y], [1], [], +[[input.y:2.16-18: symbol bar is used, but is not defined as a token and has no rules +input.y:1.17-19: warning: symbol baz is used, but is not defined as a token and has no rules +input.y:1.13-15: warning: symbol foo is used, but is not defined as a token and has no rules +]]) + +AT_CLEANUP + + +## ----------------------------------------------------- ## +## Unassociated types used for a printer or destructor. ## +## ----------------------------------------------------- ## + +AT_SETUP([Unassociated types used for a printer or destructor]) + +AT_DATA([[input.y]], +[[%token tag1 +%type tag2 + +%printer { } +%destructor { } + +%% + +exp: tag1 { $1; } + | tag2 { $1; } + +tag2: "a" { $$; } +]]) + +AT_BISON_CHECK([input.y], [0], [], +[[input.y:4.22-28: warning: type is used, but is not associated to any symbol +input.y:5.25-31: warning: type is used, but is not associated to any symbol +]]) + +AT_CLEANUP + + +## --------------------------------- ## +## Useless printers or destructors. ## +## --------------------------------- ## + +AT_SETUP([Useless printers or destructors]) + +AT_DATA([[input.y]], +[[%token token1 +%token token2 +%token token3 +%token token4 +%token token51 token52 +%token token61 token62 +%token token7 + +%printer {} token1 +%destructor {} token2 +%printer {} token51 +%destructor {} token61 + +%printer {} token7 + +%printer {} +%destructor {} +%printer {} +%destructor {} + +%printer {} +%destructor {} + +%destructor {} + +%% +exp: "a"; +]]) + +AT_BISON_CHECK([input.y], [0], [], +[[input.y:16.13-19: warning: useless %printer for type +input.y:17.16-22: warning: useless %destructor for type +]]) + + AT_CLEANUP @@@ -533,6 -442,7 +533,7 @@@ char apostrophe = '\'' #include #include + #include %} /* %{ and %} can be here too. */ @@@ -600,14 -510,13 +601,13 @@@ yylex (void #output "; /* " */ static size_t toknum; - if (! (toknum < sizeof input)) - abort (); + assert (toknum < sizeof input); yylval = value_as_yystype (input[toknum]); return input[toknum++]; } ]]) -# Pacify Emacs' font-lock-mode: " +# Pacify Emacs'font-lock-mode: " AT_DATA([main.c], [[typedef int value; @@@ -624,8 -533,8 +624,8 @@@ main (void AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-d -v -o input.c input.y]) - AT_COMPILE([input.o], [-c input.c]) - AT_COMPILE([main.o], [-c main.c]) + AT_COMPILE([input.o]) + AT_COMPILE([main.o]) AT_COMPILE([input], [input.o main.o]) AT_PARSER_CHECK([./input], 0, [[[@<:@], @@@ -686,8 -595,8 +686,8 @@@ AT_CHECK_REQUIRE(100.0, 63 AT_SETUP([String aliases for character tokens]) -# Bison once thought a character token and its alias were different symbols -# with the same user token number. +# Bison once thought a character token and its alias were different +# symbols with the same user token number. AT_DATA_GRAMMAR([input.y], [[%token 'a' "a" @@@ -745,7 -654,7 +745,7 @@@ input.y:18.8-16: warning: POSIX Yacc fo AT_BISON_CHECK([-o input.c input.y]) # Make sure we don't export silly token identifiers with periods or dashes. - AT_COMPILE([input.o], [-c input.c]) + AT_COMPILE([input.o]) # Periods are genuine letters, they can start identifiers. @@@ -811,10 -720,10 +811,10 @@@ AT_CLEANU AT_SETUP([Unclosed constructs]) -# Bison's scan-gram.l once forgot to STRING_FINISH some unclosed constructs, so -# they were prepended to whatever it STRING_GROW'ed next. It also threw them -# away rather than returning them to the parser. The effect was confusing -# subsequent error messages. +# Bison's scan-gram.l once forgot to STRING_FINISH some unclosed +# constructs, so they were prepended to whatever it STRING_GROW'ed +# next. It also threw them away rather than returning them to the +# parser. The effect was confusing subsequent error messages. AT_DATA([input.y], [[%token A "a @@@ -856,8 -765,8 +856,8 @@@ AT_CLEANU AT_SETUP([%start after first rule]) -# Bison once complained that a %start after the first rule was a redeclaration -# of the start symbol. +# Bison once complained that a %start after the first rule was a +# redeclaration of the start symbol. AT_DATA([input.y], [[%% @@@ -1174,17 -1083,6 +1174,17 @@@ 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:2.9-21: %define variable 'api.namespace' redefined +input.y:1.9-17: previous definition +]]) + AT_DATA([[input.y]], [[%define foo_bar "baz" %% @@@ -1243,14 -1141,14 +1243,14 @@@ m4_define([AT_CHECK_NAMESPACE_ERROR] 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[ ]])]) ]) diff --combined tests/local.at index 649e9943,5a5bbdd0..d5c73657 --- a/tests/local.at +++ b/tests/local.at @@@ -90,14 -90,15 +90,15 @@@ m4_popdef([AT_LOC_LAST_COLUMN])] # AT_BISON_OPTION_PUSHDEFS([BISON-OPTIONS]) # ----------------------------------------- m4_define([AT_BISON_OPTION_PUSHDEFS], - [_AT_BISON_OPTION_PUSHDEFS($[1], $[2], [$1])]) + [m4_divert_text([KILL], + [_AT_BISON_OPTION_PUSHDEFS($[1], $[2], [$1])])]) # _AT_BISON_OPTION_PUSHDEFS($1, $2, [BISON-OPTIONS]) # -------------------------------------------------- # This macro works around the impossibility to define macros # inside macros, because issuing `[$1]' is not possible in M4 :(. -# This sucks hard, GNU M4 should really provide M5 like $$1. +# This sucks hard, GNU M4 should really provide M5-like $$1. m4_define([_AT_BISON_OPTION_PUSHDEFS], [m4_if([$1$2], $[1]$[2], [], [m4_fatal([$0: Invalid arguments: $@])])dnl @@@ -137,47 -138,52 +138,55 @@@ m4_pushdef([AT_PURE_AND_LOC_IF] m4_pushdef([AT_GLR_OR_PARAM_IF], [m4_bmatch([$3], [%glr-parser\|%parse-param], [$1], [$2])]) m4_pushdef([AT_NAME_PREFIX], - [m4_bmatch([$3], [%name-prefix ".*"], - [m4_bregexp([$3], [%name-prefix "\([^""]*\)"], [\1])], - [yy])]) - m4_pushdef([AT_API_PREFIX], [m4_bmatch([$3], [\(%define api\.prefix\|%name-prefix\) ".*"], [m4_bregexp([$3], [\(%define api\.prefix\|%name-prefix\) "\([^""]*\)"], [\2])], [yy])]) +m4_pushdef([AT_TOKEN_PREFIX], +[m4_bmatch([$3], [%define api.tokens.prefix ".*"], + [m4_bregexp([$3], [%define api.tokens.prefix "\(.*\)"], [\1])])]) + m4_pushdef([AT_API_prefix], + [m4_bmatch([$3], [%define api\.prefix ".*"], + [m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])], + [yy])]) # yyerror receives the location if %location & %pure & (%glr or %parse-param). m4_pushdef([AT_YYERROR_ARG_LOC_IF], [AT_GLR_OR_PARAM_IF([AT_PURE_AND_LOC_IF([$1], [$2])], - [$2])]) + [$2])]) # yyerror always sees the locations (when activated), except if # (yacc & pure & !param). FIXME: This is wrong. See the manual. m4_pushdef([AT_YYERROR_SEES_LOC_IF], [AT_LOCATION_IF([AT_YACC_IF([AT_PURE_IF([AT_PARAM_IF([$1], [$2])], - [$1])], - [$1])], - [$2])]) + [$1])], + [$1])], + [$2])]) # The interface is pure: either because %define api.pure, or because we # are using the C++ parsers. m4_pushdef([AT_PURE_LEX_IF], [AT_PURE_IF([$1], - [AT_SKEL_CC_IF([$1], [$2])])]) + [AT_SKEL_CC_IF([$1], [$2])])]) + m4_pushdef([AT_YYSTYPE], + [AT_SKEL_CC_IF([AT_NAME_PREFIX[::parser::semantic_type]], + [[YYSTYPE]])]) + m4_pushdef([AT_YYLTYPE], + [AT_SKEL_CC_IF([AT_NAME_PREFIX[::parser::location_type]], + [[YYLTYPE]])]) + + AT_PURE_LEX_IF( [m4_pushdef([AT_LOC], [(*llocp)]) m4_pushdef([AT_VAL], [(*lvalp)]) m4_pushdef([AT_YYLEX_FORMALS], - [YYSTYPE *lvalp[]AT_LOCATION_IF([, YYLTYPE *llocp])]) - [AT_YYSTYPE *lvalp[]AT_LOCATION_IF([, AT_YYLTYPE *llocp])]) ++ [AT_YYSTYPE *lvalp[]AT_LOCATION_IF([, AT_YYLTYPE *llocp])]) m4_pushdef([AT_YYLEX_ARGS], - [lvalp[]AT_LOCATION_IF([, llocp])]) + [lvalp[]AT_LOCATION_IF([, llocp])]) m4_pushdef([AT_USE_LEX_ARGS], - [(void) lvalp;AT_LOCATION_IF([(void) llocp])]) + [(void) lvalp;AT_LOCATION_IF([(void) llocp])]) m4_pushdef([AT_YYLEX_PRE_FORMALS], -- [AT_YYLEX_FORMALS, ]) ++ [AT_YYLEX_FORMALS, ]) m4_pushdef([AT_YYLEX_PRE_ARGS], -- [AT_YYLEX_ARGS, ]) ++ [AT_YYLEX_ARGS, ]) ], [m4_pushdef([AT_LOC], [[(]AT_NAME_PREFIX[lloc)]]) m4_pushdef([AT_VAL], [[(]AT_NAME_PREFIX[lval)]]) @@@ -196,25 -202,26 +205,28 @@@ AT_SKEL_CC_IF [AT_LOC_PUSHDEF([begin.line], [begin.column], [end.line], [end.column])])], [AT_LOC_PUSHDEF([first_line], [first_column], [last_line], [last_column])]) + +AT_GLR_IF([AT_KEYWORDS([glr])]) ])# _AT_BISON_OPTION_PUSHDEFS # AT_BISON_OPTION_POPDEFS # ----------------------- m4_define([AT_BISON_OPTION_POPDEFS], + [m4_divert_text([KILL], [m4_popdef([AT_YYLEX_PRE_ARGS]) m4_popdef([AT_YYLEX_PRE_FORMALS]) m4_popdef([AT_USE_LEX_ARGS]) m4_popdef([AT_YYLEX_ARGS]) m4_popdef([AT_YYLEX_FORMALS]) + m4_popdef([AT_YYLTYPE]) + m4_popdef([AT_YYSTYPE]) m4_popdef([AT_VAL]) m4_popdef([AT_LOC]) m4_popdef([AT_PURE_LEX_IF]) m4_popdef([AT_YYERROR_SEES_LOC_IF]) m4_popdef([AT_YYERROR_ARG_LOC_IF]) - m4_popdef([AT_API_PREFIX]) + m4_popdef([AT_API_prefix]) m4_popdef([AT_NAME_PREFIX]) m4_popdef([AT_GLR_OR_PARAM_IF]) m4_popdef([AT_PURE_AND_LOC_IF]) @@@ -230,7 -237,7 +242,7 @@@ m4_popdef([AT_SKEL_JAVA_IF] m4_popdef([AT_GLR_CC_IF]) m4_popdef([AT_LALR1_CC_IF]) m4_popdef([AT_DEFINES_IF]) - AT_LOC_POPDEF + AT_LOC_POPDEF])dnl ])# AT_BISON_OPTION_POPDEFS @@@ -287,7 -294,7 +299,7 @@@ $2] # AT_YYLEX_DEFINE(INPUT-STRING, [ACTION]) # --------------------------------------- m4_define([AT_YYLEX_PROTOTYPE], - [int AT_API_PREFIX[]lex (]AT_YYLEX_FORMALS[)[]dnl + [int AT_NAME_PREFIX[]lex (]AT_YYLEX_FORMALS[)[]dnl ]) m4_define([AT_YYLEX_DECLARE_EXTERN], @@@ -299,19 -306,19 +311,19 @@@ m4_define([AT_YYLEX_DECLARE] ]) m4_define([AT_YYLEX_DEFINE], - [[#include /* abort */ + [[#include static ]AT_YYLEX_PROTOTYPE[ { static char const input[] = "$1"; static size_t toknum = 0; int res; - if (! (toknum < sizeof input)) - abort (); + ]AT_USE_LEX_ARGS[; + assert (toknum < sizeof input); res = input[toknum++]; - ]$2;[]AT_LOCATION_IF([[ - ]AT_API_PREFIX[lloc.first_line = ]AT_API_PREFIX[lloc.last_line = 1; - ]AT_API_PREFIX[lloc.first_column = ]AT_API_PREFIX[lloc.last_column = toknum;]])[ + ]$2[;]AT_LOCATION_IF([[ + ]AT_LOC_FIRST_LINE[ = ]AT_LOC_LAST_LINE[ = 1; + ]AT_LOC_FIRST_COLUMN[ = ]AT_LOC_LAST_COLUMN[ = toknum;]])[ return res; }]dnl ]) @@@ -329,7 -336,7 +341,7 @@@ m4_define([AT_YYERROR_FORMALS] m4_define([AT_YYERROR_PROTOTYPE], [m4_case(AT_LANG, - [c], [[void ]AT_API_PREFIX[error (]AT_YYERROR_FORMALS[)]])[]dnl + [c], [[void ]AT_NAME_PREFIX[error (]AT_YYERROR_FORMALS[)]])[]dnl ]) m4_define([AT_YYERROR_DECLARE_EXTERN], @@@ -363,11 -370,13 +375,11 @@@ stati }]], [c++], [[/* A C++ error reporting function. */ void -]AT_NAME_PREFIX[::parser::error (const location_type& l, const std::string& m) -{ - (void) l; - std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl; +]AT_NAME_PREFIX[::parser::error (]AT_LOCATION_IF([[const location_type& l, ]])[const std::string& m) +{ std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl; }]], [java], [AT_LOCATION_IF([[public void yyerror (Calc.Location l, String s) - { +{ if (l == null) System.err.println (s); else @@@ -377,7 -386,7 +389,7 @@@ public void yyerror (String s) { System.err.println (s); - }]])])dnl +}]])])dnl ]) @@@ -540,22 -549,38 +552,38 @@@ m4_define([AT_QUELL_VALGRIND] # AT_COMPILE(OUTPUT, [SOURCES = OUTPUT.c]) # ---------------------------------------- - # Compile SOURCES into OUTPUT. If OUTPUT does not contain '.', - # assume that we are linking too; this is a hack. + # Compile SOURCES into OUTPUT. + # + # If OUTPUT does not contain '.', assume that we are linking too, + # otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT + # with trailing .o removed, and ".c" appended. m4_define([AT_COMPILE], - [AT_CHECK([$CC $CFLAGS $CPPFLAGS m4_bmatch([$1], [[.]], [], [$LDFLAGS ])-o $1 m4_default([$2], [$1.c])[]m4_bmatch([$1], [[.]], [], [ $LIBS])], + [AT_CHECK(m4_join([ ], + [$CC $CFLAGS $CPPFLAGS], + [m4_bmatch([$1], [[.]], [-c], [$LDFLAGS])], + [-o $1], + [m4_default([$2], [m4_bpatsubst([$1], [\.o$]).c])], + [m4_bmatch([$1], [[.]], [], [$LIBS])]), - 0, [ignore], [ignore])]) + 0, [ignore], [ignore])]) # AT_COMPILE_CXX(OUTPUT, [SOURCES = OUTPUT.cc]) - # -------------------------------------------- - # Compile SOURCES into OUTPUT. If OUTPUT does not contain '.', - # assume that we are linking too; this is a hack. - # If the C++ compiler does not work, ignore the test. + # --------------------------------------------- + # Compile SOURCES into OUTPUT. If the C++ compiler does not work, + # ignore the test. + # + # If OUTPUT does not contain '.', assume that we are linking too, + # otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT + # with trailing .o removed, and ".cc" appended. m4_define([AT_COMPILE_CXX], [AT_KEYWORDS(c++) AT_CHECK([$BISON_CXX_WORKS], 0, ignore, ignore) - AT_CHECK([$CXX $CXXFLAGS $CPPFLAGS m4_bmatch([$1], [[.]], [], [$LDFLAGS ])-o $1 m4_default([$2], [$1.cc])[]m4_bmatch([$1], [[.]], [], [ $LIBS])], + AT_CHECK(m4_join([ ], + [$CXX $CXXFLAGS $CPPFLAGS], + [m4_bmatch([$1], [[.]], [-c], [$LDFLAGS])], + [-o $1], + [m4_default([$2], [m4_bpatsubst([$1], [\.o$]).cc])], + [m4_bmatch([$1], [[.]], [], [$LIBS])]), - 0, [ignore], [ignore])]) + 0, [ignore], [ignore])]) # AT_JAVA_COMPILE(SOURCES) # ------------------------ @@@ -569,6 -594,11 +597,11 @@@ AT_CHECK([[$SHELL ../../../javacomp.sh # AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c] # -------------------------------------------- + # Compile SOURCES into OUTPUT. Skip if compiler does not work. + # + # If OUTPUT does not contain '.', assume that we are linking too, + # otherwise pass "-c"; this is a hack. The default SOURCES is OUTPUT + # with trailing .o removed, and ".c"/".cc" appended. m4_define([AT_LANG_COMPILE], [m4_case(AT_LANG, [c], [AT_COMPILE([$1], [$2])], @@@ -589,23 -619,23 +622,23 @@@ m4_define([AT_FULL_COMPILE] [java], [AT_BISON_CHECK([-o $1.java $1.y]) AT_LANG_COMPILE([$1], - m4_join([ ], - [$1.java], - m4_ifval($2, [[$1-$2.java]]), + m4_join([ ], + [$1.java], + m4_ifval($2, [[$1-$2.java]]), m4_ifval($3, [[$1-$3.java]])))], [c++], [AT_BISON_CHECK([-o $1.cc $1.y]) AT_LANG_COMPILE([$1], - m4_join([ ], - [$1.cc], - m4_ifval($2, [[$1-$2.cc]]), + m4_join([ ], + [$1.cc], + m4_ifval($2, [[$1-$2.cc]]), m4_ifval($3, [[$1-$3.cc]])))], [c], [AT_BISON_CHECK([-o $1.c $1.y]) AT_LANG_COMPILE([$1], - m4_join([ ], - [$1.c], - m4_ifval($2, [[$1-$2.c]]), + m4_join([ ], + [$1.c], + m4_ifval($2, [[$1-$2.c]]), m4_ifval($3, [[$1-$3.c]])))]) ]) diff --combined tests/named-refs.at index 0e6f60c8,3ccf1f66..2484c438 --- a/tests/named-refs.at +++ b/tests/named-refs.at @@@ -46,10 -46,10 +46,10 @@@ static int power (int base, int exponen %token NUM "number" %type exp -%nonassoc '=' /* comparison */ +%nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' -%left NEG /* negation--unary minus */ +%precedence NEG /* negation--unary minus */ %right '^' /* exponentiation */ %% @@@ -162,10 -162,8 +162,8 @@@ int main (int argc, const char **argv } status = yyparse (); fclose (input); - if (global_result != result) - abort (); - if (global_count != count) - abort (); + assert (global_result == result); + assert (global_count == count); return status; } ]]) @@@ -213,10 -211,10 +211,10 @@@ static int power (int base, int exponen %token NUM "number" %type exp -%nonassoc '=' /* comparison */ +%nonassoc '=' /* comparison */ %left '-' '+' %left '*' '/' -%left NEG /* negation--unary minus */ +%precedence NEG /* negation--unary minus */ %right '^' /* exponentiation */ %% diff --combined tests/regression.at index bc129b7c,ac7d55ee..b23cbcfd --- a/tests/regression.at +++ b/tests/regression.at @@@ -41,7 -41,7 +41,7 @@@ program: 'x' AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y]) - AT_COMPILE([input.o], [-c input.c]) + AT_COMPILE([input.o]) AT_COMPILE([input.o], [-DYYDEBUG -c input.c]) AT_CLEANUP @@@ -71,7 -71,7 +71,7 @@@ program: { $$ = ""; } AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y]) - AT_COMPILE([input.o], [-c input.c]) + AT_COMPILE([input.o]) AT_CLEANUP @@@ -111,7 -111,7 +111,7 @@@ exp: MY_TOKEN AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-y -o input.c input.y]) - AT_COMPILE([input.o], [-c input.c]) + AT_COMPILE([input.o]) AT_CLEANUP @@@ -156,7 -156,7 +156,7 @@@ exp: MY_TOKEN AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y]) - AT_COMPILE([input.o], [-c input.c]) + AT_COMPILE([input.o]) AT_CLEANUP @@@ -527,7 -527,7 +527,7 @@@ exp AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([-o input.c input.y]) - AT_COMPILE([input.o], [-c input.c]) + AT_COMPILE([input.o]) AT_CLEANUP @@@ -546,7 -546,7 +546,7 @@@ AT_SETUP([Web2c Report] AT_KEYWORDS([report]) AT_DATA([input.y], -[[%token undef_id_tok const_id_tok +[[%token undef_id_tok const_id_tok %start CONST_DEC_PART @@@ -556,12 -556,12 +556,12 @@@ CONST_DEC_PART ; CONST_DEC_LIST: - CONST_DEC + CONST_DEC | CONST_DEC_LIST CONST_DEC ; CONST_DEC: - { } undef_id_tok '=' const_id_tok ';' + { } undef_id_tok '=' const_id_tok ';' ; %% ]]) @@@ -767,6 -767,15 +767,6 @@@ AT_CHECK([[cat tables.c]], 0 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6 }; -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 5, 6, 9, 14 -}; -static const yytype_int8 yyrhs[] = -{ - 8, 0, -1, 9, -1, -1, 10, 11, -1, 3, - 4, 5, 8, -1, 6, 8, -1 -}; static const yytype_uint8 yyrline[] = { 0, 2, 2, 3, 3, 4, 5 @@@ -780,24 -789,32 +780,24 @@@ static const yytype_uint16 yytoknum[] { 0, 256, 257, 258, 259, 260, 261 }; -static const yytype_uint8 yyr1[] = -{ - 0, 7, 8, 9, 9, 10, 11 -}; -static const yytype_uint8 yyr2[] = +static const yytype_int8 yypact[] = { - 0, 2, 1, 0, 2, 4, 2 + -2, -1, 4, -8, 0, 2, -8, -2, -8, -2, + -8, -8 }; static const yytype_uint8 yydefact[] = { 3, 0, 0, 2, 0, 0, 1, 3, 4, 3, 6, 5 }; -static const yytype_int8 yydefgoto[] = -{ - -1, 2, 3, 4, 8 -}; -static const yytype_int8 yypact[] = -{ - -2, -1, 4, -8, 0, 2, -8, -2, -8, -2, - -8, -8 -}; static const yytype_int8 yypgoto[] = { -8, -7, -8, -8, -8 }; +static const yytype_int8 yydefgoto[] = +{ + -1, 2, 3, 4, 8 +}; static const yytype_uint8 yytable[] = { 10, 1, 11, 5, 6, 0, 7, 9 @@@ -811,14 -828,6 +811,14 @@@ static const yytype_uint8 yystos[] 0, 3, 8, 9, 10, 4, 0, 6, 11, 5, 8, 8 }; +static const yytype_uint8 yyr1[] = +{ + 0, 7, 8, 9, 9, 10, 11 +}; +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 0, 2, 4, 2 +}; ]]) AT_CLEANUP @@@ -839,7 -848,7 +839,7 @@@ m4_define([_AT_DATA_DANCER_Y] [AT_DATA_GRAMMAR([dancer.y], [%{ static int yylex (AT_LALR1_CC_IF([int *], [void])); -AT_LALR1_CC_IF([], +AT_LALR1_CC_IF([#include ], [#include #include ]AT_YYERROR_DECLARE[]) @@@ -901,6 -910,7 +901,7 @@@ yyparse ( } ]) + #include static int yylex (AT_LALR1_CC_IF([int *lval], [void])) [{ @@@ -910,8 -920,7 +911,7 @@@ }; static size_t toknum; ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[ - if (! (toknum < sizeof tokens / sizeof *tokens)) - abort (); + assert (toknum < sizeof tokens / sizeof *tokens); return tokens[toknum++]; }] @@@ -954,11 -963,11 +954,11 @@@ AT_CHECK_DANCER([%skeleton "lalr1.cc"] # -------------------------------- m4_define([_AT_DATA_EXPECT2_Y], [AT_DATA_GRAMMAR([expect2.y], -[[%{ -static int yylex (]AT_LALR1_CC_IF([int *], [void])); -AT_LALR1_CC_IF([], -[[#include -#include +[%{ +static int yylex (AT_LALR1_CC_IF([int *], [void])); +AT_LALR1_CC_IF([[#include ]], +[[#include +#include ]AT_YYERROR_DECLARE])[ %} $1 @@@ -986,6 -995,7 +986,7 @@@ yyparse ( } ])[ + #include static int yylex (]AT_LALR1_CC_IF([int *lval], [void])[) { @@@ -995,8 -1005,7 +996,7 @@@ }; static size_t toknum; ]AT_LALR1_CC_IF([*lval = 0; /* Pacify GCC. */])[ - if (! (toknum < sizeof tokens / sizeof *tokens)) - abort (); + assert (toknum < sizeof tokens / sizeof *tokens); return tokens[toknum++]; } @@@ -1054,7 -1063,7 +1054,7 @@@ AT_DATA_GRAMMAR([input.y] start: { printf ("Bison would once convert this action to a midrule because of the" - " subsequent braced code.\n"); + " subsequent braced code.\n"); } ; @@@ -1237,9 -1246,8 +1237,9 @@@ AT_CLEANU AT_SETUP([[parse-gram.y: LALR = IELR]]) -# Avoid differences in synclines by telling bison that the output files -# have the same name. +# Avoid tests/bison's dark magic by processing a local copy of the +# grammar. Avoid differences in synclines by telling bison that the +# output files have the same name. [cp $abs_top_srcdir/src/parse-gram.y input.y] AT_BISON_CHECK([[-o input.c -Dlr.type=lalr input.y]]) [mv input.c lalr.c] @@@ -1253,11 -1261,11 +1253,11 @@@ AT_CLEANU -## --------------------------------------- ## -## %error-verbose and YYSTACK_USE_ALLOCA. ## -## --------------------------------------- ## +## -------------------------------------------- ## +## parse.error=verbose and YYSTACK_USE_ALLOCA. ## +## -------------------------------------------- ## -AT_SETUP([[%error-verbose and YYSTACK_USE_ALLOCA]]) +AT_SETUP([[parse.error=verbose and YYSTACK_USE_ALLOCA]]) AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], @@@ -1268,7 -1276,7 +1268,7 @@@ #define YYSTACK_USE_ALLOCA 1 } -%error-verbose +%define parse.error verbose %% @@@ -1301,9 -1309,9 +1301,9 @@@ syntax_error %% ]AT_YYERROR_DEFINE[ -/* Induce two syntax error messages (which requires full error - recovery by shifting 3 tokens) in order to detect any loss of the - reallocated buffer. */ + /* Induce two syntax error messages (which requires full error + recovery by shifting 3 tokens) in order to detect any loss of the + reallocated buffer. */ ]AT_YYLEX_DEFINE([abc])[ int main (void) @@@ -1324,9 -1332,9 +1324,9 @@@ AT_CLEANU -## ------------------------- ## -## %error-verbose overflow. ## -## ------------------------- ## +## ------------------------------ ## +## parse.error=verbose overflow. ## +## ------------------------------ ## # Imagine the case where YYSTACK_ALLOC_MAXIMUM = YYSIZE_MAXIMUM and an # invocation of yysyntax_error has caused yymsg_alloc to grow to exactly @@@ -1336,8 -1344,7 +1336,8 @@@ # size calculation would return YYSIZE_MAXIMUM to yyparse. Then, # yyparse would invoke yyerror using the old contents of yymsg. -AT_SETUP([[%error-verbose overflow]]) +AT_SETUP([[parse.error=verbose overflow]]) + AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([input.y], [[%code { @@@ -1362,7 -1369,7 +1362,7 @@@ #define YYMAXDEPTH 100 } -%error-verbose +%define parse.error verbose %% @@@ -1410,8 -1417,8 +1410,8 @@@ syntax_error2 %% ]AT_YYERROR_DEFINE[ -/* Induce two syntax error messages (which requires full error - recovery by shifting 3 tokens). */ + /* Induce two syntax error messages (which requires full error + recovery by shifting 3 tokens). */ ]AT_YYLEX_DEFINE([abc])[ int main (void) @@@ -1461,7 -1468,7 +1461,7 @@@ AT_DATA_GRAMMAR([input.y] } ]$1[ -%error-verbose +%define parse.error verbose %token 'c' %%