From 14da0cdd075600829a4373b97645e75a8b1310ac Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Tue, 4 Nov 2008 13:26:59 -0500 Subject: [PATCH 001/404] Fix user actions without a trailing semicolon. Reported by Sergei Steshenko at . * THANKS (Sergei Steshenko): Add. * src/scan-code.l (SC_RULE_ACTION): Fix it. * tests/regression.at (Fix user actions without a trailing semicolon): New test case. --- ChangeLog | 10 ++++++++++ THANKS | 1 + src/scan-code.l | 4 ++-- tests/regression.at | 26 +++++++++++++++++++++++++- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca2c184f..08c5417b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-11-04 Joel E. Denny + + Fix user actions without a trailing semicolon. + Reported by Sergei Steshenko at + . + * THANKS (Sergei Steshenko): Add. + * src/scan-code.l (SC_RULE_ACTION): Fix it. + * tests/regression.at (Fix user actions without a trailing semicolon): + New test case. + 2008-11-02 Joel E. Denny Initiate further development. diff --git a/THANKS b/THANKS index 6785e2a8..5f88c6c2 100644 --- a/THANKS +++ b/THANKS @@ -79,6 +79,7 @@ Robert Anisko anisko_r@epita.fr Satya Kiran Popuri satyakiran@gmail.com Sebastien Fricker sebastien.fricker@gmail.com Sebastian Setzer sebastian.setzer.ext@siemens.com +Sergei Steshenko sergstesh@yahoo.com Shura debil_urod@ngs.ru Steve Murphy murf@parsetree.com Tim Josling tej@melbpc.org.au diff --git a/src/scan-code.l b/src/scan-code.l index 630d45d5..71c90768 100644 --- a/src/scan-code.l +++ b/src/scan-code.l @@ -1,6 +1,6 @@ /* Bison Action Scanner -*- C -*- - Copyright (C) 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -170,7 +170,7 @@ splice (\\[ \f\t\v]*\n)* "{" STRING_GROW; ++braces_level; "}" { - bool outer_brace = --braces_level < 0; + bool outer_brace = --braces_level == 0; /* As an undocumented Bison extension, append `;' before the last brace in braced code, so that the user code can omit trailing diff --git a/tests/regression.at b/tests/regression.at index 51bf3f30..6bfc8d09 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -1201,7 +1201,7 @@ AT_CLEANUP ## Token number in precedence declaration. ## ## ---------------------------------------- ## -AT_SETUP([[Token number in precedence declaration.]]) +AT_SETUP([[Token number in precedence declaration]]) # POSIX says token numbers can be declared in %left, %right, and %nonassoc, but # we lost this in Bison 1.50. @@ -1255,3 +1255,27 @@ AT_COMPILE([[input]]) AT_PARSER_CHECK([[./input]]) AT_CLEANUP + + + +## ----------------------------------------------- ## +## Fix user actions without a trailing semicolon. ## +## ----------------------------------------------- ## + +AT_SETUP([[Fix user actions without a trailing semicolon]]) + +# This feature is undocumented, but we accidentally broke it in 2.3a, and there +# was a complaint at: +# . + +AT_DATA([input.y], +[[%% +start: {asdffdsa} ; +]]) + +AT_BISON_CHECK([[-o input.c input.y]]) +AT_CHECK([[sed -n '/asdffdsa/s/^ *//p' input.c]], [[0]], +[[{asdffdsa;} +]]) + +AT_CLEANUP From d6fb461dd8b8ce881af052e4d8b5cfc4e8c2178b Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 4 Nov 2008 22:18:28 +0100 Subject: [PATCH 002/404] Reformat NEWS. * NEWS: Use more outline-mode markup. Suggested by Jim Meyering. --- ChangeLog | 6 + NEWS | 372 +++++++++++++++++++++++++++--------------------------- 2 files changed, 192 insertions(+), 186 deletions(-) diff --git a/ChangeLog b/ChangeLog index 08c5417b..ec760d69 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-11-04 Akim Demaille + + Reformat NEWS. + * NEWS: Use more outline-mode markup. + Suggested by Jim Meyering. + 2008-11-04 Joel E. Denny Fix user actions without a trailing semicolon. diff --git a/NEWS b/NEWS index dcaa386d..d63c9500 100644 --- a/NEWS +++ b/NEWS @@ -1,13 +1,13 @@ Bison News ---------- -Changes in version ?.? (????-??-??): +* Changes in version ?.? (????-??-??): -* +** -Changes in version 2.4 (2008-11-02): +* Changes in version 2.4 (2008-11-02): -* %language is an experimental feature. +** %language is an experimental feature. We first introduced this feature in test release 2.3b as a cleaner alternative to %skeleton. Since then, we have discussed the possibility of @@ -15,26 +15,26 @@ Changes in version 2.4 (2008-11-02): we consider %language to be an experimental feature that will likely evolve in future releases. -* Forward compatibility with GNU M4 has been improved. +** Forward compatibility with GNU M4 has been improved. -* Several bugs in the C++ skeleton and the experimental Java skeleton have been +** Several bugs in the C++ skeleton and the experimental Java skeleton have been fixed. -Changes in version 2.3b (2008-05-27): +* Changes in version 2.3b (2008-05-27): -* The quotes around NAME that used to be required in the following directive +** The quotes around NAME that used to be required in the following directive are now deprecated: %define NAME "VALUE" -* The directive `%pure-parser' is now deprecated in favor of: +** The directive `%pure-parser' is now deprecated in favor of: %define api.pure which has the same effect except that Bison is more careful to warn about unreasonable usage in the latter case. -* Push Parsing +** Push Parsing Bison can now generate an LALR(1) parser in C with a push interface. That is, instead of invoking `yyparse', which pulls tokens from `yylex', you can @@ -50,11 +50,11 @@ Changes in version 2.3b (2008-05-27): The current push parsing interface is experimental and may evolve. More user feedback will help to stabilize it. -* The -g and --graph options now output graphs in Graphviz DOT format, +** The -g and --graph options now output graphs in Graphviz DOT format, not VCG format. Like --graph, -g now also takes an optional FILE argument and thus cannot be bundled with other short options. -* Java +** Java Bison can now generate an LALR(1) parser in Java. The skeleton is `data/lalr1.java'. Consider using the new %language directive instead of @@ -65,30 +65,30 @@ Changes in version 2.3b (2008-05-27): The current Java interface is experimental and may evolve. More user feedback will help to stabilize it. -* %language +** %language This new directive specifies the programming language of the generated parser, which can be C (the default), C++, or Java. Besides the skeleton that Bison uses, the directive affects the names of the generated files if the grammar file's name ends in ".y". -* XML Automaton Report +** XML Automaton Report Bison can now generate an XML report of the LALR(1) automaton using the new `--xml' option. The current XML schema is experimental and may evolve. More user feedback will help to stabilize it. -* The grammar file may now specify the name of the parser header file using +** The grammar file may now specify the name of the parser header file using %defines. For example: %defines "parser.h" -* When reporting useless rules, useless nonterminals, and unused terminals, +** When reporting useless rules, useless nonterminals, and unused terminals, Bison now employs the terms "useless in grammar" instead of "useless", "useless in parser" instead of "never reduced", and "unused in grammar" instead of "unused". -* Unreachable State Removal +** Unreachable State Removal Previously, Bison sometimes generated parser tables containing unreachable states. A state can become unreachable during conflict resolution if Bison @@ -110,7 +110,7 @@ Changes in version 2.3b (2008-05-27): See the %define entry in the `Bison Declaration Summary' in the Bison manual for further discussion. -* Lookahead Set Correction in the `.output' Report +** Lookahead Set Correction in the `.output' Report When instructed to generate a `.output' file including lookahead sets (using `--report=lookahead', for example), Bison now prints each reduction's @@ -121,17 +121,17 @@ Changes in version 2.3b (2008-05-27): bug affected only the `.output' file and not the generated parser source code. -* --report-file=FILE is a new option to override the default `.output' file +** --report-file=FILE is a new option to override the default `.output' file name. -* The `=' that used to be required in the following directives is now +** The `=' that used to be required in the following directives is now deprecated: %file-prefix "parser" %name-prefix "c_" %output "parser.c" -* An Alternative to `%{...%}' -- `%code QUALIFIER {CODE}' +** An Alternative to `%{...%}' -- `%code QUALIFIER {CODE}' Bison 2.3a provided a new set of directives as a more flexible alternative to the traditional Yacc prologue blocks. Those have now been consolidated into @@ -152,7 +152,7 @@ Changes in version 2.3b (2008-05-27): The prologue alternatives are experimental. More user feedback will help to determine whether they should become permanent features. -* Revised warning: unset or unused mid-rule values +** Revised warning: unset or unused mid-rule values Since Bison 2.2, Bison has warned about mid-rule values that are set but not used within any of the actions of the parent rule. For example, Bison warns @@ -172,7 +172,7 @@ Changes in version 2.3b (2008-05-27): To enable these warnings, specify the option `--warnings=midrule-values' or `-W', which is a synonym for `--warnings=all'. -* Default %destructor or %printer with `<*>' or `<>' +** Default %destructor or %printer with `<*>' or `<>' Bison now recognizes two separate kinds of default %destructor's and %printer's: @@ -197,25 +197,25 @@ Changes in version 2.3b (2008-05-27): See the section `Freeing Discarded Symbols' in the Bison manual for further details. -* %left, %right, and %nonassoc can now declare token numbers. This is required +** %left, %right, and %nonassoc can now declare token numbers. This is required by POSIX. However, see the end of section `Operator Precedence' in the Bison manual for a caveat concerning the treatment of literal strings. -* The nonfunctional --no-parser, -n, and %no-parser options have been +** The nonfunctional --no-parser, -n, and %no-parser options have been completely removed from Bison. -Changes in version 2.3a, 2006-09-13: +* Changes in version 2.3a, 2006-09-13: -* Instead of %union, you can define and use your own union type +** Instead of %union, you can define and use your own union type YYSTYPE if your grammar contains at least one tag. Your YYSTYPE need not be a macro; it can be a typedef. This change is for compatibility with other Yacc implementations, and is required by POSIX. -* Locations columns and lines start at 1. +** Locations columns and lines start at 1. In accordance with the GNU Coding Standards and Emacs. -* You may now declare per-type and default %destructor's and %printer's: +** You may now declare per-type and default %destructor's and %printer's: For example: @@ -241,13 +241,13 @@ Changes in version 2.3a, 2006-09-13: %destructor's and %printer's were experimental, and they were rewritten in future versions.] -* Except for LALR(1) parsers in C with POSIX Yacc emulation enabled (with `-y', +** Except for LALR(1) parsers in C with POSIX Yacc emulation enabled (with `-y', `--yacc', or `%yacc'), Bison no longer generates #define statements for associating token numbers with token names. Removing the #define statements helps to sanitize the global namespace during preprocessing, but POSIX Yacc requires them. Bison still generates an enum for token names in all cases. -* Handling of traditional Yacc prologue blocks is now more consistent but +** Handling of traditional Yacc prologue blocks is now more consistent but potentially incompatible with previous releases of Bison. As before, you declare prologue blocks in your grammar file with the @@ -266,7 +266,7 @@ Changes in version 2.3a, 2006-09-13: Now, Bison never inserts the pre-prologue into the header file. In the code file, it always inserts it before the token definitions. -* Bison now provides a more flexible alternative to the traditional Yacc +** Bison now provides a more flexible alternative to the traditional Yacc prologue blocks: %before-header, %start-header, %end-header, and %after-header. @@ -314,32 +314,32 @@ Changes in version 2.3a, 2006-09-13: [Although we failed to mention this here in the 2.3a release, the prologue alternatives were experimental, and they were rewritten in future versions.] -* The option `--report=look-ahead' has been changed to `--report=lookahead'. +** The option `--report=look-ahead' has been changed to `--report=lookahead'. The old spelling still works, but is not documented and may be removed in a future release. -Changes in version 2.3, 2006-06-05: +* Changes in version 2.3, 2006-06-05: -* GLR grammars should now use `YYRECOVERING ()' instead of `YYRECOVERING', +** GLR grammars should now use `YYRECOVERING ()' instead of `YYRECOVERING', for compatibility with LALR(1) grammars. -* It is now documented that any definition of YYSTYPE or YYLTYPE should +** It is now documented that any definition of YYSTYPE or YYLTYPE should be to a type name that does not contain parentheses or brackets. -Changes in version 2.2, 2006-05-19: +* Changes in version 2.2, 2006-05-19: -* The distribution terms for all Bison-generated parsers now permit +** The distribution terms for all Bison-generated parsers now permit using the parsers in nonfree programs. Previously, this permission was granted only for Bison-generated LALR(1) parsers in C. -* %name-prefix changes the namespace name in C++ outputs. +** %name-prefix changes the namespace name in C++ outputs. -* The C++ parsers export their token_type. +** The C++ parsers export their token_type. -* Bison now allows multiple %union declarations, and concatenates +** Bison now allows multiple %union declarations, and concatenates their contents together. -* New warning: unused values +** New warning: unused values Right-hand side symbols whose values are not used are reported, if the symbols have destructors. For instance: @@ -373,26 +373,26 @@ Changes in version 2.2, 2006-05-19: The warning is intended to help catching lost values and memory leaks. If a value is ignored, its associated memory typically is not reclaimed. -* %destructor vs. YYABORT, YYACCEPT, and YYERROR. +** %destructor vs. YYABORT, YYACCEPT, and YYERROR. Destructors are now called when user code invokes YYABORT, YYACCEPT, and YYERROR, for all objects on the stack, other than objects corresponding to the right-hand side of the current rule. -* %expect, %expect-rr +** %expect, %expect-rr Incorrect numbers of expected conflicts are now actual errors, instead of warnings. -* GLR, YACC parsers. +** GLR, YACC parsers. The %parse-params are available in the destructors (and the experimental printers) as per the documentation. -* Bison now warns if it finds a stray `$' or `@' in an action. +** Bison now warns if it finds a stray `$' or `@' in an action. -* %require "VERSION" +** %require "VERSION" This specifies that the grammar file depends on features implemented in Bison version VERSION or higher. -* lalr1.cc: The token and value types are now class members. +** lalr1.cc: The token and value types are now class members. The tokens were defined as free form enums and cpp macros. YYSTYPE was defined as a free form union. They are now class members: tokens are enumerations of the `yy::parser::token' struct, and the @@ -406,37 +406,37 @@ Changes in version 2.2, 2006-05-19: If you wish to update, then make sure older version of Bison will fail using `%require "2.2"'. -* DJGPP support added. +** DJGPP support added. -Changes in version 2.1, 2005-09-16: +* Changes in version 2.1, 2005-09-16: -* The C++ lalr1.cc skeleton supports %lex-param. +** The C++ lalr1.cc skeleton supports %lex-param. -* Bison-generated parsers now support the translation of diagnostics like +** Bison-generated parsers now support the translation of diagnostics like "syntax error" into languages other than English. The default language is still English. For details, please see the new Internationalization section of the Bison manual. Software distributors should also see the new PACKAGING file. Thanks to Bruno Haible for this new feature. -* Wording in the Bison-generated parsers has been changed slightly to +** Wording in the Bison-generated parsers has been changed slightly to simplify translation. In particular, the message "memory exhausted" has replaced "parser stack overflow", as the old message was not always accurate for modern Bison-generated parsers. -* Destructors are now called when the parser aborts, for all symbols left +** Destructors are now called when the parser aborts, for all symbols left behind on the stack. Also, the start symbol is now destroyed after a successful parse. In both cases, the behavior was formerly inconsistent. -* When generating verbose diagnostics, Bison-generated parsers no longer +** When generating verbose diagnostics, Bison-generated parsers no longer quote the literal strings associated with tokens. For example, for a syntax error associated with '%token NUM "number"' they might print 'syntax error, unexpected number' instead of 'syntax error, unexpected "number"'. -Changes in version 2.0, 2004-12-25: +* Changes in version 2.0, 2004-12-25: -* Possibly-incompatible changes +** Possibly-incompatible changes - Bison-generated parsers no longer default to using the alloca function (when available) to extend the parser stack, due to widespread @@ -461,7 +461,7 @@ Changes in version 2.0, 2004-12-25: - NUL bytes are no longer allowed in Bison string literals, unfortunately. -* New features +** New features - GLR grammars now support locations. @@ -483,7 +483,7 @@ Changes in version 2.0, 2004-12-25: - New configure option --disable-yacc, to disable installation of the yacc command and -ly library introduced in 1.875 for POSIX conformance. -* Bug fixes +** Bug fixes - For now, %expect-count violations are now just warnings, not errors. This is for compatibility with Bison 1.75 and earlier (when there are @@ -497,12 +497,12 @@ Changes in version 2.0, 2004-12-25: - Semicolons are now allowed before "|" in grammar rules, as POSIX requires. -Changes in version 1.875, 2003-01-01: +* Changes in version 1.875, 2003-01-01: -* The documentation license has been upgraded to version 1.2 +** The documentation license has been upgraded to version 1.2 of the GNU Free Documentation License. -* syntax error processing +** syntax error processing - In Yacc-style parsers YYLLOC_DEFAULT is now used to compute error locations too. This fixes bugs in error-location computation. @@ -517,7 +517,7 @@ Changes in version 1.875, 2003-01-01: - #defining yyerror to steal internal variables is discouraged. It is not guaranteed to work forever. -* POSIX conformance +** POSIX conformance - Semicolons are once again optional at the end of grammar rules. This reverts to the behavior of Bison 1.33 and earlier, and improves @@ -550,7 +550,7 @@ Changes in version 1.875, 2003-01-01: using typedef instead of defining it as a macro. For consistency, YYLTYPE is also declared instead of defined. -* Other compatibility issues +** Other compatibility issues - %union directives can now have a tag before the `{', e.g., the directive `%union foo {...}' now generates the C code @@ -569,7 +569,7 @@ Changes in version 1.875, 2003-01-01: typedefs or tags; they are no longer documented and are planned to be withdrawn in a future release. -* GLR parser notes +** GLR parser notes - GLR and inline Users of Bison have to decide how they handle the portability of the @@ -578,32 +578,32 @@ Changes in version 1.875, 2003-01-01: - `parsing stack overflow...' -> `parser stack overflow' GLR parsers now report `parser stack overflow' as per the Bison manual. -* Bison now warns if it detects conflicting outputs to the same file, +** Bison now warns if it detects conflicting outputs to the same file, e.g., it generates a warning for `bison -d -o foo.h foo.y' since that command outputs both code and header to foo.h. -* #line in output files +** #line in output files - --no-line works properly. -* Bison can no longer be built by a K&R C compiler; it requires C89 or +** Bison can no longer be built by a K&R C compiler; it requires C89 or later to be built. This change originally took place a few versions ago, but nobody noticed until we recently asked someone to try building Bison with a K&R C compiler. -Changes in version 1.75, 2002-10-14: +* Changes in version 1.75, 2002-10-14: -* Bison should now work on 64-bit hosts. +** Bison should now work on 64-bit hosts. -* Indonesian translation thanks to Tedi Heriyanto. +** Indonesian translation thanks to Tedi Heriyanto. -* GLR parsers +** GLR parsers Fix spurious parse errors. -* Pure parsers +** Pure parsers Some people redefine yyerror to steal yyparse' private variables. Reenable this trick until an official feature replaces it. -* Type Clashes +** Type Clashes In agreement with POSIX and with other Yaccs, leaving a default action is valid when $$ is untyped, and $1 typed: @@ -613,7 +613,7 @@ Changes in version 1.75, 2002-10-14: typed: ... untyped; -* Values of mid-rule actions +** Values of mid-rule actions The following code: foo: { ... } { $$ = $1; } ... @@ -621,9 +621,9 @@ Changes in version 1.75, 2002-10-14: was incorrectly rejected: $1 is defined in the second mid-rule action, and is equal to the $$ of the first mid-rule action. -Changes in version 1.50, 2002-10-04: +* Changes in version 1.50, 2002-10-04: -* GLR parsing +** GLR parsing The declaration %glr-parser causes Bison to produce a Generalized LR (GLR) parser, capable of handling @@ -634,33 +634,33 @@ Changes in version 1.50, 2002-10-04: Unfortunately Bison 1.50 does not work properly on 64-bit hosts like the Alpha, so please stick to 32-bit hosts for now. -* Output Directory +** Output Directory When not in Yacc compatibility mode, when the output file was not specified, running `bison foo/bar.y' created `foo/bar.c'. It now creates `bar.c'. -* Undefined token +** Undefined token The undefined token was systematically mapped to 2 which prevented the use of 2 by the user. This is no longer the case. -* Unknown token numbers +** Unknown token numbers If yylex returned an out of range value, yyparse could die. This is no longer the case. -* Error token +** Error token According to POSIX, the error token must be 256. Bison extends this requirement by making it a preference: *if* the user specified that one of her tokens is numbered 256, then error will be mapped onto another number. -* Verbose error messages +** Verbose error messages They no longer report `..., expecting error or...' for states where error recovery is possible. -* End token +** End token Defaults to `$end' instead of `$'. -* Error recovery now conforms to documentation and to POSIX +** Error recovery now conforms to documentation and to POSIX When a Bison-generated parser encounters a syntax error, it now pops the stack until it finds a state that allows shifting the error token. Formerly, it popped the stack until it found a state that @@ -670,32 +670,32 @@ Changes in version 1.50, 2002-10-04: Paul Eggert, "Reductions during Bison error handling" (2002-05-20) . -* Traces +** Traces Popped tokens and nonterminals are now reported. -* Larger grammars +** Larger grammars Larger grammars are now supported (larger token numbers, larger grammar size (= sum of the LHS and RHS lengths), larger LALR tables). Formerly, many of these numbers ran afoul of 16-bit limits; now these limits are 32 bits on most hosts. -* Explicit initial rule +** Explicit initial rule Bison used to play hacks with the initial rule, which the user does not write. It is now explicit, and visible in the reports and graphs as rule 0. -* Useless rules +** Useless rules Before, Bison reported the useless rules, but, although not used, included them in the parsers. They are now actually removed. -* Useless rules, useless nonterminals +** Useless rules, useless nonterminals They are now reported, as a warning, with their locations. -* Rules never reduced +** Rules never reduced Rules that can never be reduced because of conflicts are now reported. -* Incorrect `Token not used' +** Incorrect `Token not used' On a grammar such as %token useless useful @@ -705,16 +705,16 @@ Changes in version 1.50, 2002-10-04: where a token was used to set the precedence of the last rule, bison reported both `useful' and `useless' as useless tokens. -* Revert the C++ namespace changes introduced in 1.31 +** Revert the C++ namespace changes introduced in 1.31 as they caused too many portability hassles. -* Default locations +** Default locations By an accident of design, the default computation of @$ was performed after another default computation was performed: @$ = @1. The latter is now removed: YYLLOC_DEFAULT is fully responsible of the computation of @$. -* Token end-of-file +** Token end-of-file The token end of file may be specified by the user, in which case, the user symbol is used in the reports, the graphs, and the verbose error messages instead of `$end', which remains being the default. @@ -723,22 +723,22 @@ Changes in version 1.50, 2002-10-04: or %token MYEOF 0 "end of file" -* Semantic parser +** Semantic parser This old option, which has been broken for ages, is removed. -* New translations +** New translations Brazilian Portuguese, thanks to Alexandre Folle de Menezes. Croatian, thanks to Denis Lackovic. -* Incorrect token definitions +** Incorrect token definitions When given `%token 'a' "A"', Bison used to output `#define 'a' 65'. -* Token definitions as enums +** Token definitions as enums Tokens are output both as the traditional #define's, and, provided the compiler supports ANSI C or is a C++ compiler, as enums. This lets debuggers display names instead of integers. -* Reports +** Reports In addition to --verbose, bison supports --report=THINGS, which produces additional information: - itemset @@ -750,7 +750,7 @@ Changes in version 1.50, 2002-10-04: Bison used to systematically output this information on top of the report. Solved conflicts are now attached to their states. -* Type clashes +** Type clashes 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: @@ -760,11 +760,11 @@ Changes in version 1.50, 2002-10-04: This is fixed. -* GNU M4 is now required when using Bison. +** GNU M4 is now required when using Bison. -Changes in version 1.35, 2002-03-25: +* Changes in version 1.35, 2002-03-25: -* C Skeleton +** C Skeleton Some projects use Bison's C parser with C++ compilers, and define YYSTYPE as a class. The recent adjustment of C parsers for data alignment and 64 bit architectures made this impossible. @@ -777,234 +777,234 @@ Changes in version 1.35, 2002-03-25: This kludge also addresses some C++ problems when the stack was extended. -Changes in version 1.34, 2002-03-12: +* Changes in version 1.34, 2002-03-12: -* File name clashes are detected +** File name clashes are detected $ bison foo.y -d -o foo.x fatal error: header and parser would both be named `foo.x' -* A missing `;' at the end of a rule triggers a warning +** A missing `;' at the end of a rule triggers a warning In accordance with POSIX, and in agreement with other Yacc implementations, Bison will mandate this semicolon in the near future. This eases the implementation of a Bison parser of Bison grammars by making this grammar LALR(1) instead of LR(2). To facilitate the transition, this release introduces a warning. -* Revert the C++ namespace changes introduced in 1.31, as they caused too +** Revert the C++ namespace changes introduced in 1.31, as they caused too many portability hassles. -* DJGPP support added. +** DJGPP support added. -* Fix test suite portability problems. +** Fix test suite portability problems. -Changes in version 1.33, 2002-02-07: +* Changes in version 1.33, 2002-02-07: -* Fix C++ issues +** Fix C++ issues Groff could not be compiled for the definition of size_t was lacking under some conditions. -* Catch invalid @n +** Catch invalid @n As is done with $n. -Changes in version 1.32, 2002-01-23: +* Changes in version 1.32, 2002-01-23: -* Fix Yacc output file names +** Fix Yacc output file names -* Portability fixes +** Portability fixes -* Italian, Dutch translations +** Italian, Dutch translations -Changes in version 1.31, 2002-01-14: +* Changes in version 1.31, 2002-01-14: -* Many Bug Fixes +** Many Bug Fixes -* GNU Gettext and %expect +** GNU Gettext and %expect GNU Gettext asserts 10 s/r conflicts, but there are 7. Now that Bison dies on incorrect %expectations, we fear there will be too many bug reports for Gettext, so _for the time being_, %expect does not trigger an error when the input file is named `plural.y'. -* Use of alloca in parsers +** Use of alloca in parsers If YYSTACK_USE_ALLOCA is defined to 0, then the parsers will use malloc exclusively. Since 1.29, but was not NEWS'ed. alloca is used only when compiled with GCC, to avoid portability problems as on AIX. -* yyparse now returns 2 if memory is exhausted; formerly it dumped core. +** yyparse now returns 2 if memory is exhausted; formerly it dumped core. -* When the generated parser lacks debugging code, YYDEBUG is now 0 +** When the generated parser lacks debugging code, YYDEBUG is now 0 (as POSIX requires) instead of being undefined. -* User Actions +** User Actions Bison has always permitted actions such as { $$ = $1 }: it adds the ending semicolon. Now if in Yacc compatibility mode, the semicolon is no longer output: one has to write { $$ = $1; }. -* Better C++ compliance +** Better C++ compliance The output parsers try to respect C++ namespaces. [This turned out to be a failed experiment, and it was reverted later.] -* Reduced Grammars +** Reduced Grammars Fixed bugs when reporting useless nonterminals. -* 64 bit hosts +** 64 bit hosts The parsers work properly on 64 bit hosts. -* Error messages +** Error messages Some calls to strerror resulted in scrambled or missing error messages. -* %expect +** %expect When the number of shift/reduce conflicts is correct, don't issue any warning. -* The verbose report includes the rule line numbers. +** The verbose report includes the rule line numbers. -* Rule line numbers are fixed in traces. +** Rule line numbers are fixed in traces. -* Swedish translation +** Swedish translation -* Parse errors +** Parse errors Verbose parse error messages from the parsers are better looking. Before: parse error: unexpected `'/'', expecting `"number"' or `'-'' or `'('' Now: parse error: unexpected '/', expecting "number" or '-' or '(' -* Fixed parser memory leaks. +** Fixed parser memory leaks. When the generated parser was using malloc to extend its stacks, the previous allocations were not freed. -* Fixed verbose output file. +** Fixed verbose output file. Some newlines were missing. Some conflicts in state descriptions were missing. -* Fixed conflict report. +** Fixed conflict report. Option -v was needed to get the result. -* %expect +** %expect Was not used. Mismatches are errors, not warnings. -* Fixed incorrect processing of some invalid input. +** Fixed incorrect processing of some invalid input. -* Fixed CPP guards: 9foo.h uses BISON_9FOO_H instead of 9FOO_H. +** Fixed CPP guards: 9foo.h uses BISON_9FOO_H instead of 9FOO_H. -* Fixed some typos in the documentation. +** Fixed some typos in the documentation. -* %token MY_EOF 0 is supported. +** %token MY_EOF 0 is supported. Before, MY_EOF was silently renumbered as 257. -* doc/refcard.tex is updated. +** doc/refcard.tex is updated. -* %output, %file-prefix, %name-prefix. +** %output, %file-prefix, %name-prefix. New. -* --output +** --output New, aliasing `--output-file'. -Changes in version 1.30, 2001-10-26: +* Changes in version 1.30, 2001-10-26: -* `--defines' and `--graph' have now an optional argument which is the +** `--defines' and `--graph' have now an optional argument which is the output file name. `-d' and `-g' do not change; they do not take any argument. -* `%source_extension' and `%header_extension' are removed, failed +** `%source_extension' and `%header_extension' are removed, failed experiment. -* Portability fixes. +** Portability fixes. -Changes in version 1.29, 2001-09-07: +* Changes in version 1.29, 2001-09-07: -* The output file does not define const, as this caused problems when used +** The output file does not define const, as this caused problems when used with common autoconfiguration schemes. If you still use ancient compilers that lack const, compile with the equivalent of the C compiler option `-Dconst='. autoconf's AC_C_CONST macro provides one way to do this. -* Added `-g' and `--graph'. +** Added `-g' and `--graph'. -* The Bison manual is now distributed under the terms of the GNU FDL. +** The Bison manual is now distributed under the terms of the GNU FDL. -* The input and the output files has automatically a similar extension. +** The input and the output files has automatically a similar extension. -* Russian translation added. +** Russian translation added. -* NLS support updated; should hopefully be less troublesome. +** NLS support updated; should hopefully be less troublesome. -* Added the old Bison reference card. +** Added the old Bison reference card. -* Added `--locations' and `%locations'. +** Added `--locations' and `%locations'. -* Added `-S' and `--skeleton'. +** Added `-S' and `--skeleton'. -* `%raw', `-r', `--raw' is disabled. +** `%raw', `-r', `--raw' is disabled. -* Special characters are escaped when output. This solves the problems +** Special characters are escaped when output. This solves the problems of the #line lines with path names including backslashes. -* New directives. +** New directives. `%yacc', `%fixed_output_files', `%defines', `%no_parser', `%verbose', `%debug', `%source_extension' and `%header_extension'. -* @$ +** @$ Automatic location tracking. -Changes in version 1.28, 1999-07-06: +* Changes in version 1.28, 1999-07-06: -* Should compile better now with K&R compilers. +** Should compile better now with K&R compilers. -* Added NLS. +** Added NLS. -* Fixed a problem with escaping the double quote character. +** Fixed a problem with escaping the double quote character. -* There is now a FAQ. +** There is now a FAQ. -Changes in version 1.27: +* Changes in version 1.27: -* The make rule which prevented bison.simple from being created on +** The make rule which prevented bison.simple from being created on some systems has been fixed. -Changes in version 1.26: +* Changes in version 1.26: -* Bison now uses automake. +** Bison now uses automake. -* New mailing lists: and . +** New mailing lists: and . -* Token numbers now start at 257 as previously documented, not 258. +** Token numbers now start at 257 as previously documented, not 258. -* Bison honors the TMPDIR environment variable. +** Bison honors the TMPDIR environment variable. -* A couple of buffer overruns have been fixed. +** A couple of buffer overruns have been fixed. -* Problems when closing files should now be reported. +** Problems when closing files should now be reported. -* Generated parsers should now work even on operating systems which do +** Generated parsers should now work even on operating systems which do not provide alloca(). -Changes in version 1.25, 1995-10-16: +* Changes in version 1.25, 1995-10-16: -* Errors in the input grammar are not fatal; Bison keeps reading +** Errors in the input grammar are not fatal; Bison keeps reading the grammar file, and reports all the errors found in it. -* Tokens can now be specified as multiple-character strings: for +** Tokens can now be specified as multiple-character strings: for example, you could use "<=" for a token which looks like <=, instead of chosing a name like LESSEQ. -* The %token_table declaration says to write a table of tokens (names +** The %token_table declaration says to write a table of tokens (names and numbers) into the parser file. The yylex function can use this table to recognize multiple-character string tokens, or for other purposes. -* The %no_lines declaration says not to generate any #line preprocessor +** The %no_lines declaration says not to generate any #line preprocessor directives in the parser file. -* The %raw declaration says to use internal Bison token numbers, not +** The %raw declaration says to use internal Bison token numbers, not Yacc-compatible token numbers, when token names are defined as macros. -* The --no-parser option produces the parser tables without including +** The --no-parser option produces the parser tables without including the parser engine; a project can now use its own parser engine. The actions go into a separate file called NAME.act, in the form of a switch statement body. -Changes in version 1.23: +* Changes in version 1.23: The user can define YYPARSE_PARAM as the name of an argument to be passed into yyparse. The argument should have type void *. It should @@ -1013,11 +1013,11 @@ by casting it to the proper pointer type. Line numbers in output file corrected. -Changes in version 1.22: +* Changes in version 1.22: --help option added. -Changes in version 1.20: +* Changes in version 1.20: Output file does not redefine const for C++. From 738cde3e937b920babf55dea2db4cbfe17eebb9c Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 4 Nov 2008 22:26:39 +0100 Subject: [PATCH 003/404] Mention the trailing semicolon in action. * NEWS: Mention the trailing semicolon in action. --- ChangeLog | 4 ++++ NEWS | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ec760d69..49c2d99d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-11-04 Akim Demaille + + * NEWS: Mention the trailing semicolon in action. + 2008-11-04 Akim Demaille Reformat NEWS. diff --git a/NEWS b/NEWS index d63c9500..9ee61800 100644 --- a/NEWS +++ b/NEWS @@ -3,7 +3,22 @@ Bison News * Changes in version ?.? (????-??-??): -** +** Temporary hack for adding a semicolon to the user action. + + Bison used to prepend a trailing semicolon at the end of the user + action for reductions. This allowed actions such as + + exp: exp "+" exp { $$ = $1 + $3 }; + + instead of + + exp: exp "+" exp { $$ = $1 + $3; }; + + This prevents the future support for languages than do not use `;' + as C/C++/Java do. Yet some grammars still depend on this `feature'. + Bison 2.4.1 restores the previous behavior to leave more time for + grammars depending on the old behavior to be adjusted. Future + release of Bison will disable this feature. * Changes in version 2.4 (2008-11-02): From 4b1ebc495bd39572b60640bc469b0852e9f71447 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 7 Nov 2008 16:48:31 -0500 Subject: [PATCH 004/404] Clean up %skeleton and %language priority implementation. * src/getargs.c (skeleton_prio): Use default_prio rather than 2, and remove static qualifier because others will soon need to see it. (language_prio): Likewise. (getargs): Use command_line_prio rather than 0. * src/getargs.h (command_line_prio, grammar_prio, default_prio): New enum fields. (skeleton_prio): Extern it. (language_prio): Extern it. * src/parse-gram.y: Use grammar_prio rather than 1. --- ChangeLog | 13 +++++++++++++ src/getargs.c | 8 ++++---- src/getargs.h | 5 ++++- src/parse-gram.c | 8 ++++---- src/parse-gram.h | 2 +- src/parse-gram.y | 4 ++-- 6 files changed, 28 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 49c2d99d..4d3011f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-11-07 Joel E. Denny + + Clean up %skeleton and %language priority implementation. + * src/getargs.c (skeleton_prio): Use default_prio rather than 2, and + remove static qualifier because others will soon need to see it. + (language_prio): Likewise. + (getargs): Use command_line_prio rather than 0. + * src/getargs.h (command_line_prio, grammar_prio, default_prio): New + enum fields. + (skeleton_prio): Extern it. + (language_prio): Extern it. + * src/parse-gram.y: Use grammar_prio rather than 1. + 2008-11-04 Akim Demaille * NEWS: Mention the trailing semicolon in action. diff --git a/src/getargs.c b/src/getargs.c index c9fc9bfc..f36f25bc 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -70,9 +70,9 @@ static struct bison_language const valid_languages[] = { { "", "", "", "", false } }; -static int skeleton_prio = 2; +int skeleton_prio = default_prio; const char *skeleton = NULL; -static int language_prio = 2; +int language_prio = default_prio; struct bison_language const *language = &valid_languages[0]; const char *include = NULL; @@ -520,11 +520,11 @@ getargs (int argc, char *argv[]) break; case 'L': - language_argmatch (optarg, 0, NULL); + language_argmatch (optarg, command_line_prio, NULL); break; case 'S': - skeleton_arg (AS_FILE_NAME (optarg), 0, NULL); + skeleton_arg (AS_FILE_NAME (optarg), command_line_prio, NULL); break; case 'T': diff --git a/src/getargs.h b/src/getargs.h index 8449626b..eb7f448e 100644 --- a/src/getargs.h +++ b/src/getargs.h @@ -1,7 +1,7 @@ /* Parse command line arguments for bison. Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -24,11 +24,13 @@ #include "location.h" extern char *program_name; +enum { command_line_prio, grammar_prio, default_prio }; /* flags set by % directives */ /* for -S */ extern char const *skeleton; +extern int skeleton_prio; /* for -I */ extern char const *include; @@ -68,6 +70,7 @@ struct bison_language bool add_tab; }; +extern int language_prio; extern struct bison_language const *language; /*-----------. diff --git a/src/parse-gram.c b/src/parse-gram.c index 56eba09b..b7938dcd 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -1,5 +1,5 @@ -/* A Bison parser, made by GNU Bison 2.3b.21-d67c5-dirty. */ +/* A Bison parser, made by GNU Bison 2.4.4-738cd. */ /* Skeleton implementation for Bison's Yacc-like parsers in C @@ -46,7 +46,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.3b.21-d67c5-dirty" +#define YYBISON_VERSION "2.4.4-738cd" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -1994,7 +1994,7 @@ yyreduce: /* Line 1455 of yacc.c */ #line 257 "parse-gram.y" - { language_argmatch ((yyvsp[(2) - (2)].chars), 1, &(yylsp[(1) - (2)])); } + { language_argmatch ((yyvsp[(2) - (2)].chars), grammar_prio, &(yylsp[(1) - (2)])); } break; case 19: @@ -2110,7 +2110,7 @@ yyreduce: skeleton_user = uniqstr_new (skeleton_build); free (skeleton_build); } - skeleton_arg (skeleton_user, 1, &(yylsp[(1) - (2)])); + skeleton_arg (skeleton_user, grammar_prio, &(yylsp[(1) - (2)])); } break; diff --git a/src/parse-gram.h b/src/parse-gram.h index 78b2a4f1..938b2017 100644 --- a/src/parse-gram.h +++ b/src/parse-gram.h @@ -1,5 +1,5 @@ -/* A Bison parser, made by GNU Bison 2.3b.21-d67c5-dirty. */ +/* A Bison parser, made by GNU Bison 2.4.4-738cd. */ /* Skeleton interface for Bison's Yacc-like parsers in C diff --git a/src/parse-gram.y b/src/parse-gram.y index fa74d8d8..a8526b24 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -254,7 +254,7 @@ prologue_declaration: muscle_code_grow ("initial_action", action.code, @2); code_scanner_last_string_free (); } -| "%language" STRING { language_argmatch ($2, 1, &@1); } +| "%language" STRING { language_argmatch ($2, grammar_prio, &@1); } | "%lex-param" "{...}" { add_param ("lex_param", $2, @2); } | "%locations" { locations_flag = true; } | "%name-prefix" STRING { spec_name_prefix = $2; } @@ -300,7 +300,7 @@ prologue_declaration: skeleton_user = uniqstr_new (skeleton_build); free (skeleton_build); } - skeleton_arg (skeleton_user, 1, &@1); + skeleton_arg (skeleton_user, grammar_prio, &@1); } | "%token-table" { token_table_flag = true; } | "%verbose" { report_flag |= report_states; } From 7ed73f82ad0d54be945b9d5146e343c8e89bf81f Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 7 Nov 2008 16:48:57 -0500 Subject: [PATCH 005/404] Don't add a semicolon to actions for %skeleton or %language. It breaks Java test cases as reported by Akim Demaille. * src/scan-code.l: Implement. --- ChangeLog | 6 ++++++ src/scan-code.l | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4d3011f1..86aa3e5d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-11-07 Joel E. Denny + + Don't add a semicolon to actions for %skeleton or %language. + It breaks Java test cases as reported by Akim Demaille. + * src/scan-code.l: Implement. + 2008-11-07 Joel E. Denny Clean up %skeleton and %language priority implementation. diff --git a/src/scan-code.l b/src/scan-code.l index 71c90768..13a78c27 100644 --- a/src/scan-code.l +++ b/src/scan-code.l @@ -175,7 +175,9 @@ splice (\\[ \f\t\v]*\n)* /* As an undocumented Bison extension, append `;' before the last brace in braced code, so that the user code can omit trailing `;'. But do not append `;' if emulating Yacc, since Yacc does - not append one. + not append one. Also, some output languages (like Java) do not + accept an extra semicolon, so don't append if the user specified + a skeleton or language. FIXME: Bison should warn if a semicolon seems to be necessary here, and should omit the semicolon if it seems unnecessary @@ -186,7 +188,8 @@ splice (\\[ \f\t\v]*\n)* should also diagnose other Bison extensions like %yacc. Perhaps there should also be a GCC-style --pedantic-errors option, so that such warnings are diagnosed as errors. */ - if (outer_brace && ! yacc_flag) + if (outer_brace && !yacc_flag && language_prio == default_prio + && skeleton_prio == default_prio) obstack_1grow (&obstack_for_string, ';'); STRING_GROW; From b5775a81c150086df5ecc746628bc90849381f55 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 11 Nov 2008 13:37:36 +0100 Subject: [PATCH 006/404] Replace m4/warning.m4 with warnings module. * bootstrap.conf: Replace m4/warning.m4 with warnings module. * configure.ac: Adjust usage. * lib/Makefile.am: Replace $(WARNING_CFLAGS) with $(WARN_CFLAGS). * src/Makefile.am: Replace $(WARNING_CFLAGS) with $(WARN_CFLAGS). * tests/atlocal.in: Replace $(WARNING_*FLAGS) with $(WARN_*FLAGS). --- ChangeLog | 8 ++++++++ bootstrap.conf | 9 ++------- configure.ac | 32 ++++++++++++++++---------------- gnulib | 2 +- lib/Makefile.am | 2 +- m4/.cvsignore | 1 + m4/.gitignore | 1 + src/Makefile.am | 2 +- tests/atlocal.in | 4 ++-- 9 files changed, 33 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 86aa3e5d..ecd403e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-11-11 Paolo Bonzini + + * bootstrap.conf: Replace m4/warning.m4 with warnings module. + * configure.ac: Adjust usage. + * lib/Makefile.am: Replace $(WARNING_CFLAGS) with $(WARN_CFLAGS). + * src/Makefile.am: Replace $(WARNING_CFLAGS) with $(WARN_CFLAGS). + * tests/atlocal.in: Replace $(WARNING_*FLAGS) with $(WARN_*FLAGS). + 2008-11-07 Joel E. Denny Don't add a semicolon to actions for %skeleton or %language. diff --git a/bootstrap.conf b/bootstrap.conf index 89d7db5d..bcab1b89 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -21,13 +21,8 @@ gnulib_modules=' dirname error extensions fopen-safer getopt gettext git-version-gen gnumakefile hash inttypes javacomp-script javaexec-script malloc mbswidth obstack quote quotearg stdbool stpcpy strerror strtoul - strverscmp unistd unistd-safer unlocked-io unsetenv verify xalloc - xalloc-die xstrndup -' - -# Any gnulib files needed that are not in modules. -gnulib_files=' - m4/warning.m4 + strverscmp unistd unistd-safer unlocked-io unsetenv verify + warnings xalloc xalloc-die xstrndup ' # Additional xgettext options to use. Use "\\\newline" to break lines. diff --git a/configure.ac b/configure.ac index adb52715..f1ebd8de 100644 --- a/configure.ac +++ b/configure.ac @@ -51,23 +51,23 @@ AC_ARG_ENABLE(gcc-warnings, esac], [enableval=no]) if test "${enableval}" = yes; then - gl_WARNING_CFLAGS([-Werror]) - AC_SUBST([WERROR_CFLAGS], [$WARNING_CFLAGS]) - WARNING_CFLAGS= - gl_WARNING_CFLAGS([-Wall]) - gl_WARNING_CFLAGS([-Wextra -Wno-sign-compare]) - gl_WARNING_CFLAGS([-Wcast-align]) - gl_WARNING_CFLAGS([-Wcast-qual]) - gl_WARNING_CFLAGS([-Wformat]) - gl_WARNING_CFLAGS([-Wpointer-arith]) - gl_WARNING_CFLAGS([-Wwrite-strings]) - AC_SUBST([WARNING_CXXFLAGS], [$WARNING_CFLAGS]) + gl_WARN_ADD([-Werror], [WERROR_CFLAGS]) + AC_SUBST([WERROR_CFLAGS]) + gl_WARN_ADD([-Wall]) + gl_WARN_ADD([-Wextra -Wno-sign-compare]) + gl_WARN_ADD([-Wcast-align]) + gl_WARN_ADD([-Wcast-qual]) + gl_WARN_ADD([-Wformat]) + gl_WARN_ADD([-Wpointer-arith]) + gl_WARN_ADD([-Wwrite-strings]) + AC_SUBST([WARN_CXXFLAGS], [$WARN_CFLAGS]) # The following warnings are not suitable for C++. - gl_WARNING_CFLAGS([-Wbad-function-cast]) - gl_WARNING_CFLAGS([-Wmissing-declarations]) - gl_WARNING_CFLAGS([-Wmissing-prototypes]) - gl_WARNING_CFLAGS([-Wshadow]) - gl_WARNING_CFLAGS([-Wstrict-prototypes]) + gl_WARN_ADD([-Wbad-function-cast]) + gl_WARN_ADD([-Wmissing-declarations]) + gl_WARN_ADD([-Wmissing-prototypes]) + gl_WARN_ADD([-Wshadow]) + gl_WARN_ADD([-Wstrict-prototypes]) + AC_SUBST([WARN_CFLAGS]) AC_DEFINE([lint], 1, [Define to 1 if the compiler is checking for lint.]) fi diff --git a/gnulib b/gnulib index 2ec9ae24..2c64312e 160000 --- a/gnulib +++ b/gnulib @@ -1 +1 @@ -Subproject commit 2ec9ae244196c963a03bbcd3d85233ee78adbd44 +Subproject commit 2c64312ecca19a60629cb929c1ae759109c772b5 diff --git a/lib/Makefile.am b/lib/Makefile.am index 8a957c39..4ec82d94 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -17,7 +17,7 @@ include gnulib.mk -AM_CFLAGS = $(WARNING_CFLAGS) +AM_CFLAGS = $(WARN_CFLAGS) # Implementation of bitsets. bitsets_sources = \ diff --git a/m4/.cvsignore b/m4/.cvsignore index 3dfb9213..462f3028 100644 --- a/m4/.cvsignore +++ b/m4/.cvsignore @@ -58,6 +58,7 @@ unistd-safer.m4 unistd_h.m4 unlocked-io.m4 warning.m4 +warnings.m4 wchar.m4 wchar_t.m4 wctype.m4 diff --git a/m4/.gitignore b/m4/.gitignore index 12a51b1c..6c4d5665 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -58,6 +58,7 @@ /unistd_h.m4 /unlocked-io.m4 /warning.m4 +/warnings.m4 /wchar.m4 /wchar_t.m4 /wctype.m4 diff --git a/src/Makefile.am b/src/Makefile.am index ef974457..afe6d088 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -AM_CFLAGS = $(WARNING_CFLAGS) $(WERROR_CFLAGS) +AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS) AM_CPPFLAGS = -I$(top_srcdir)/lib AM_YFLAGS = "-dv" diff --git a/tests/atlocal.in b/tests/atlocal.in index 9fd930e5..a67c4dc3 100644 --- a/tests/atlocal.in +++ b/tests/atlocal.in @@ -8,7 +8,7 @@ CC='@CC@' # We want no optimization. -CFLAGS='@O0CFLAGS@ @WARNING_CFLAGS@ @WERROR_CFLAGS@' +CFLAGS='@O0CFLAGS@ @WARN_CFLAGS@ @WERROR_CFLAGS@' # We need `config.h'. CPPFLAGS="-I$abs_top_builddir/lib @CPPFLAGS@" @@ -23,7 +23,7 @@ CXX='@CXX@' BISON_CXX_WORKS='@BISON_CXX_WORKS@' # We want no optimization with C++, too. -CXXFLAGS='@O0CXXFLAGS@ @WARNING_CXXFLAGS@ @WERROR_CFLAGS@' +CXXFLAGS='@O0CXXFLAGS@ @WARN_CXXFLAGS@ @WERROR_CFLAGS@' # Are special link options needed? LDFLAGS='@LDFLAGS@' From f56274a8f95825a9e3e2b9fabf80c43d9de76351 Mon Sep 17 00:00:00 2001 From: Di-an Jan Date: Mon, 17 Nov 2008 11:07:29 +0100 Subject: [PATCH 007/404] Fix formatting and content of bison.texinfo menus * doc/bison.texinfo: Synchronize ``Detail Node Listing''. Align menus. Adjust word wrapping. Use node names for menu names. (Examples): Don't abbreviate node names. (LocalWords): Remove abbreviations. (Copying): Make description a sentence. (Java Action Features): Remove period to match the rest of menu. --- ChangeLog | 9 ++ doc/bison.texinfo | 346 +++++++++++++++++++++++----------------------- 2 files changed, 183 insertions(+), 172 deletions(-) diff --git a/ChangeLog b/ChangeLog index ecd403e9..9cda7eeb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-11-17 Di-an Jan + + * doc/bison.texinfo: Synchronize ``Detail Node Listing''. + Align menus. Adjust word wrapping. Use node names for menu names. + (Examples): Don't abbreviate node names. + (LocalWords): Remove abbreviations. + (Copying): Make description a sentence. + (Java Action Features): Remove period to match the rest of menu. + 2008-11-11 Paolo Bonzini * bootstrap.conf: Replace m4/warning.m4 with warnings module. diff --git a/doc/bison.texinfo b/doc/bison.texinfo index 71e9a16a..d4a9cc31 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -89,76 +89,76 @@ Cover art by Etienne Suvasa. @menu * Introduction:: * Conditions:: -* Copying:: The @acronym{GNU} General Public License says - how you can copy and share Bison +* Copying:: The @acronym{GNU} General Public License says + how you can copy and share Bison. Tutorial sections: -* Concepts:: Basic concepts for understanding Bison. -* Examples:: Three simple explained examples of using Bison. +* Concepts:: Basic concepts for understanding Bison. +* Examples:: Three simple explained examples of using Bison. Reference sections: -* Grammar File:: Writing Bison declarations and rules. -* Interface:: C-language interface to the parser function @code{yyparse}. -* Algorithm:: How the Bison parser works at run-time. -* Error Recovery:: Writing rules for error recovery. +* Grammar File:: Writing Bison declarations and rules. +* Interface:: C-language interface to the parser function @code{yyparse}. +* Algorithm:: How the Bison parser works at run-time. +* Error Recovery:: Writing rules for error recovery. * Context Dependency:: What to do if your language syntax is too - messy for Bison to handle straightforwardly. -* Debugging:: Understanding or debugging Bison parsers. -* Invocation:: How to run Bison (to produce the parser source file). -* Other Languages:: Creating C++ and Java parsers. -* FAQ:: Frequently Asked Questions -* Table of Symbols:: All the keywords of the Bison language are explained. -* Glossary:: Basic concepts are explained. -* Copying This Manual:: License for copying this manual. -* Index:: Cross-references to the text. + messy for Bison to handle straightforwardly. +* Debugging:: Understanding or debugging Bison parsers. +* Invocation:: How to run Bison (to produce the parser source file). +* Other Languages:: Creating C++ and Java parsers. +* FAQ:: Frequently Asked Questions +* Table of Symbols:: All the keywords of the Bison language are explained. +* Glossary:: Basic concepts are explained. +* Copying This Manual:: License for copying this manual. +* Index:: Cross-references to the text. @detailmenu --- The Detailed Node Listing --- The Concepts of Bison -* Language and Grammar:: Languages and context-free grammars, - as mathematical ideas. -* Grammar in Bison:: How we represent grammars for Bison's sake. -* Semantic Values:: Each token or syntactic grouping can have - a semantic value (the value of an integer, - the name of an identifier, etc.). -* Semantic Actions:: Each rule can have an action containing C code. -* GLR Parsers:: Writing parsers for general context-free languages. -* Locations Overview:: Tracking Locations. -* Bison Parser:: What are Bison's input and output, - how is the output used? -* Stages:: Stages in writing and running Bison grammars. -* Grammar Layout:: Overall structure of a Bison grammar file. +* Language and Grammar:: Languages and context-free grammars, + as mathematical ideas. +* Grammar in Bison:: How we represent grammars for Bison's sake. +* Semantic Values:: Each token or syntactic grouping can have + a semantic value (the value of an integer, + the name of an identifier, etc.). +* Semantic Actions:: Each rule can have an action containing C code. +* GLR Parsers:: Writing parsers for general context-free languages. +* Locations Overview:: Tracking Locations. +* Bison Parser:: What are Bison's input and output, + how is the output used? +* Stages:: Stages in writing and running Bison grammars. +* Grammar Layout:: Overall structure of a Bison grammar file. Writing @acronym{GLR} Parsers -* Simple GLR Parsers:: Using @acronym{GLR} parsers on unambiguous grammars. -* Merging GLR Parses:: Using @acronym{GLR} parsers to resolve ambiguities. -* GLR Semantic Actions:: Deferred semantic actions have special concerns. -* Compiler Requirements:: @acronym{GLR} parsers require a modern C compiler. +* Simple GLR Parsers:: Using @acronym{GLR} parsers on unambiguous grammars. +* Merging GLR Parses:: Using @acronym{GLR} parsers to resolve ambiguities. +* GLR Semantic Actions:: Deferred semantic actions have special concerns. +* Compiler Requirements:: @acronym{GLR} parsers require a modern C compiler. Examples -* RPN Calc:: Reverse polish notation calculator; - a first example with no operator precedence. -* Infix Calc:: Infix (algebraic) notation calculator. - Operator precedence is introduced. +* RPN Calc:: Reverse polish notation calculator; + a first example with no operator precedence. +* Infix Calc:: Infix (algebraic) notation calculator. + Operator precedence is introduced. * Simple Error Recovery:: Continuing after syntax errors. * Location Tracking Calc:: Demonstrating the use of @@@var{n} and @@$. -* Multi-function Calc:: Calculator with memory and trig functions. - It uses multiple data-types for semantic values. -* Exercises:: Ideas for improving the multi-function calculator. +* Multi-function Calc:: Calculator with memory and trig functions. + It uses multiple data-types for semantic values. +* Exercises:: Ideas for improving the multi-function calculator. Reverse Polish Notation Calculator -* Decls: Rpcalc Decls. Prologue (declarations) for rpcalc. -* Rules: Rpcalc Rules. Grammar Rules for rpcalc, with explanation. -* Lexer: Rpcalc Lexer. The lexical analyzer. -* Main: Rpcalc Main. The controlling function. -* Error: Rpcalc Error. The error reporting function. -* Gen: Rpcalc Gen. Running Bison on the grammar file. -* Comp: Rpcalc Compile. Run the C compiler on the output code. +* Rpcalc Declarations:: Prologue (declarations) for rpcalc. +* Rpcalc Rules:: Grammar Rules for rpcalc, with explanation. +* Rpcalc Lexer:: The lexical analyzer. +* Rpcalc Main:: The controlling function. +* Rpcalc Error:: The error reporting function. +* Rpcalc Generate:: Running Bison on the grammar file. +* Rpcalc Compile:: Run the C compiler on the output code. Grammar Rules for @code{rpcalc} @@ -168,15 +168,15 @@ Grammar Rules for @code{rpcalc} Location Tracking Calculator: @code{ltcalc} -* Decls: Ltcalc Decls. Bison and C declarations for ltcalc. -* Rules: Ltcalc Rules. Grammar rules for ltcalc, with explanations. -* Lexer: Ltcalc Lexer. The lexical analyzer. +* Ltcalc Declarations:: Bison and C declarations for ltcalc. +* Ltcalc Rules:: Grammar rules for ltcalc, with explanations. +* Ltcalc Lexer:: The lexical analyzer. Multi-Function Calculator: @code{mfcalc} -* Decl: Mfcalc Decl. Bison declarations for multi-function calculator. -* Rules: Mfcalc Rules. Grammar rules for the calculator. -* Symtab: Mfcalc Symtab. Symbol table management subroutines. +* Mfcalc Declarations:: Bison declarations for multi-function calculator. +* Mfcalc Rules:: Grammar rules for the calculator. +* Mfcalc Symbol Table:: Symbol table management subroutines. Bison Grammar Files @@ -191,11 +191,11 @@ Bison Grammar Files Outline of a Bison Grammar -* Prologue:: Syntax and usage of the prologue. +* Prologue:: Syntax and usage of the prologue. * Prologue Alternatives:: Syntax and usage of alternatives to the prologue. -* Bison Declarations:: Syntax and usage of the Bison declarations section. -* Grammar Rules:: Syntax and usage of the grammar rules section. -* Epilogue:: Syntax and usage of the epilogue. +* Bison Declarations:: Syntax and usage of the Bison declarations section. +* Grammar Rules:: Syntax and usage of the grammar rules section. +* Epilogue:: Syntax and usage of the epilogue. Defining Language Semantics @@ -230,24 +230,28 @@ Bison Declarations Parser C-Language Interface -* Parser Function:: How to call @code{yyparse} and what it returns. -* Lexical:: You must supply a function @code{yylex} - which reads tokens. -* Error Reporting:: You must supply a function @code{yyerror}. -* Action Features:: Special features for use in actions. -* Internationalization:: How to let the parser speak in the user's - native language. +* Parser Function:: How to call @code{yyparse} and what it returns. +* Push Parser Function:: How to call @code{yypush_parse} and what it returns. +* Pull Parser Function:: How to call @code{yypull_parse} and what it returns. +* Parser Create Function:: How to call @code{yypstate_new} and what it returns. +* Parser Delete Function:: How to call @code{yypstate_delete} and what it returns. +* Lexical:: You must supply a function @code{yylex} + which reads tokens. +* Error Reporting:: You must supply a function @code{yyerror}. +* Action Features:: Special features for use in actions. +* Internationalization:: How to let the parser speak in the user's + native language. The Lexical Analyzer Function @code{yylex} * Calling Convention:: How @code{yyparse} calls @code{yylex}. -* Token Values:: How @code{yylex} must return the semantic value - of the token it has read. -* Token Locations:: How @code{yylex} must return the text location - (line number, etc.) of the token, if the - actions want that. -* Pure Calling:: How the calling convention differs - in a pure parser (@pxref{Pure Decl, ,A Pure (Reentrant) Parser}). +* Token Values:: How @code{yylex} must return the semantic value + of the token it has read. +* Token Locations:: How @code{yylex} must return the text location + (line number, etc.) of the token, if the + actions want that. +* Pure Calling:: How the calling convention differs in a pure parser + (@pxref{Pure Decl, ,A Pure (Reentrant) Parser}). The Bison Parser Algorithm @@ -257,7 +261,7 @@ The Bison Parser Algorithm * Contextual Precedence:: When an operator's precedence depends on context. * Parser States:: The parser is a finite-state-machine with stack. * Reduce/Reduce:: When two rules are applicable in the same situation. -* Mystery Conflicts:: Reduce/reduce conflicts that look unjustified. +* Mystery Conflicts:: Reduce/reduce conflicts that look unjustified. * Generalized LR Parsing:: Parsing arbitrary context-free grammars. * Memory Management:: What happens when memory is exhausted. How to avoid it. @@ -311,33 +315,33 @@ A Complete C++ Example Java Parsers -* Java Bison Interface:: Asking for Java parser generation -* Java Semantic Values:: %type and %token vs. Java -* Java Location Values:: The position and location classes -* Java Parser Interface:: Instantiating and running the parser -* Java Scanner Interface:: Specifying the scanner for the parser -* Java Action Features:: Special features for use in actions. -* Java Differences:: Differences between C/C++ and Java Grammars -* Java Declarations Summary:: List of Bison declarations used with Java +* Java Bison Interface:: Asking for Java parser generation +* Java Semantic Values:: %type and %token vs. Java +* Java Location Values:: The position and location classes +* Java Parser Interface:: Instantiating and running the parser +* Java Scanner Interface:: Specifying the scanner for the parser +* Java Action Features:: Special features for use in actions +* Java Differences:: Differences between C/C++ and Java Grammars +* Java Declarations Summary:: List of Bison declarations used with Java Frequently Asked Questions -* Memory Exhausted:: Breaking the Stack Limits -* How Can I Reset the Parser:: @code{yyparse} Keeps some State -* Strings are Destroyed:: @code{yylval} Loses Track of Strings -* Implementing Gotos/Loops:: Control Flow in the Calculator -* Multiple start-symbols:: Factoring closely related grammars -* Secure? Conform?:: Is Bison @acronym{POSIX} safe? -* I can't build Bison:: Troubleshooting -* Where can I find help?:: Troubleshouting -* Bug Reports:: Troublereporting -* Other Languages:: Parsers in Java and others -* Beta Testing:: Experimenting development versions -* Mailing Lists:: Meeting other Bison users +* Memory Exhausted:: Breaking the Stack Limits +* How Can I Reset the Parser:: @code{yyparse} Keeps some State +* Strings are Destroyed:: @code{yylval} Loses Track of Strings +* Implementing Gotos/Loops:: Control Flow in the Calculator +* Multiple start-symbols:: Factoring closely related grammars +* Secure? Conform?:: Is Bison @acronym{POSIX} safe? +* I can't build Bison:: Troubleshooting +* Where can I find help?:: Troubleshouting +* Bug Reports:: Troublereporting +* More Languages:: Parsers in C++, Java, and so on +* Beta Testing:: Experimenting development versions +* Mailing Lists:: Meeting other Bison users Copying This Manual -* Copying This Manual:: License for copying this manual. +* Copying This Manual:: License for copying this manual. @end detailmenu @end menu @@ -417,19 +421,19 @@ details of Bison will not make sense. If you do not already know how to use Bison or Yacc, we suggest you start by reading this chapter carefully. @menu -* Language and Grammar:: Languages and context-free grammars, - as mathematical ideas. -* Grammar in Bison:: How we represent grammars for Bison's sake. -* Semantic Values:: Each token or syntactic grouping can have - a semantic value (the value of an integer, - the name of an identifier, etc.). -* Semantic Actions:: Each rule can have an action containing C code. -* GLR Parsers:: Writing parsers for general context-free languages. -* Locations Overview:: Tracking Locations. -* Bison Parser:: What are Bison's input and output, - how is the output used? -* Stages:: Stages in writing and running Bison grammars. -* Grammar Layout:: Overall structure of a Bison grammar file. +* Language and Grammar:: Languages and context-free grammars, + as mathematical ideas. +* Grammar in Bison:: How we represent grammars for Bison's sake. +* Semantic Values:: Each token or syntactic grouping can have + a semantic value (the value of an integer, + the name of an identifier, etc.). +* Semantic Actions:: Each rule can have an action containing C code. +* GLR Parsers:: Writing parsers for general context-free languages. +* Locations Overview:: Tracking Locations. +* Bison Parser:: What are Bison's input and output, + how is the output used? +* Stages:: Stages in writing and running Bison grammars. +* Grammar Layout:: Overall structure of a Bison grammar file. @end menu @node Language and Grammar @@ -745,10 +749,10 @@ user-defined function on the resulting values to produce an arbitrary merged result. @menu -* Simple GLR Parsers:: Using @acronym{GLR} parsers on unambiguous grammars. -* Merging GLR Parses:: Using @acronym{GLR} parsers to resolve ambiguities. -* GLR Semantic Actions:: Deferred semantic actions have special concerns. -* Compiler Requirements:: @acronym{GLR} parsers require a modern C compiler. +* Simple GLR Parsers:: Using @acronym{GLR} parsers on unambiguous grammars. +* Merging GLR Parses:: Using @acronym{GLR} parsers to resolve ambiguities. +* GLR Semantic Actions:: Deferred semantic actions have special concerns. +* Compiler Requirements:: @acronym{GLR} parsers require a modern C compiler. @end menu @node Simple GLR Parsers @@ -1376,15 +1380,15 @@ languages are written the same way. You can copy these examples into a source file to try them. @menu -* RPN Calc:: Reverse polish notation calculator; - a first example with no operator precedence. -* Infix Calc:: Infix (algebraic) notation calculator. - Operator precedence is introduced. +* RPN Calc:: Reverse polish notation calculator; + a first example with no operator precedence. +* Infix Calc:: Infix (algebraic) notation calculator. + Operator precedence is introduced. * Simple Error Recovery:: Continuing after syntax errors. * Location Tracking Calc:: Demonstrating the use of @@@var{n} and @@$. -* Multi-function Calc:: Calculator with memory and trig functions. - It uses multiple data-types for semantic values. -* Exercises:: Ideas for improving the multi-function calculator. +* Multi-function Calc:: Calculator with memory and trig functions. + It uses multiple data-types for semantic values. +* Exercises:: Ideas for improving the multi-function calculator. @end menu @node RPN Calc @@ -1403,16 +1407,16 @@ The source code for this calculator is named @file{rpcalc.y}. The @samp{.y} extension is a convention used for Bison input files. @menu -* Decls: Rpcalc Decls. Prologue (declarations) for rpcalc. -* Rules: Rpcalc Rules. Grammar Rules for rpcalc, with explanation. -* Lexer: Rpcalc Lexer. The lexical analyzer. -* Main: Rpcalc Main. The controlling function. -* Error: Rpcalc Error. The error reporting function. -* Gen: Rpcalc Gen. Running Bison on the grammar file. -* Comp: Rpcalc Compile. Run the C compiler on the output code. +* Rpcalc Declarations:: Prologue (declarations) for rpcalc. +* Rpcalc Rules:: Grammar Rules for rpcalc, with explanation. +* Rpcalc Lexer:: The lexical analyzer. +* Rpcalc Main:: The controlling function. +* Rpcalc Error:: The error reporting function. +* Rpcalc Generate:: Running Bison on the grammar file. +* Rpcalc Compile:: Run the C compiler on the output code. @end menu -@node Rpcalc Decls +@node Rpcalc Declarations @subsection Declarations for @code{rpcalc} Here are the C and Bison declarations for the reverse polish notation @@ -1662,7 +1666,7 @@ therefore, @code{NUM} becomes a macro for @code{yylex} to use. The semantic value of the token (if it has one) is stored into the global variable @code{yylval}, which is where the Bison parser will look for it. (The C data type of @code{yylval} is @code{YYSTYPE}, which was -defined at the beginning of the grammar; @pxref{Rpcalc Decls, +defined at the beginning of the grammar; @pxref{Rpcalc Declarations, ,Declarations for @code{rpcalc}}.) A token type code of zero is returned if the end-of-input is encountered. @@ -1758,7 +1762,7 @@ have not written any error rules in this example, so any invalid input will cause the calculator program to exit. This is not clean behavior for a real calculator, but it is adequate for the first example. -@node Rpcalc Gen +@node Rpcalc Generate @subsection Running Bison to Make the Parser @cindex running Bison (introduction) @@ -1977,12 +1981,12 @@ most of the work needed to use locations will be done in the lexical analyzer. @menu -* Decls: Ltcalc Decls. Bison and C declarations for ltcalc. -* Rules: Ltcalc Rules. Grammar rules for ltcalc, with explanations. -* Lexer: Ltcalc Lexer. The lexical analyzer. +* Ltcalc Declarations:: Bison and C declarations for ltcalc. +* Ltcalc Rules:: Grammar rules for ltcalc, with explanations. +* Ltcalc Lexer:: The lexical analyzer. @end menu -@node Ltcalc Decls +@node Ltcalc Declarations @subsection Declarations for @code{ltcalc} The C and Bison declarations for the location tracking calculator are @@ -2218,12 +2222,12 @@ $ Note that multiple assignment and nested function calls are permitted. @menu -* Decl: Mfcalc Decl. Bison declarations for multi-function calculator. -* Rules: Mfcalc Rules. Grammar rules for the calculator. -* Symtab: Mfcalc Symtab. Symbol table management subroutines. +* Mfcalc Declarations:: Bison declarations for multi-function calculator. +* Mfcalc Rules:: Grammar rules for the calculator. +* Mfcalc Symbol Table:: Symbol table management subroutines. @end menu -@node Mfcalc Decl +@node Mfcalc Declarations @subsection Declarations for @code{mfcalc} Here are the C and Bison declarations for the multi-function calculator. @@ -2319,7 +2323,7 @@ exp: NUM @{ $$ = $1; @} %% @end smallexample -@node Mfcalc Symtab +@node Mfcalc Symbol Table @subsection The @code{mfcalc} Symbol Table @cindex symbol table example @@ -2632,11 +2636,11 @@ As a @acronym{GNU} extension, @samp{//} introduces a comment that continues until end of line. @menu -* Prologue:: Syntax and usage of the prologue. +* Prologue:: Syntax and usage of the prologue. * Prologue Alternatives:: Syntax and usage of alternatives to the prologue. -* Bison Declarations:: Syntax and usage of the Bison declarations section. -* Grammar Rules:: Syntax and usage of the grammar rules section. -* Epilogue:: Syntax and usage of the epilogue. +* Bison Declarations:: Syntax and usage of the Bison declarations section. +* Grammar Rules:: Syntax and usage of the grammar rules section. +* Epilogue:: Syntax and usage of the epilogue. @end menu @node Prologue @@ -5221,19 +5225,17 @@ identifier (aside from those in this manual) in an action or in epilogue in the grammar file, you are likely to run into trouble. @menu -* Parser Function:: How to call @code{yyparse} and what it returns. -* Push Parser Function:: How to call @code{yypush_parse} and what it returns. -* Pull Parser Function:: How to call @code{yypull_parse} and what it returns. -* Parser Create Function:: How to call @code{yypstate_new} and what it - returns. -* Parser Delete Function:: How to call @code{yypstate_delete} and what it - returns. -* Lexical:: You must supply a function @code{yylex} - which reads tokens. -* Error Reporting:: You must supply a function @code{yyerror}. -* Action Features:: Special features for use in actions. -* Internationalization:: How to let the parser speak in the user's - native language. +* Parser Function:: How to call @code{yyparse} and what it returns. +* Push Parser Function:: How to call @code{yypush_parse} and what it returns. +* Pull Parser Function:: How to call @code{yypull_parse} and what it returns. +* Parser Create Function:: How to call @code{yypstate_new} and what it returns. +* Parser Delete Function:: How to call @code{yypstate_delete} and what it returns. +* Lexical:: You must supply a function @code{yylex} + which reads tokens. +* Error Reporting:: You must supply a function @code{yyerror}. +* Action Features:: Special features for use in actions. +* Internationalization:: How to let the parser speak in the user's + native language. @end menu @node Parser Function @@ -5400,13 +5402,13 @@ that need it. @xref{Invocation, ,Invoking Bison}. @menu * Calling Convention:: How @code{yyparse} calls @code{yylex}. -* Token Values:: How @code{yylex} must return the semantic value - of the token it has read. -* Token Locations:: How @code{yylex} must return the text location - (line number, etc.) of the token, if the - actions want that. -* Pure Calling:: How the calling convention differs - in a pure parser (@pxref{Pure Decl, ,A Pure (Reentrant) Parser}). +* Token Values:: How @code{yylex} must return the semantic value + of the token it has read. +* Token Locations:: How @code{yylex} must return the text location + (line number, etc.) of the token, if the + actions want that. +* Pure Calling:: How the calling convention differs in a pure parser + (@pxref{Pure Decl, ,A Pure (Reentrant) Parser}). @end menu @node Calling Convention @@ -6049,7 +6051,7 @@ This kind of parser is known in the literature as a bottom-up parser. * Contextual Precedence:: When an operator's precedence depends on context. * Parser States:: The parser is a finite-state-machine with stack. * Reduce/Reduce:: When two rules are applicable in the same situation. -* Mystery Conflicts:: Reduce/reduce conflicts that look unjustified. +* Mystery Conflicts:: Reduce/reduce conflicts that look unjustified. * Generalized LR Parsing:: Parsing arbitrary context-free grammars. * Memory Management:: What happens when memory is exhausted. How to avoid it. @end menu @@ -7653,7 +7655,7 @@ standard I/O stream, the numeric code for the token type, and the token value (from @code{yylval}). Here is an example of @code{YYPRINT} suitable for the multi-function -calculator (@pxref{Mfcalc Decl, ,Declarations for @code{mfcalc}}): +calculator (@pxref{Mfcalc Declarations, ,Declarations for @code{mfcalc}}): @smallexample %@{ @@ -8728,14 +8730,14 @@ main (int argc, char *argv[]) @section Java Parsers @menu -* Java Bison Interface:: Asking for Java parser generation -* Java Semantic Values:: %type and %token vs. Java -* Java Location Values:: The position and location classes -* Java Parser Interface:: Instantiating and running the parser -* Java Scanner Interface:: Specifying the scanner for the parser -* Java Action Features:: Special features for use in actions. -* Java Differences:: Differences between C/C++ and Java Grammars -* Java Declarations Summary:: List of Bison declarations used with Java +* Java Bison Interface:: Asking for Java parser generation +* Java Semantic Values:: %type and %token vs. Java +* Java Location Values:: The position and location classes +* Java Parser Interface:: Instantiating and running the parser +* Java Scanner Interface:: Specifying the scanner for the parser +* Java Action Features:: Special features for use in actions +* Java Differences:: Differences between C/C++ and Java Grammars +* Java Declarations Summary:: List of Bison declarations used with Java @end menu @node Java Bison Interface @@ -10357,7 +10359,7 @@ grammatically indivisible. The piece of text it represents is a token. @c LocalWords: akim fn cp syncodeindex vr tp synindex dircategory direntry @c LocalWords: ifset vskip pt filll insertcopying sp ISBN Etienne Suvasa @c LocalWords: ifnottex yyparse detailmenu GLR RPN Calc var Decls Rpcalc -@c LocalWords: rpcalc Lexer Gen Comp Expr ltcalc mfcalc Decl Symtab yylex +@c LocalWords: rpcalc Lexer Expr ltcalc mfcalc yylex @c LocalWords: yyerror pxref LR yylval cindex dfn LALR samp gpl BNF xref @c LocalWords: const int paren ifnotinfo AC noindent emph expr stmt findex @c LocalWords: glr YYSTYPE TYPENAME prog dprec printf decl init stmtMerge From bf151b75ff06644963600328ea666ae85875832b Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Mon, 17 Nov 2008 09:35:58 -0500 Subject: [PATCH 008/404] Don't let maintainer-*-check targets force a version update. * cfg.mk (_is-dist-target): Implement. maintainer-check* was already handled. --- ChangeLog | 8 +++++++- cfg.mk | 8 ++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9cda7eeb..a54f7b64 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-11-17 Joel E. Denny + + Don't let maintainer-*-check targets force a version update. + * cfg.mk (_is-dist-target): Implement. maintainer-check* was already + handled. + 2008-11-17 Di-an Jan * doc/bison.texinfo: Synchronize ``Detail Node Listing''. @@ -5,7 +11,7 @@ (Examples): Don't abbreviate node names. (LocalWords): Remove abbreviations. (Copying): Make description a sentence. - (Java Action Features): Remove period to match the rest of menu. + (Java Action Features): Remove period to match the rest of menu. 2008-11-11 Paolo Bonzini diff --git a/cfg.mk b/cfg.mk index 913ecb8a..bee0fcbe 100644 --- a/cfg.mk +++ b/cfg.mk @@ -14,11 +14,11 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# It's useful to run maintainer-check* targets during development, but we don't -# want to wait on a recompile because of an update to $(VERSION). Thus, -# override the _is-dist-target from GNUmakefile so that maintainer-check* +# It's useful to run maintainer-*check* targets during development, but we +# don't want to wait on a recompile because of an update to $(VERSION). Thus, +# override the _is-dist-target from GNUmakefile so that maintainer-*check* # targets are filtered out. -_is-dist-target = $(filter-out %clean maintainer-check%, \ +_is-dist-target = $(filter-out %clean maintainer-check% maintainer-%-check, \ $(filter maintainer-% dist% alpha beta major,$(MAKECMDGOALS))) # Use alpha.gnu.org for alpha and beta releases. From 462503f8255a30ac70ac2efd93a902bcd81bfca2 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Tue, 18 Nov 2008 22:34:26 -0500 Subject: [PATCH 009/404] Fix unexpanded macros in GLR defines file. Reported by Csaba Raduly at . * THANKS (Csaba Raduly): Add. * data/glr.c: Fix overquoting on b4_prefix for yylval and yylloc. * tests/calc.at (_AT_DATA_CALC_Y): If %defines is specified, generate lexer in a separate module that includes the defines file. (AT_CHECK_CALC): Use AT_FULL_COMPILE and request compilation of lexer source. * tests/local.at (_AT_BISON_OPTION_PUSHDEFS): Push AT_DEFINES_IF. Adjust AT_LOC and AT_VAL to use AT_NAME_PREFIX. (AT_BISON_OPTION_POPDEFS): Pop AT_DEFINES_IF. (AT_DATA_SOURCE_PROLOGUE): New. (AT_DATA_GRAMMAR_PROLOGUE): Use AT_DATA_SOURCE_PROLOGUE. (AT_DATA_SOURCE): New. (AT_FULL_COMPILE): New, copied from master branch and extended to support an additional output file. --- ChangeLog | 20 ++++ THANKS | 1 + data/glr.c | 8 +- tests/calc.at | 316 +++++++++++++++++++++++++------------------------ tests/local.at | 56 +++++++-- 5 files changed, 232 insertions(+), 169 deletions(-) diff --git a/ChangeLog b/ChangeLog index a54f7b64..3015d924 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2008-11-18 Joel E. Denny + + Fix unexpanded macros in GLR defines file. + Reported by Csaba Raduly at + . + * THANKS (Csaba Raduly): Add. + * data/glr.c: Fix overquoting on b4_prefix for yylval and yylloc. + * tests/calc.at (_AT_DATA_CALC_Y): If %defines is specified, generate + lexer in a separate module that includes the defines file. + (AT_CHECK_CALC): Use AT_FULL_COMPILE and request compilation of lexer + source. + * tests/local.at (_AT_BISON_OPTION_PUSHDEFS): Push AT_DEFINES_IF. + Adjust AT_LOC and AT_VAL to use AT_NAME_PREFIX. + (AT_BISON_OPTION_POPDEFS): Pop AT_DEFINES_IF. + (AT_DATA_SOURCE_PROLOGUE): New. + (AT_DATA_GRAMMAR_PROLOGUE): Use AT_DATA_SOURCE_PROLOGUE. + (AT_DATA_SOURCE): New. + (AT_FULL_COMPILE): New, copied from master branch and extended to + support an additional source file. + 2008-11-17 Joel E. Denny Don't let maintainer-*-check targets force a version update. diff --git a/THANKS b/THANKS index 5f88c6c2..40291c71 100644 --- a/THANKS +++ b/THANKS @@ -22,6 +22,7 @@ Charles-Henri de Boysson de-boy_c@epita.fr Christian Burger cburger@sunysb.edu Cris Bailiff c.bailiff+bison@awayweb.com Cris van Pelt cris@amf03054.office.wxs.nl +Csaba Raduly csaba_22@yahoo.co.uk Daniel Hagerty hag@gnu.org David J. MacKenzie djm@gnu.org Derek M. Jones derek@knosof.co.uk diff --git a/data/glr.c b/data/glr.c index c6de6d8f..84637e0e 100644 --- a/data/glr.c +++ b/data/glr.c @@ -1,8 +1,8 @@ -*- C -*- # GLR skeleton for Bison -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, -# Inc. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 @@ -2644,10 +2644,10 @@ b4_copyright([Skeleton interface for Bison GLR parsers in C], b4_shared_declarations b4_pure_if([], -[[extern YYSTYPE b4_prefix][lval;]]) +[[extern YYSTYPE ]b4_prefix[lval;]]) b4_locations_if([b4_pure_if([], -[extern YYLTYPE b4_prefix[]lloc;]) +[extern YYLTYPE ]b4_prefix[lloc;]) ]) ])]) m4_divert_pop(0) diff --git a/tests/calc.at b/tests/calc.at index 26249088..5f118580 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -1,7 +1,7 @@ # Simple calculator. -*- Autotest -*- -# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software -# Foundation, Inc. +# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 @@ -28,21 +28,162 @@ # _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES]) # ----------------------------------------------- -# Produce `calc.y'. Don't call this macro directly, because it contains -# some occurrences of `$1' etc. which will be interpreted by m4. So -# you should call it with $1, $2, and $3 as arguments, which is what -# AT_DATA_CALC_Y does. +# Produce `calc.y' and, if %defines was specified, `calc-lex.c' or +# `calc-lex.cc'. +# +# Don't call this macro directly, because it contains some occurrences +# of `$1' etc. which will be interpreted by m4. So you should call it +# with $1, $2, and $3 as arguments, which is what AT_DATA_CALC_Y does. m4_define([_AT_DATA_CALC_Y], [m4_if([$1$2$3], $[1]$[2]$[3], [], [m4_fatal([$0: Invalid arguments: $@])])dnl +m4_pushdef([AT_CALC_LEX], +[[#include + +int ]AT_NAME_PREFIX[lex (]AT_LEX_FORMALS[); +static int get_char (]AT_LEX_FORMALS[); +static void unget_char (]AT_LEX_PRE_FORMALS[ int c); + +]AT_LOCATION_IF([ +static YYLTYPE last_yylloc; +])[ +static int +get_char (]AT_LEX_FORMALS[) +{ + int res = getc (input); + ]AT_USE_LEX_ARGS[; +]AT_LOCATION_IF([ + last_yylloc = AT_LOC; + if (res == '\n') + { + AT_LOC.last_line++; + AT_LOC.last_column = 1; + } + else + AT_LOC.last_column++; +])[ + return res; +} + +static void +unget_char (]AT_LEX_PRE_FORMALS[ int c) +{ + ]AT_USE_LEX_ARGS[; +]AT_LOCATION_IF([ + /* Wrong when C == `\n'. */ + AT_LOC = last_yylloc; +])[ + ungetc (c, input); +} + +static int +read_signed_integer (]AT_LEX_FORMALS[) +{ + int c = get_char (]AT_LEX_ARGS[); + int sign = 1; + int n = 0; + + ]AT_USE_LEX_ARGS[; + if (c == '-') + { + c = get_char (]AT_LEX_ARGS[); + sign = -1; + } + + while (isdigit (c)) + { + n = 10 * n + (c - '0'); + c = get_char (]AT_LEX_ARGS[); + } + + unget_char (]AT_LEX_PRE_ARGS[ c); + + return sign * n; +} + + +/*---------------------------------------------------------------. +| Lexical analyzer returns an integer on the stack and the token | +| NUM, or the ASCII character read if not a number. Skips all | +| blanks and tabs, returns 0 for EOF. | +`---------------------------------------------------------------*/ + +int +]AT_NAME_PREFIX[lex (]AT_LEX_FORMALS[) +{ + static int init = 1; + int c; + + if (init) + { + init = 0; +]AT_LOCATION_IF([ + AT_LOC.last_column = 1; + AT_LOC.last_line = 1; +])[ + } + +]AT_LOCATION_IF([ + AT_LOC.first_column = AT_LOC.last_column; + AT_LOC.first_line = AT_LOC.last_line; +])[ + + /* Skip white space. */ + while ((c = get_char (]AT_LEX_ARGS[)) == ' ' || c == '\t') + { +]AT_LOCATION_IF( +[ AT_LOC.first_column = AT_LOC.last_column; + AT_LOC.first_line = AT_LOC.last_line; +])[ + } + + /* process numbers */ + if (c == '.' || isdigit (c)) + { + unget_char (]AT_LEX_PRE_ARGS[ c); + ]AT_VAL[.ival = read_signed_integer (]AT_LEX_ARGS[); + return NUM; + } + + /* Return end-of-file. */ + if (c == EOF) + return CALC_EOF; + + /* Return single chars. */ + return c; +} +]]) + AT_DATA_GRAMMAR([calc.y], [[/* Infix notation calculator--calc */ ]$4 AT_SKEL_CC_IF( [%define global_tokens_and_yystype])[ -%{ -#include +%code requires { +/* Exercise pre-prologue dependency to %union. */ +typedef int semantic_value; +} +/* Exercise %union. */ +%union +{ + semantic_value ival; +}; + +%code provides { +#include +/* The input. */ +extern FILE *input;]AT_SKEL_CC_IF([[ +#ifndef YYLTYPE +# define YYLTYPE ]AT_NAME_PREFIX[::location +#endif +#define first_line begin.line +#define first_column begin.column +#define last_line end.line +#define last_column end.column]])[ +} + +%code { #include #include #if HAVE_UNISTD_H @@ -51,33 +192,13 @@ AT_SKEL_CC_IF( # undef alarm # define alarm(seconds) /* empty */ #endif -#include #define USE(Var) -/* Exercise pre-prologue dependency to %union. */ -typedef int semantic_value; - +FILE *input; static semantic_value global_result = 0; static int global_count = 0; -%} - -/* Exercise %union. */ -%union -{ - semantic_value ival; -}; - -%{ static int power (int base, int exponent); -]AT_SKEL_CC_IF( -[#ifndef YYLTYPE -[#] define YYLTYPE AT_NAME_PREFIX::location -#endif -#define first_line begin.line -#define first_column begin.column -#define last_line end.line -#define last_column end.column -], +]AT_SKEL_CC_IF(, [/* yyerror receives the location if: - %location & %pure & %glr - %location & %pure & %yacc & %parse-param. */ @@ -85,10 +206,8 @@ static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ]) AT_PARAM_IF([semantic_value *result, int *count, ]) const char *s );])[ -static int yylex (]AT_LEX_FORMALS[); -static int get_char (]AT_LEX_FORMALS[); -static void unget_char (]AT_LEX_PRE_FORMALS[ int c); -%} +int yylex (]AT_LEX_FORMALS[); +} ]AT_SKEL_CC_IF( [/* The lalr1.cc skeleton, for backward compatibility, defines @@ -144,8 +263,6 @@ exp: | '-' error { $$ = 0; YYERROR; } ; %% -/* The input. */ -static FILE *input; ]AT_SKEL_CC_IF( [/* A C++ error reporting function. */ @@ -185,117 +302,7 @@ AT_YYERROR_SEES_LOC_IF([ fprintf (stderr, "%s\n", s); }])[ - -]AT_LOCATION_IF([ -static YYLTYPE last_yylloc; -])[ -static int -get_char (]AT_LEX_FORMALS[) -{ - int res = getc (input); - ]AT_USE_LEX_ARGS[; -]AT_LOCATION_IF([ - last_yylloc = AT_LOC; - if (res == '\n') - { - AT_LOC.last_line++; - AT_LOC.last_column = 1; - } - else - AT_LOC.last_column++; -])[ - return res; -} - - -static void -unget_char (]AT_LEX_PRE_FORMALS[ int c) -{ - ]AT_USE_LEX_ARGS[; -]AT_LOCATION_IF([ - /* Wrong when C == `\n'. */ - AT_LOC = last_yylloc; -])[ - ungetc (c, input); -} - -static int -read_signed_integer (]AT_LEX_FORMALS[) -{ - int c = get_char (]AT_LEX_ARGS[); - int sign = 1; - int n = 0; - - ]AT_USE_LEX_ARGS[; - if (c == '-') - { - c = get_char (]AT_LEX_ARGS[); - sign = -1; - } - - while (isdigit (c)) - { - n = 10 * n + (c - '0'); - c = get_char (]AT_LEX_ARGS[); - } - - unget_char (]AT_LEX_PRE_ARGS[ c); - - return sign * n; -} - - - -/*---------------------------------------------------------------. -| Lexical analyzer returns an integer on the stack and the token | -| NUM, or the ASCII character read if not a number. Skips all | -| blanks and tabs, returns 0 for EOF. | -`---------------------------------------------------------------*/ - -static int -yylex (]AT_LEX_FORMALS[) -{ - static int init = 1; - int c; - - if (init) - { - init = 0; -]AT_LOCATION_IF([ - AT_LOC.last_column = 1; - AT_LOC.last_line = 1; -])[ - } - -]AT_LOCATION_IF([ - AT_LOC.first_column = AT_LOC.last_column; - AT_LOC.first_line = AT_LOC.last_line; -])[ - - /* Skip white space. */ - while ((c = get_char (]AT_LEX_ARGS[)) == ' ' || c == '\t') - { -]AT_LOCATION_IF( -[ AT_LOC.first_column = AT_LOC.last_column; - AT_LOC.first_line = AT_LOC.last_line; -])[ - } - - /* process numbers */ - if (c == '.' || isdigit (c)) - { - unget_char (]AT_LEX_PRE_ARGS[ c); - ]AT_VAL[.ival = read_signed_integer (]AT_LEX_ARGS[); - return NUM; - } - - /* Return end-of-file. */ - if (c == EOF) - return CALC_EOF; - - /* Return single chars. */ - return c; -} +]AT_DEFINES_IF(, [AT_CALC_LEX])[ static int power (int base, int exponent) @@ -343,12 +350,18 @@ main (int argc, const char **argv) return status; } ]]) +AT_DEFINES_IF([AT_DATA_SOURCE([[calc-lex.c]AT_SKEL_CC_IF([[c]])], +[[#include "calc.h]AT_SKEL_CC_IF([[h]])[" + +]AT_CALC_LEX])]) +m4_popdef([AT_CALC_LEX]) ])# _AT_DATA_CALC_Y # AT_DATA_CALC_Y([BISON-OPTIONS]) # ------------------------------- -# Produce `calc.y'. +# Produce `calc.y' and, if %defines was specified, `calc-lex.c' or +# `calc-lex.cc'. m4_define([AT_DATA_CALC_Y], [_AT_DATA_CALC_Y($[1], $[2], $[3], [$1]) ]) @@ -453,12 +466,7 @@ m4_ifval([$2], [AT_CHECK([exit 77])]) AT_BISON_OPTION_PUSHDEFS([$1]) AT_DATA_CALC_Y([$1]) - -AT_SKEL_CC_IF( - [AT_BISON_CHECK([-o calc.cc calc.y]) - AT_COMPILE_CXX([calc])], - [AT_BISON_CHECK([-o calc.c calc.y]) - AT_COMPILE([calc])]) +AT_FULL_COMPILE([calc], [AT_DEFINES_IF([[lex]])]) # Test the priorities. _AT_CHECK_CALC([$1], diff --git a/tests/local.at b/tests/local.at index 59765c54..01adaf5d 100644 --- a/tests/local.at +++ b/tests/local.at @@ -1,7 +1,8 @@ # Process this -*- Autotest -*- file with autom4te. # Macros for the GNU Bison Test suite. -# Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. +# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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 @@ -39,6 +40,8 @@ m4_define([AT_BISON_OPTION_PUSHDEFS], m4_define([_AT_BISON_OPTION_PUSHDEFS], [m4_if([$1$2], $[1]$[2], [], [m4_fatal([$0: Invalid arguments: $@])])dnl +m4_pushdef([AT_DEFINES_IF], +[m4_bmatch([$3], [%defines], [$1], [$2])]) m4_pushdef([AT_SKEL_CC_IF], [m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])]) m4_pushdef([AT_GLR_IF], @@ -100,8 +103,8 @@ AT_PURE_LEX_IF( m4_pushdef([AT_LEX_PRE_ARGS], [AT_LEX_ARGS, ]) ], -[m4_pushdef([AT_LOC], [(yylloc)]) - m4_pushdef([AT_VAL], [(yylval)]) +[m4_pushdef([AT_LOC], [[(]AT_NAME_PREFIX[lloc)]]) + m4_pushdef([AT_VAL], [[(]AT_NAME_PREFIX[lval)]]) m4_pushdef([AT_LEX_FORMALS], [void]) m4_pushdef([AT_LEX_ARGS], []) m4_pushdef([AT_USE_LEX_ARGS], []) @@ -135,6 +138,7 @@ m4_popdef([AT_GLR_IF]) m4_popdef([AT_SKEL_CC_IF]) m4_popdef([AT_GLR_CC_IF]) m4_popdef([AT_LALR1_CC_IF]) +m4_popdef([AT_DEFINES_IF]) ])# AT_BISON_OPTION_POPDEFS @@ -143,21 +147,37 @@ m4_popdef([AT_LALR1_CC_IF]) ## Generating Grammar Files. ## ## -------------------------- ## +# AT_DATA_SOURCE_PROLOGUE +# ------------------------ +# The prologue that should be included in any source code that is +# meant to be compiled. +m4_define([AT_DATA_SOURCE_PROLOGUE], +[[#include +/* We don't need perfect functions for these tests. */ +#undef malloc +#undef memcmp +#undef realloc +]]) # AT_DATA_GRAMMAR_PROLOGUE # ------------------------ # The prologue that should be included in any grammar which parser is # meant to be compiled. m4_define([AT_DATA_GRAMMAR_PROLOGUE], -[[%{ -#include -/* We don't need perfect functions for these tests. */ -#undef malloc -#undef memcmp -#undef realloc -%}] -]) +[[%code top { +]AT_DATA_SOURCE_PROLOGUE[]dnl +[} +]]) +# AT_DATA_SOURCE(NAME, CONTENT) +# ----------------------------- +# Generate the file NAME, which CONTENT is preceded by +# AT_DATA_SOURCE_PROLOGUE. +m4_define([AT_DATA_SOURCE], +[AT_DATA([$1], +[AT_DATA_SOURCE_PROLOGUE +$2]) +]) # AT_DATA_GRAMMAR(NAME, CONTENT) # ------------------------------ @@ -268,6 +288,20 @@ AT_CHECK([$CXX $CXXFLAGS $CPPFLAGS m4_bmatch([$1], [[.]], [], [$LDFLAGS ])-o $1 0, [ignore], [ignore])]) +# AT_FULL_COMPILE(OUTPUT, [OTHER]) +# -------------------------------- +# Compile OUTPUT.y to OUTPUT.c or OUTPUT.cc, and compile it to OUTPUT. +# If OTHER is specified, compile OUTPUT-OTHER.c or OUTPUT-OTHER.cc to OUTPUT +# along with it. +# Relies on AT_SKEL_CC_IF. +m4_define([AT_FULL_COMPILE], +[AT_SKEL_CC_IF( + [AT_BISON_CHECK([-o $1.cc $1.y]) + AT_COMPILE_CXX([$1]m4_ifval($2, [, [$1.cc $1-$2.cc]]))], + [AT_BISON_CHECK([-o $1.c $1.y]) + AT_COMPILE([$1]m4_ifval($2, [, [$1.c $1-$2.c]]))]) +]) + ## ---------------------------- ## ## Running a generated parser. ## From a957d06cef15e00e35e26fa87a93b9183d1ec220 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Wed, 19 Nov 2008 12:06:34 -0500 Subject: [PATCH 010/404] * NEWS: Update for recent changes. --- ChangeLog | 4 ++++ NEWS | 11 ++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3015d924..92bda4e5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-11-19 Joel E. Denny + + * NEWS: Update for recent changes. + 2008-11-18 Joel E. Denny Fix unexpanded macros in GLR defines file. diff --git a/NEWS b/NEWS index 9ee61800..9cfc9c63 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,9 @@ Bison News * Changes in version ?.? (????-??-??): +** In the GLR defines file, unexpanded M4 macros in the yylval and yylloc + declarations have been fixed. + ** Temporary hack for adding a semicolon to the user action. Bison used to prepend a trailing semicolon at the end of the user @@ -16,9 +19,11 @@ Bison News This prevents the future support for languages than do not use `;' as C/C++/Java do. Yet some grammars still depend on this `feature'. - Bison 2.4.1 restores the previous behavior to leave more time for - grammars depending on the old behavior to be adjusted. Future - release of Bison will disable this feature. + Bison 2.4.1 restores the previous behavior in the case of C output + to leave more time for grammars depending on the old behavior to be + adjusted. Future releases of Bison will disable this feature. + +** A few minor improvements to the Bison manual. * Changes in version 2.4 (2008-11-02): From 7e6d1e2296b8dab7e37e9414c058d0d290fad1c3 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Wed, 19 Nov 2008 12:14:37 -0500 Subject: [PATCH 011/404] * NEWS: Clarify a little. --- ChangeLog | 4 ++++ NEWS | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 92bda4e5..bc754133 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-11-19 Joel E. Denny + + * NEWS: Clarify a little. + 2008-11-19 Joel E. Denny * NEWS: Update for recent changes. diff --git a/NEWS b/NEWS index 9cfc9c63..56edc707 100644 --- a/NEWS +++ b/NEWS @@ -20,8 +20,10 @@ Bison News This prevents the future support for languages than do not use `;' as C/C++/Java do. Yet some grammars still depend on this `feature'. Bison 2.4.1 restores the previous behavior in the case of C output - to leave more time for grammars depending on the old behavior to be - adjusted. Future releases of Bison will disable this feature. + (specifically, when neither %language or %skeleton or equivalent + command-line options are used) to leave more time for grammars + depending on the old behavior to be adjusted. Future releases of + Bison will disable this feature. ** A few minor improvements to the Bison manual. From bee1df15b2707caeeda551d8ae316c64d4797c08 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 5 Dec 2008 09:26:38 -0700 Subject: [PATCH 012/404] Build testsuite with newer autoconf. * tests/output.at (m4_expand): Don't override in newer autoconf, where the underlying implementation changed. * tests/cxx-type.at (_AT_RESOLVED_GLR_OUTPUT) (_AT_RESOLVED_GLR_OUTPUT_WITH_LOC, _AT_AMBIG_GLR_OUTPUT) (_AT_AMBIG_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR) (_AT_VERBOSE_GLR_STDERR): Expand to double-quoted strings, since some of them contain unbalanced ')'. Signed-off-by: Eric Blake --- ChangeLog | 23 +++++++++++++++++------ tests/cxx-type.at | 28 ++++++++++++++-------------- tests/output.at | 5 +++-- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc754133..b6da40d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-12-05 Eric Blake + + Build testsuite with newer autoconf. + * tests/output.at (m4_expand): Don't override in newer autoconf, + where the underlying implementation changed. + * tests/cxx-type.at (_AT_RESOLVED_GLR_OUTPUT) + (_AT_RESOLVED_GLR_OUTPUT_WITH_LOC, _AT_AMBIG_GLR_OUTPUT) + (_AT_AMBIG_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR) + (_AT_VERBOSE_GLR_STDERR): Expand to double-quoted strings, + since some of them contain unbalanced ')'. + 2008-11-19 Joel E. Denny * NEWS: Clarify a little. @@ -280,9 +291,9 @@ 2008-08-29 Akim Demaille Clarify UPDATED use. - * doc/bison.texinfo: It refers to the last edition of this file, + * doc/bison.texinfo: It refers to the last edition of this file, not to the release date of Bison. - Reported by Joel E. Denny. + Reported by Joel E. Denny. 2008-08-29 Akim Demaille @@ -302,15 +313,15 @@ 2008-08-27 Akim Demaille Check yyerrok in calc.at. - * tests/calc.at (calc.y): Use yyerrok on "( error )". - (AT_CHECK_CALC): Add a check that ensures that yyerrok works as - expected. + * tests/calc.at (calc.y): Use yyerrok on "( error )". + (AT_CHECK_CALC): Add a check that ensures that yyerrok works as + expected. 2008-08-27 Akim Demaille Support yyerrok in lalr1.cc. YYBACKUP is still to import back into lalr1.cc. - * data/lalr1.cc (yyerrork, yyclearin, YYRECOVERING): Define. + * data/lalr1.cc (yyerrork, yyclearin, YYRECOVERING): Define. 2008-08-26 Joel E. Denny diff --git a/tests/cxx-type.at b/tests/cxx-type.at index 0725bfc1..923dc237 100644 --- a/tests/cxx-type.at +++ b/tests/cxx-type.at @@ -1,6 +1,6 @@ # Checking GLR Parsing. -*- Autotest -*- -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, -# Inc. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 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 @@ -351,7 +351,7 @@ AT_BISON_OPTION_POPDEFS ]) m4_define([_AT_RESOLVED_GLR_OUTPUT], -[[+(z,q) +[[[+(z,q) (T,x) (T,x,y) =(x,y) @@ -360,10 +360,10 @@ m4_define([_AT_RESOLVED_GLR_OUTPUT], (T,y,+(z,q)) +(z,q) -]]) +]]]) m4_define([_AT_RESOLVED_GLR_OUTPUT_WITH_LOC], -[[3.0-3.5: +(z,q) +[[[3.0-3.5: +(z,q) 5.0-5.3: (T,x) 7.0-7.7: (T,x,y) 9.0-9.5: =(x,y) @@ -372,10 +372,10 @@ m4_define([_AT_RESOLVED_GLR_OUTPUT_WITH_LOC], 15.0-15.13: (T,y,+(z,q)) 17.0-17.15: 19.0-19.5: +(z,q) -]]) +]]]) m4_define([_AT_AMBIG_GLR_OUTPUT], -[[+(z,q) +[[[+(z,q) (T,x) (T,x,y) =(x,y) @@ -384,10 +384,10 @@ m4_define([_AT_AMBIG_GLR_OUTPUT], ((T,y,+(z,q)),=((y,T),+(z,q))) +(z,q) -]]) +]]]) m4_define([_AT_AMBIG_GLR_OUTPUT_WITH_LOC], -[[3.0-3.5: +(z,q) +[[[3.0-3.5: +(z,q) 5.0-5.3: (T,x) 7.0-7.7: (T,x,y) 9.0-9.5: =(x,y) @@ -396,15 +396,15 @@ m4_define([_AT_AMBIG_GLR_OUTPUT_WITH_LOC], 15.0-15.13: ((T,y,+(z,q)),=((y,T),+(z,q))) 17.0-17.15: 19.0-19.5: +(z,q) -]]) +]]]) m4_define([_AT_GLR_STDERR], -[[syntax error -]]) +[[[syntax error +]]]) m4_define([_AT_VERBOSE_GLR_STDERR], -[[syntax error, unexpected ID, expecting '=' or '+' or ')' -]]) +[[[syntax error, unexpected ID, expecting '=' or '+' or ')' +]]]) ## ---------------------------------------------------- ## ## Compile the grammar described in the documentation. ## diff --git a/tests/output.at b/tests/output.at index 1e37347f..ce0a2b27 100644 --- a/tests/output.at +++ b/tests/output.at @@ -200,9 +200,10 @@ AT_CLEANUP AT_CHECK_OUTPUT_FILE_NAME([[`~!@#$%^&*()-=_+{}[]|\:;<>, .']]) dnl Work around a bug in m4_expand that broke AT_SETUP in autoconf 2.62, dnl by using the definition from 2.63. -m4_define([m4_expand], [_$0(-=<{($1)}>=-)]) +m4_version_prereq([2.63], [], +[m4_define([m4_expand], [_$0(-=<{($1)}>=-)]) m4_define([_m4_expand], -[m4_changequote([-=<{(], [)}>=-])$1m4_changequote([, ])]) +[m4_changequote([-=<{(], [)}>=-])$1m4_changequote([, ])])]) AT_CHECK_OUTPUT_FILE_NAME([[(]]) AT_CHECK_OUTPUT_FILE_NAME([[)]]) AT_CHECK_OUTPUT_FILE_NAME([[#]]) From 1eb0b146594c8b4a8e7aa06e4fcf275739d0900f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Wed, 5 Nov 2008 07:00:04 +0100 Subject: [PATCH 013/404] Spelling fixes. * NEWS: s/than/that/. --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 56edc707..72d73e13 100644 --- a/NEWS +++ b/NEWS @@ -17,7 +17,7 @@ Bison News exp: exp "+" exp { $$ = $1 + $3; }; - This prevents the future support for languages than do not use `;' + This prevents the future support for languages that do not use `;' as C/C++/Java do. Yet some grammars still depend on this `feature'. Bison 2.4.1 restores the previous behavior in the case of C output (specifically, when neither %language or %skeleton or equivalent From 876fd8357ac4e2aa2fd8dac29c6a8b52ed58c682 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 9 Dec 2008 13:24:18 +0100 Subject: [PATCH 014/404] Update data/README. * data/README: Document glr.cc, lalr1.java, m4sugar and xslt. --- ChangeLog | 5 +++++ data/README | 41 ++++++++++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index b6da40d9..a5bca840 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-12-09 Akim Demaille + + Update data/README. + * data/README: Document glr.cc, lalr1.java, m4sugar and xslt. + 2008-12-05 Eric Blake Build testsuite with newer autoconf. diff --git a/data/README b/data/README index 94aad558..18e025c1 100644 --- a/data/README +++ b/data/README @@ -1,31 +1,58 @@ -*- outline -*- -This directory contains Bison skeletons: the general shapes of the -different parser kinds, that are specialized for specific grammars by -the bison program. +This directory contains data needed by Bison. -Currently, there are only three supported skeletons: +* Skeletons +Bison skeletons: the general shapes of the different parser kinds, +that are specialized for specific grammars by the bison program. + +Currently, the supported skeletons are: - yacc.c It used to be named bison.simple: it corresponds to C Yacc compatible LALR(1) parsers. - lalr1.cc - Produces a C++ parser class. It is still very experimental, and not - yet supported. Please, subscribe to bison-patches@gnu.org. + Produces a C++ parser class. + +- lalr1.java + Produces a Java parser class. - glr.c A Generalized LR C parser based on Bison's LALR(1) tables. +- glr.cc + A Generalized LR C++ parser. Actually a C++ wrapper around glr.c. + These skeletons are the only ones supported by the Bison team. Because the interface between skeletons and the bison program is not finished, *we are not bound to it*. In particular, Bison is not mature enough for us to consider that ``foreign skeletons'' are supported. +* m4sugar +This directory contains M4sugar, sort of an extended library for M4, +which is used by Bison to instantiate the skeletons. + +* xslt +This directory contains XSLT programs that transform Bison's XML output +into various formats. + +- bison.xsl + A library of routines used by the other XSLT programs. + +- xml2dot.xsl + Conversion into GraphViz's dot format. + +- xml2text.xsl + Conversion into text. + +- xml2xhtml.xsl + Conversion into XHTML. + ----- -Copyright (C) 2002 Free Software Foundation, Inc. +Copyright (C) 2002, 2008 Free Software Foundation, Inc. This file is part of GNU Bison. From 0364b3344f9d69fa90a3001b8b9d05f4bec1ce75 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Thu, 11 Dec 2008 14:25:10 -0500 Subject: [PATCH 015/404] * gnulib: Update submodule to HEAD. --- ChangeLog | 4 ++++ gnulib | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a5bca840..b969ee69 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2008-12-11 Joel E. Denny + + * gnulib: Update submodule to HEAD. + 2008-12-09 Akim Demaille Update data/README. diff --git a/gnulib b/gnulib index 2c64312e..58fe6dca 160000 --- a/gnulib +++ b/gnulib @@ -1 +1 @@ -Subproject commit 2c64312ecca19a60629cb929c1ae759109c772b5 +Subproject commit 58fe6dca7be83f48966dda3711bf8da48ee9ab7f From d07932ef3d14aae86149b8ff65258f520ffa3998 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Thu, 11 Dec 2008 15:37:24 -0500 Subject: [PATCH 016/404] Semicolon feature removal is not about future language support. * NEWS: The semicolon feature is no longer active for newer languages, so don't claim that it causes trouble for them. --- ChangeLog | 6 ++++++ NEWS | 13 ++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index b969ee69..d3cb7bb0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-12-11 Joel E. Denny + + Semicolon feature removal is not about future language support. + * NEWS: The semicolon feature is no longer active for newer languages, + so don't claim that it causes trouble for them. + 2008-12-11 Joel E. Denny * gnulib: Update submodule to HEAD. diff --git a/NEWS b/NEWS index 72d73e13..d67e3f03 100644 --- a/NEWS +++ b/NEWS @@ -17,13 +17,12 @@ Bison News exp: exp "+" exp { $$ = $1 + $3; }; - This prevents the future support for languages that do not use `;' - as C/C++/Java do. Yet some grammars still depend on this `feature'. - Bison 2.4.1 restores the previous behavior in the case of C output - (specifically, when neither %language or %skeleton or equivalent - command-line options are used) to leave more time for grammars - depending on the old behavior to be adjusted. Future releases of - Bison will disable this feature. + Some grammars still depend on this `feature'. Bison 2.4.1 restores + the previous behavior in the case of C output (specifically, when + neither %language or %skeleton or equivalent command-line options + are used) to leave more time for grammars depending on the old + behavior to be adjusted. Future releases of Bison will disable this + feature. ** A few minor improvements to the Bison manual. From 41930e7ad89f9a889b1c00fbd2842dded01ada1a Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Thu, 11 Dec 2008 16:06:48 -0500 Subject: [PATCH 017/404] Version 2.4.1. * NEWS: Set version and date. * lib/Makefile.am: Update copyright year. * tests/atlocal.in: Update copyright year. --- ChangeLog | 7 +++++++ NEWS | 2 +- lib/Makefile.am | 3 ++- tests/atlocal.in | 4 ++-- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3cb7bb0..f28a8478 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-12-11 Joel E. Denny + + Version 2.4.1. + * NEWS: Set version and date. + * lib/Makefile.am: Update copyright year. + * tests/atlocal.in: Update copyright year. + 2008-12-11 Joel E. Denny Semicolon feature removal is not about future language support. diff --git a/NEWS b/NEWS index d67e3f03..7d1a444d 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,7 @@ Bison News ---------- -* Changes in version ?.? (????-??-??): +* Changes in version 2.4.1 (2008-12-11): ** In the GLR defines file, unexpanded M4 macros in the yylval and yylloc declarations have been fixed. diff --git a/lib/Makefile.am b/lib/Makefile.am index 4ec82d94..03d4138f 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,6 +1,7 @@ # Make bison/lib. -# Copyright (C) 2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. +# Copyright (C) 2001, 2002, 2003, 2004, 2006, 2008 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 diff --git a/tests/atlocal.in b/tests/atlocal.in index a67c4dc3..1a5f5f4f 100644 --- a/tests/atlocal.in +++ b/tests/atlocal.in @@ -1,8 +1,8 @@ # @configure_input@ -*- shell-script -*- # Configurable variable values for Bison test suite. -# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software -# Foundation, Inc. +# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free +# Software Foundation, Inc. # We need a C compiler. CC='@CC@' From 8defe11bfa8e614988f4f9cd66f9abcd051b8abb Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 8 Jan 2009 09:41:21 +0100 Subject: [PATCH 018/404] Fix grep portability issues. Grep on Solaris does not support -q. Reported by Summum Bonum. * NEWS: Add a stub for 2.4.2. * THANKS: Add Summum Bonum. * tests/atlocal.in (EGREP): New. (CC, CXX, XSLTPROC): Make it possible to override them via envvars. * tests/java.at: Use $EGREP instead of egrep. Use AT_CHECK's ignore instead of grep's -q. --- ChangeLog | 14 ++++++++++++++ NEWS | 6 ++++-- THANKS | 3 ++- tests/atlocal.in | 13 ++++++++----- tests/java.at | 22 +++++++++++----------- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index f28a8478..5320ec3e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2009-01-08 Akim Demaille + + Fix grep portability issues. + Grep on Solaris does not support -q. + Reported by Summum Bonum. + + * NEWS: Add a stub for 2.4.2. + * THANKS: Add Summum Bonum. + * tests/atlocal.in (EGREP): New. + (CC, CXX, XSLTPROC): Make it possible to override them via + envvars. + * tests/java.at: Use $EGREP instead of egrep. + Use AT_CHECK's ignore instead of grep's -q. + 2008-12-11 Joel E. Denny Version 2.4.1. diff --git a/NEWS b/NEWS index 7d1a444d..69c6d3b2 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ Bison News ---------- +* Changes in version 2.4.2 (????-??-??): + * Changes in version 2.4.1 (2008-12-11): ** In the GLR defines file, unexpanded M4 macros in the yylval and yylloc @@ -1049,9 +1051,9 @@ End: ----- Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, -2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. -This file is part of Bison, the GNU Compiler Compiler. +This file is part of Bison, the GNU Parser Generator. 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 diff --git a/THANKS b/THANKS index 40291c71..d7addddd 100644 --- a/THANKS +++ b/THANKS @@ -78,11 +78,12 @@ Raja R Harinath harinath@cs.umn.edu Richard Stallman rms@gnu.org Robert Anisko anisko_r@epita.fr Satya Kiran Popuri satyakiran@gmail.com -Sebastien Fricker sebastien.fricker@gmail.com Sebastian Setzer sebastian.setzer.ext@siemens.com +Sebastien Fricker sebastien.fricker@gmail.com Sergei Steshenko sergstesh@yahoo.com Shura debil_urod@ngs.ru Steve Murphy murf@parsetree.com +Summum Bonum sum@geekhouse.org Tim Josling tej@melbpc.org.au Tim Van Holder tim.van.holder@pandora.be Tom Lane tgl@sss.pgh.pa.us diff --git a/tests/atlocal.in b/tests/atlocal.in index 1a5f5f4f..91ba6742 100644 --- a/tests/atlocal.in +++ b/tests/atlocal.in @@ -1,11 +1,11 @@ # @configure_input@ -*- shell-script -*- # Configurable variable values for Bison test suite. -# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free -# Software Foundation, Inc. +# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +# 2009 Free Software Foundation, Inc. # We need a C compiler. -CC='@CC@' +: ${CC='@CC@'} # We want no optimization. CFLAGS='@O0CFLAGS@ @WARN_CFLAGS@ @WERROR_CFLAGS@' @@ -17,7 +17,7 @@ CPPFLAGS="-I$abs_top_builddir/lib @CPPFLAGS@" GCC='@GCC@' # The C++ compiler. -CXX='@CXX@' +: ${CXX='@CXX@'} # If 'exit 77'; skip all C++ tests; otherwise ':'. BISON_CXX_WORKS='@BISON_CXX_WORKS@' @@ -38,4 +38,7 @@ CONF_JAVAC='@CONF_JAVAC@' CONF_JAVA='@CONF_JAVA@' # Empty if no xsltproc was found -XSLTPROC='@XSLTPROC@' +: ${XSLTPROC='@XSLTPROC@'} + +# We need egrep. +: ${EGREP='@EGREP@'} diff --git a/tests/java.at b/tests/java.at index a3e1a0ed..ac6564f7 100644 --- a/tests/java.at +++ b/tests/java.at @@ -1,6 +1,6 @@ # Java tests for simple calculator. -*- Autotest -*- -# Copyright (C) 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2007, 2008, 2009 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 @@ -134,7 +134,7 @@ AT_LOCATION_IF([[ ]], [[ public void yyerror (String s) { - System.err.println (s); + System.err.println (s); } ]])[ @@ -342,7 +342,7 @@ _AT_CHECK_JAVA_CALC_ERROR([$1], [/dev/null], # first error is ")", which is needed to recover from the error and # produce the "0" that triggers the "0 != 1" error. # -_AT_CHECK_JAVA_CALC_ERROR([$1], +_AT_CHECK_JAVA_CALC_ERROR([$1], [() + (1 + 1 + 1 +) + (* * *) + (1 * 2 * *) = 1], [1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' 1: syntax error, unexpected ')', expecting number or '-' or '(' or '!' @@ -426,7 +426,7 @@ start: "end" {$2}; class m4_default([$3], [Position]) {} ]) AT_BISON_CHECK([[YYParser.y]]) -AT_CHECK([[grep -q '[mb]4_' YYParser.y]], [1]) +AT_CHECK([[grep '[mb]4_' YYParser.y]], [1], [ignore]) AT_JAVA_COMPILE([[YYParser.java]]) ]) @@ -458,7 +458,7 @@ m4_define([AT_CHECK_JAVA_MINIMAL_W_LEXER], { $3 } - + $4 }], [$5], [$7])]) @@ -747,9 +747,9 @@ AT_CHECK_JAVA_MINIMAL([[ %define location_type "MyLoc" %define position_type "MyPos" %code { class MyPos {} }]], [[$$ = $1;]], [[MyPos]]) -AT_CHECK([[grep -q 'java.awt.Color' YYParser.java]]) -AT_CHECK([[egrep -v ' */?\*' YYParser.java | grep -q 'Position']], [1]) -AT_CHECK([[egrep -v ' */?\*' YYParser.java | grep -q 'Location']], [1]) +AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore]) +AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Position']], [1], [ignore]) +AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Location']], [1], [ignore]) AT_CHECK_JAVA_MINIMAL_W_LEXER([[ %define stype "java.awt.Color" @@ -759,8 +759,8 @@ AT_CHECK_JAVA_MINIMAL_W_LEXER([[ %code { class MyPos {} }]], [], [[return EOF;]], [], [[$$ = $1;]], [[java.awt.Color]], [[MyPos]], [[MyLoc]]) -AT_CHECK([[grep -q 'java.awt.Color' YYParser.java]]) -AT_CHECK([[egrep -v ' */?\*' YYParser.java | grep -q 'Position']], [1]) -AT_CHECK([[egrep -v ' */?\*' YYParser.java | grep -q 'Location']], [1]) +AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore]) +AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Position']], [1], [ignore]) +AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Location']], [1], [ignore]) AT_CLEANUP From 5339158d012074343af6d44e52e38b7456f6e386 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 12 Feb 2009 09:51:53 +0100 Subject: [PATCH 019/404] Update gnulib. --- gnulib | 2 +- lib/.cvsignore | 2 ++ lib/.gitignore | 2 ++ m4/.cvsignore | 6 ++++++ m4/.gitignore | 6 ++++++ 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/gnulib b/gnulib index 58fe6dca..66216f48 160000 --- a/gnulib +++ b/gnulib @@ -1 +1 @@ -Subproject commit 58fe6dca7be83f48966dda3711bf8da48ee9ab7f +Subproject commit 66216f4811a8d82810e88371c64214191b31e244 diff --git a/lib/.cvsignore b/lib/.cvsignore index 7b8ba6b5..412882f3 100644 --- a/lib/.cvsignore +++ b/lib/.cvsignore @@ -41,6 +41,8 @@ inttypes_.h localcharset.c localcharset.h malloc.c +mbrtowc.c +mbsinit.c mbswidth.c mbswidth.h obstack.c diff --git a/lib/.gitignore b/lib/.gitignore index c9cc650f..b647a928 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -44,6 +44,8 @@ /localcharset.c /localcharset.h /malloc.c +/mbrtowc.c +/mbsinit.c /mbswidth.c /mbswidth.h /obstack.c diff --git a/m4/.cvsignore b/m4/.cvsignore index 462f3028..3cdc569e 100644 --- a/m4/.cvsignore +++ b/m4/.cvsignore @@ -1,3 +1,4 @@ +00gnulib.m4 absolute-header.m4 argmatch.m4 config-h.m4 @@ -29,11 +30,16 @@ lib-ld.m4 lib-link.m4 lib-prefix.m4 localcharset.m4 +locale-fr.m4 +locale-ja.m4 +locale-zh.m4 longlong.m4 malloc.m4 mbrtowc.m4 +mbsinit.m4 mbstate_t.m4 mbswidth.m4 +multiarch.m4 nls.m4 po.m4 progtest.m4 diff --git a/m4/.gitignore b/m4/.gitignore index 6c4d5665..0755b7d7 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -1,3 +1,4 @@ +/00gnulib.m4 /absolute-header.m4 /argmatch.m4 /config-h.m4 @@ -29,11 +30,16 @@ /lib-link.m4 /lib-prefix.m4 /localcharset.m4 +/locale-fr.m4 +/locale-ja.m4 +/locale-zh.m4 /longlong.m4 /malloc.m4 /mbrtowc.m4 +/mbsinit.m4 /mbstate_t.m4 /mbswidth.m4 +/multiarch.m4 /nls.m4 /po.m4 /progtest.m4 From f3079439416261c4c58b5faed343a4aaa3ada5dd Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 26 Mar 2009 22:59:01 +0100 Subject: [PATCH 020/404] gnulib: update. * gnulib: Update to latest. * lib/Makefile.am (AM_CPPFLAGS): It is now defined by gnulib, so use +=. --- ChangeLog | 7 +++++++ gnulib | 2 +- lib/Makefile.am | 6 +++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5320ec3e..7e225f9d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-03-26 Akim Demaille + + gnulib: update. + * gnulib: Update to latest. + * lib/Makefile.am (AM_CPPFLAGS): It is now defined by gnulib, so + use +=. + 2009-01-08 Akim Demaille Fix grep portability issues. diff --git a/gnulib b/gnulib index 66216f48..5a1286a9 160000 --- a/gnulib +++ b/gnulib @@ -1 +1 @@ -Subproject commit 66216f4811a8d82810e88371c64214191b31e244 +Subproject commit 5a1286a9f8597c0063a82645b55f3e97433fc521 diff --git a/lib/Makefile.am b/lib/Makefile.am index 03d4138f..f7c3bef5 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -1,7 +1,7 @@ # Make bison/lib. -# Copyright (C) 2001, 2002, 2003, 2004, 2006, 2008 Free Software Foundation, -# Inc. +# Copyright (C) 2001, 2002, 2003, 2004, 2006, 2008, 2009 +# 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 @@ -18,7 +18,7 @@ include gnulib.mk -AM_CFLAGS = $(WARN_CFLAGS) +AM_CFLAGS += $(WARN_CFLAGS) # Implementation of bitsets. bitsets_sources = \ From b328890a9e62573176b34279fb59f0b97935f33a Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 26 Mar 2009 23:02:18 +0100 Subject: [PATCH 021/404] lalr1.cc: avoid GCC 4.3 warnings. GCC 4.3 now warns about "a || b && c" and asks for explicit parentheses. Reported by Alexandre Duret-Lutz. * data/location.cc: Update copyright years. (Position::operator==): Use parens to make precedence explicit. Compare lines and columns first, as they are more likely to be different, and they are faster to compare. --- ChangeLog | 11 +++++++++++ data/location.cc | 17 +++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7e225f9d..2713a500 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-03-26 Akim Demaille + + lalr1.cc: avoid GCC 4.3 warnings. + GCC 4.3 now warns about "a || b && c" and asks for explicit + parentheses. + Reported by Alexandre Duret-Lutz. + * data/location.cc: Update copyright years. + (Position::operator==): Use parens to make precedence explicit. + Compare lines and columns first, as they are more likely to be + different, and they are faster to compare. + 2009-03-26 Akim Demaille gnulib: update. diff --git a/data/location.cc b/data/location.cc index 4b79069f..2adde81a 100644 --- a/data/location.cc +++ b/data/location.cc @@ -1,7 +1,7 @@ # C++ skeleton for Bison -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, -# Inc. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009 +# 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 @@ -21,7 +21,7 @@ m4_changecom() m4_divert_push(0)dnl @output(b4_dir_prefix[]position.hh@) b4_copyright([Positions for Bison parsers in C++], - [2002, 2003, 2004, 2005, 2006])[ + [2002, 2003, 2004, 2005, 2006, 2007, 2009])[ /** ** \file position.hh @@ -116,10 +116,11 @@ b4_copyright([Positions for Bison parsers in C++], inline bool operator== (const position& pos1, const position& pos2) { - return - (pos1.filename == pos2.filename - || pos1.filename && pos2.filename && *pos1.filename == *pos2.filename) - && pos1.line == pos2.line && pos1.column == pos2.column; + return (pos1.line == pos2.line + && pos1.column == pos2.column + && (pos1.filename == pos2.filename + || (pos1.filename && pos2.filename + && *pos1.filename == *pos2.filename))); } /// Compare two position objects. @@ -145,7 +146,7 @@ b4_copyright([Positions for Bison parsers in C++], #endif // not BISON_POSITION_HH] @output(b4_dir_prefix[]location.hh@) b4_copyright([Locations for Bison parsers in C++], - [2002, 2003, 2004, 2005, 2006])[ + [2002, 2003, 2004, 2005, 2006, 2007, 2009])[ /** ** \file location.hh From 6469c4d72b031e3dccce7051db812bd03208bd85 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 26 Mar 2009 23:14:45 +0100 Subject: [PATCH 022/404] doc: update README-hacking. * README-hacking: We now use git and git submodules. Reported by Ralf Wildenhues and Alexandre Duret-Lutz. --- ChangeLog | 6 +++++ README-hacking | 62 ++++++++++++++++++++++++++++++++++++++++++++------ THANKS | 1 + 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2713a500..c163347d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-03-26 Akim Demaille + + doc: update README-hacking. + * README-hacking: We now use git and git submodules. + Reported by Ralf Wildenhues and Alexandre Duret-Lutz. + 2009-03-26 Akim Demaille lalr1.cc: avoid GCC 4.3 warnings. diff --git a/README-hacking b/README-hacking index 1116a6c0..a63cabbd 100644 --- a/README-hacking +++ b/README-hacking @@ -39,31 +39,79 @@ Obviously, if you are reading these notes, you did manage to check out this package from the repository. For the record, you will find all the relevant information on: - http://savannah.gnu.org/cvs/?group_id=56 + http://savannah.gnu.org/git/?group=bison + +Bison uses Git submodules: subscriptions to other Git repositories. +In particular it uses gnulib, the GNU portability library. To ask Git +to perform the first checkout of the submodules, run + + $ git submodule update --init + +Git submodule support is weak before versions 1.6 and later, you +should probably upgrade Git if your version is older. The next step is to get other files needed to build, which are extracted from other source packages: - $ ./bootstrap + $ ./bootstrap And there you are! Just - $ ./configure - $ make - $ make check + $ ./configure + $ make + $ make check At this point, there should be no difference between your local copy, and the master copy: - $ cvs diff + $ git diff should output no difference. Enjoy! +* Updating + +The use of submodules make things somewhat different because git does +not support recursive operations: submodules must be taken care of +explicitly by the user. + +** Updating Bison + +If you pull a newer version of a branch, say via `git pull', you might +import requests for updated submodules. A simple `git diff' will +reveal if the current version of the submodule (i.e., the actual +contents of the gnulib directory) and the current request from the +subscriber (i.e., the reference of the version of gnulib that the +Bison reporitory requests) differ. To upgrade the submodules (i.e., +to check out the version that is actually requested by the subscriber, +run `git submodule update'. + + $ git pull + $ git submodule update + +** Updating a submodule +To update a submodule, say gnulib, do as follows: + +Get the most recent version of the master branch from git. + + $ cd gnulib + $ git fetch + $ git checkout -b master --track origin/master + +Make sure Bison can live with that version of gnulib. + + $ cd .. + $ ./bootstrap + $ make distcheck + +Register your changes. + + $ git checkin ... + ----- -Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software +Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify diff --git a/THANKS b/THANKS index d7addddd..4c847f52 100644 --- a/THANKS +++ b/THANKS @@ -75,6 +75,7 @@ Piotr Gackiewicz gacek@intertel.com.pl Quoc Peyrot chojin@lrde.epita.fr R Blake blakers@mac.com Raja R Harinath harinath@cs.umn.edu +Ralf Wildenhues Ralf.Wildenhues@gmx.de Richard Stallman rms@gnu.org Robert Anisko anisko_r@epita.fr Satya Kiran Popuri satyakiran@gmail.com From 26fccd4d7bbae99c25837862d4b979765e35831f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 26 Mar 2009 23:36:18 +0100 Subject: [PATCH 023/404] doc: merge HACKING and README-hacking. Two files is confusing. Reported by Alexandre Duret-Lutz. * README-hacking: Merge into... * HACKING (Working from the repository): here. --- ChangeLog | 9 ++++ HACKING | 117 +++++++++++++++++++++++++++++++++++++++++++- README-hacking | 128 ------------------------------------------------- 3 files changed, 124 insertions(+), 130 deletions(-) delete mode 100644 README-hacking diff --git a/ChangeLog b/ChangeLog index c163347d..7b39f16e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-03-26 Akim Demaille + + doc: merge HACKING and README-hacking. + Two files is confusing. + Reported by Alexandre Duret-Lutz. + + * README-hacking: Merge into... + * HACKING (Working from the repository): here. + 2009-03-26 Akim Demaille doc: update README-hacking. diff --git a/HACKING b/HACKING index 091ba66c..14693965 100644 --- a/HACKING +++ b/HACKING @@ -5,7 +5,7 @@ Don't put this file into the distribution. Everything related to the development of Bison is on Savannah: - http://savannah.gnu.org/projects/bison/ + http://savannah.gnu.org/projects/bison/ * Administrivia @@ -47,6 +47,118 @@ of the .output file etc. This excludes impossible error messages meant for the maintainers only. +* Working from the repository + +These notes intend to help people working on the checked-out sources. +These requirements do not apply when building from a distribution tarball. + +** Requirements + +We've opted to keep only the highest-level sources in the repository. +This eases our maintenance burden, (fewer merges etc.), but imposes more +requirements on anyone wishing to build from the just-checked-out sources. +For example, you have to use the latest stable versions of the maintainer +tools we depend upon, including: + +- Automake +- Autoconf +- Flex +- Gettext +- Gzip +- Perl +- Rsync +- Tar + +Valgrind is also highly recommended, if +Valgrind supports your architecture. + +Bison is written using Bison grammars, so there are bootstrapping +issues. The bootstrap script attempts to discover when the C code +generated from the grammars is out of date, and to bootstrap with an +out-of-date version of the C code, but the process is not foolproof. +Also, you may run into similar problems yourself if you modify Bison. + +Only building the initial full source tree will be a bit painful. +Later, after synchronizing from the repository a plain `make' should +be sufficient. + +** First checkout + +Obviously, if you are reading these notes, you did manage to check out +this package from the repository. For the record, you will find all the +relevant information on: + + http://savannah.gnu.org/git/?group=bison + +Bison uses Git submodules: subscriptions to other Git repositories. +In particular it uses gnulib, the GNU portability library. To ask Git +to perform the first checkout of the submodules, run + + $ git submodule update --init + +Git submodule support is weak before versions 1.6 and later, you +should probably upgrade Git if your version is older. + +The next step is to get other files needed to build, which are +extracted from other source packages: + + $ ./bootstrap + +And there you are! Just + + $ ./configure + $ make + $ make check + +At this point, there should be no difference between your local copy, +and the master copy: + + $ git diff + +should output no difference. + +Enjoy! + +** Updating + +The use of submodules make things somewhat different because git does +not support recursive operations: submodules must be taken care of +explicitly by the user. + +*** Updating Bison + +If you pull a newer version of a branch, say via `git pull', you might +import requests for updated submodules. A simple `git diff' will +reveal if the current version of the submodule (i.e., the actual +contents of the gnulib directory) and the current request from the +subscriber (i.e., the reference of the version of gnulib that the +Bison reporitory requests) differ. To upgrade the submodules (i.e., +to check out the version that is actually requested by the subscriber, +run `git submodule update'. + + $ git pull + $ git submodule update + +*** Updating a submodule +To update a submodule, say gnulib, do as follows: + +Get the most recent version of the master branch from git. + + $ cd gnulib + $ git fetch + $ git checkout -b master --track origin/master + +Make sure Bison can live with that version of gnulib. + + $ cd .. + $ ./bootstrap + $ make distcheck + +Register your changes. + + $ git checkin ... + + * Test suite ** make check @@ -195,7 +307,8 @@ Push these changes. ----- -Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. +Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009 +Free Software Foundation, Inc. This file is part of GNU Bison. diff --git a/README-hacking b/README-hacking deleted file mode 100644 index a63cabbd..00000000 --- a/README-hacking +++ /dev/null @@ -1,128 +0,0 @@ --*- outline -*- - -These notes intend to help people working on the checked-out sources. -These requirements do not apply when building from a distribution tarball. - -* Requirements - -We've opted to keep only the highest-level sources in the repository. -This eases our maintenance burden, (fewer merges etc.), but imposes more -requirements on anyone wishing to build from the just-checked-out sources. -For example, you have to use the latest stable versions of the maintainer -tools we depend upon, including: - -- Automake -- Autoconf -- Flex -- Gettext -- Gzip -- Perl -- Rsync -- Tar - -Valgrind is also highly recommended, if -Valgrind supports your architecture. - -Bison is written using Bison grammars, so there are bootstrapping -issues. The bootstrap script attempts to discover when the C code -generated from the grammars is out of date, and to bootstrap with an -out-of-date version of the C code, but the process is not foolproof. -Also, you may run into similar problems yourself if you modify Bison. - -Only building the initial full source tree will be a bit painful. -Later, after synchronizing from the repository a plain `make' should -be sufficient. - -* First checkout - -Obviously, if you are reading these notes, you did manage to check out -this package from the repository. For the record, you will find all the -relevant information on: - - http://savannah.gnu.org/git/?group=bison - -Bison uses Git submodules: subscriptions to other Git repositories. -In particular it uses gnulib, the GNU portability library. To ask Git -to perform the first checkout of the submodules, run - - $ git submodule update --init - -Git submodule support is weak before versions 1.6 and later, you -should probably upgrade Git if your version is older. - -The next step is to get other files needed to build, which are -extracted from other source packages: - - $ ./bootstrap - -And there you are! Just - - $ ./configure - $ make - $ make check - -At this point, there should be no difference between your local copy, -and the master copy: - - $ git diff - -should output no difference. - -Enjoy! - -* Updating - -The use of submodules make things somewhat different because git does -not support recursive operations: submodules must be taken care of -explicitly by the user. - -** Updating Bison - -If you pull a newer version of a branch, say via `git pull', you might -import requests for updated submodules. A simple `git diff' will -reveal if the current version of the submodule (i.e., the actual -contents of the gnulib directory) and the current request from the -subscriber (i.e., the reference of the version of gnulib that the -Bison reporitory requests) differ. To upgrade the submodules (i.e., -to check out the version that is actually requested by the subscriber, -run `git submodule update'. - - $ git pull - $ git submodule update - -** Updating a submodule -To update a submodule, say gnulib, do as follows: - -Get the most recent version of the master branch from git. - - $ cd gnulib - $ git fetch - $ git checkout -b master --track origin/master - -Make sure Bison can live with that version of gnulib. - - $ cd .. - $ ./bootstrap - $ make distcheck - -Register your changes. - - $ git checkin ... - ------ - -Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2009 Free Software -Foundation, Inc. - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . From 2075a82a18ad334ec61ba777d0d61de08e2b64cb Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 31 Mar 2009 10:40:17 +0200 Subject: [PATCH 024/404] bootstrap: README-hacking no longer exists * bootstrap (checkout_only_file): Set to HACKING. --- ChangeLog | 5 +++++ bootstrap | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b39f16e..ff9105d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-03-31 Akim Demaille + + bootstrap: README-hacking no longer exists + * bootstrap (checkout_only_file): Set to HACKING. + 2009-03-26 Akim Demaille doc: merge HACKING and README-hacking. diff --git a/bootstrap b/bootstrap index f92d1ccd..72090116 100755 --- a/bootstrap +++ b/bootstrap @@ -2,8 +2,8 @@ # Bootstrap this package from checked-out sources. -# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, -# Inc. +# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# 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 @@ -129,7 +129,7 @@ excluded_files= # File that should exist in the top directory of a checked out hierarchy, # but not in a distribution tarball. -checkout_only_file=README-hacking +checkout_only_file=HACKING # Whether to use copies instead of symlinks. copy=false From c1455babda1c43195e185a8590678836ad08ac8f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 31 Mar 2009 10:41:25 +0200 Subject: [PATCH 025/404] bootstrap: --help to stdout. * bootstrap (usage): Don't send --help to stderr. Use a here doc instead of a long string. --- ChangeLog | 6 ++++++ bootstrap | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ff9105d5..0eae269f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-03-31 Akim Demaille + + bootstrap: --help to stdout. + * bootstrap (usage): Don't send --help to stderr. + Use a here doc instead of a long string. + 2009-03-31 Akim Demaille bootstrap: README-hacking no longer exists diff --git a/bootstrap b/bootstrap index 72090116..4b0abfa6 100755 --- a/bootstrap +++ b/bootstrap @@ -36,7 +36,7 @@ bt_regex=`echo "$bt"| sed 's/\./[.]/g'` bt2=${bt}2 usage() { - echo >&2 "\ + cat < Date: Tue, 3 Feb 2009 03:08:32 -0500 Subject: [PATCH 026/404] Add reminder about uploading public key to keys.gnupg.net. * HACKING (Release Procedure): Here. (cherry picked from commit 06c3084fb5a566e802ba35a9cc54be51db7fe6f1) --- ChangeLog | 5 +++++ HACKING | 12 +++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0eae269f..92166b09 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-02-03 Joel E. Denny + + Add reminder about uploading public key to keys.gnupg.net. + * HACKING (Release Procedure): Here. + 2009-03-31 Akim Demaille bootstrap: --help to stdout. diff --git a/HACKING b/HACKING index 14693965..16dff1a5 100644 --- a/HACKING +++ b/HACKING @@ -257,9 +257,15 @@ The generic GNU upload procedure is at: http://www.gnu.org/prep/maintain/maintain.html#Automated-FTP-Uploads -After following the instructions there to register your information so you're -permitted to upload, here's a brief reminder of how to roll the tarballs and -upload them: +Follow the instructions there to register your information so you're permitted +to upload. Make sure your public key has been uploaded at least to +keys.gnupg.net. You can upload it with: + + gpg --keyserver keys.gnupg.net --send-keys F125BDF3 + +where F125BDF3 should be replaced with your key ID. + +Here's a brief reminder of how to roll the tarballs and upload them: *** make distcheck *** gpg -b bison-2.3b.tar.gz From 5d3a1ecbbe1d0a97d12c1699c720c3ce7c079a3a Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 29 Jul 2008 12:45:21 +0200 Subject: [PATCH 027/404] Locations without columns for command line arguments. * src/location.c (location_print): Don't display negative columns. * src/location.h: Document this. (cherry picked from commit 56c5eca97359ecc15481c6b9dff8f34c63219d70) --- ChangeLog | 6 ++++++ src/location.c | 10 ++++++---- src/location.h | 12 ++++++++---- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 92166b09..0bebbdfd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-11-07 Akim Demaille + + Locations without columns for command line arguments. + * src/location.c (location_print): Don't display negative columns. + * src/location.h: Document this. + 2009-02-03 Joel E. Denny Add reminder about uploading public key to keys.gnupg.net. diff --git a/src/location.c b/src/location.c index 57adf188..98627a55 100644 --- a/src/location.c +++ b/src/location.c @@ -1,5 +1,5 @@ /* Locations for Bison - Copyright (C) 2002, 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2002, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -101,9 +101,11 @@ void location_print (FILE *out, location loc) { int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0; - fprintf (out, "%s:%d.%d", + fprintf (out, "%s:%d", quotearg_n_style (3, escape_quoting_style, loc.start.file), - loc.start.line, loc.start.column); + loc.start.line); + if (0 <= loc.start.column) + fprintf (out, ".%d", loc.start.column); if (loc.start.file != loc.end.file) fprintf (out, "-%s:%d.%d", @@ -111,7 +113,7 @@ location_print (FILE *out, location loc) loc.end.line, end_col); else if (loc.start.line < loc.end.line) fprintf (out, "-%d.%d", loc.end.line, end_col); - else if (loc.start.column < end_col) + else if (0 <= loc.start.column && loc.start.column < end_col) fprintf (out, "-%d", end_col); } diff --git a/src/location.h b/src/location.h index 785947ef..efd256dd 100644 --- a/src/location.h +++ b/src/location.h @@ -1,5 +1,5 @@ /* Locations for Bison - Copyright (C) 2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -31,9 +31,13 @@ typedef struct If this is INT_MAX, the line number has overflowed. */ int line; - /* The (origin-1) column just after the boundary. This is neither a - byte count, nor a character count; it is a column count. - If this is INT_MAX, the column number has overflowed. */ + /* If nonnegative, the (origin-1) column just after the boundary. + This is neither a byte count, nor a character count; it is a + column count. If this is INT_MAX, the column number has + overflowed. + + Meaningless and not displayed if negative. + */ int column; } boundary; From 580c075d7f6a06d84149fd789a42528371621b7d Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 3 Apr 2009 03:13:36 -0400 Subject: [PATCH 028/404] Fix strange %define locations for default values. Reported by Akim Demaille at and discussed again starting at . * data/bison.m4 (b4_percent_define_default): Leave syncline blank because location information is bogus. Use angle brackets to delimit fake file name because square brackets look like over-quoted m4. Choose a better fake file name. Use negative line numbers. * src/muscle_tab.c (muscle_percent_define_default): Likewise. * src/location.c (location_print): If line for a boundary is negative, only print that boundary's file name. * src/location.h: Document that. * tests/skeletons.at (%define Boolean variables: invalid skeleton defaults): Update output. --- ChangeLog | 19 +++++++++++++++++++ data/bison.m4 | 11 +++++------ src/location.c | 47 +++++++++++++++++++++++++++++++--------------- src/location.h | 10 +++++++--- src/muscle_tab.c | 9 ++++----- tests/skeletons.at | 4 ++-- 6 files changed, 69 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0bebbdfd..e0c738b9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2009-04-03 Joel E. Denny + + Fix strange %define locations for default values. + Reported by Akim Demaille at + + and discussed again starting at + . + * data/bison.m4 (b4_percent_define_default): Leave syncline blank + because location information is bogus. + Use angle brackets to delimit fake file name because square brackets + look like underexpanded m4. Choose a better fake file name. + Use negative line numbers. + * src/muscle_tab.c (muscle_percent_define_default): Likewise. + * src/location.c (location_print): If line for a boundary is negative, + only print that boundary's file name. + * src/location.h: Document that. + * tests/skeletons.at (%define Boolean variables: invalid skeleton + defaults): Update output. + 2008-11-07 Akim Demaille Locations without columns for command line arguments. diff --git a/data/bison.m4 b/data/bison.m4 index bad62963..f9dd503d 100644 --- a/data/bison.m4 +++ b/data/bison.m4 @@ -1,8 +1,8 @@ -*- Autoconf -*- # Language-independent M4 Macros for Bison. -# Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, -# Inc. +# Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009 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 @@ -464,10 +464,9 @@ m4_define([b4_percent_define_default], [m4_ifndef([b4_percent_define(]$1[)], [m4_define([b4_percent_define(]$1[)], [$2])dnl m4_define([b4_percent_define_loc(]$1[)], - [[[[[Bison:b4_percent_define_default]:1.0]], [[[Bison:b4_percent_define_default]:1.0]]]])dnl - m4_define([b4_percent_define_syncline(]$1[)], - [[]b4_syncline(1, [["[Bison:b4_percent_define_default]"]])[ -]])])]) + [[[[:-1.-1]], + [[:-1.-1]]]])dnl + m4_define([b4_percent_define_syncline(]$1[)], [[]])])]) # b4_percent_define_check_values(VALUES) # -------------------------------------- diff --git a/src/location.c b/src/location.c index 98627a55..4cbfd8db 100644 --- a/src/location.c +++ b/src/location.c @@ -1,5 +1,6 @@ /* Locations for Bison - Copyright (C) 2002, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2002, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, + Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -100,21 +101,37 @@ location_compute (location *loc, boundary *cur, char const *token, size_t size) void location_print (FILE *out, location loc) { - int end_col = 0 < loc.end.column ? loc.end.column - 1 : 0; - fprintf (out, "%s:%d", - quotearg_n_style (3, escape_quoting_style, loc.start.file), - loc.start.line); - if (0 <= loc.start.column) - fprintf (out, ".%d", loc.start.column); - + int end_col = 0 != loc.end.column ? loc.end.column - 1 : 0; + fprintf (out, "%s", + quotearg_n_style (3, escape_quoting_style, loc.start.file)); + if (0 <= loc.start.line) + { + fprintf(out, ":%d", loc.start.line); + if (0 <= loc.start.column) + fprintf (out, ".%d", loc.start.column); + } if (loc.start.file != loc.end.file) - fprintf (out, "-%s:%d.%d", - quotearg_n_style (3, escape_quoting_style, loc.end.file), - loc.end.line, end_col); - else if (loc.start.line < loc.end.line) - fprintf (out, "-%d.%d", loc.end.line, end_col); - else if (0 <= loc.start.column && loc.start.column < end_col) - fprintf (out, "-%d", end_col); + { + fprintf (out, "-%s", + quotearg_n_style (3, escape_quoting_style, loc.end.file)); + if (0 <= loc.end.line) + { + fprintf(out, ":%d", loc.end.line); + if (0 <= end_col) + fprintf (out, ".%d", end_col); + } + } + else if (0 <= loc.end.line) + { + if (loc.start.line < loc.end.line) + { + fprintf (out, "-%d", loc.end.line); + if (0 <= end_col) + fprintf (out, ".%d", end_col); + } + else if (0 <= end_col && loc.start.column < end_col) + fprintf (out, "-%d", end_col); + } } void diff --git a/src/location.h b/src/location.h index efd256dd..a99232bd 100644 --- a/src/location.h +++ b/src/location.h @@ -1,5 +1,6 @@ /* Locations for Bison - Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software + Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -27,8 +28,11 @@ typedef struct /* The name of the file that contains the boundary. */ uniqstr file; - /* The (origin-1) line that contains the boundary. - If this is INT_MAX, the line number has overflowed. */ + /* If nonnegative, the (origin-1) line that contains the boundary. + If this is INT_MAX, the line number has overflowed. + + Meaningless and not displayed if negative. + */ int line; /* If nonnegative, the (origin-1) column just after the boundary. diff --git a/src/muscle_tab.c b/src/muscle_tab.c index afe59bec..43415716 100644 --- a/src/muscle_tab.c +++ b/src/muscle_tab.c @@ -1,6 +1,6 @@ /* Muscle table manager for Bison. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -540,13 +540,12 @@ muscle_percent_define_default (char const *variable, char const *value) { location loc; MUSCLE_INSERT_STRING (name, value); - loc.start.file = loc.end.file = "[Bison:muscle_percent_define_default]"; - loc.start.line = loc.end.line = 1; - loc.start.column = loc.end.column = 0; + loc.start.file = loc.end.file = ""; + loc.start.line = loc.end.line = -1; + loc.start.column = loc.end.column = -1; muscle_insert (loc_name, ""); muscle_location_grow (loc_name, loc); muscle_insert (syncline_name, ""); - muscle_syncline_grow (syncline_name, loc); } } diff --git a/tests/skeletons.at b/tests/skeletons.at index 3845d3dd..60fc1176 100644 --- a/tests/skeletons.at +++ b/tests/skeletons.at @@ -1,5 +1,5 @@ # Checking skeleton support. -*- Autotest -*- -# Copyright (C) 2007 Free Software Foundation, Inc. +# Copyright (C) 2007, 2009 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 @@ -159,7 +159,7 @@ start: ; ]]) AT_BISON_CHECK([[input.y]], [[1]], [[]], -[[[Bison:b4_percent_define_default]:1.0: invalid value for %define Boolean variable `foo' +[[: invalid value for %define Boolean variable `foo' ]]) AT_CLEANUP From 5bc993d947cf23057d9f0e2706ea32e89762f718 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 3 Apr 2009 18:32:02 -0400 Subject: [PATCH 029/404] Help with updating web manual. * HACKING: Incorporate instructions from gnulib/doc/README. * bootstrap.conf (gnulib_modules): Add gendocs. --- ChangeLog | 10 ++++++++-- HACKING | 41 +++++++++++++++++++++++++++++++++++++++++ bootstrap.conf | 14 +++++++------- build-aux/.cvsignore | 1 + build-aux/.gitignore | 1 + doc/.cvsignore | 5 +++-- doc/.gitignore | 5 +++-- 7 files changed, 64 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index e0c738b9..1b7afc4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-04-03 Joel E. Denny + + Help with updating web manual. + * HACKING: Incorporate instructions from gnulib/doc/README. + * bootstrap.conf (gnulib_modules): Add gendocs. + 2009-04-03 Joel E. Denny Fix strange %define locations for default values. @@ -44,7 +50,7 @@ doc: merge HACKING and README-hacking. Two files is confusing. Reported by Alexandre Duret-Lutz. - + * README-hacking: Merge into... * HACKING (Working from the repository): here. @@ -77,7 +83,7 @@ Fix grep portability issues. Grep on Solaris does not support -q. Reported by Summum Bonum. - + * NEWS: Add a stub for 2.4.2. * THANKS: Add Summum Bonum. * tests/atlocal.in (EGREP): New. diff --git a/HACKING b/HACKING index 16dff1a5..82f07bb4 100644 --- a/HACKING +++ b/HACKING @@ -283,6 +283,47 @@ Here's a brief reminder of how to roll the tarballs and upload them: *** put bison-2.3b.tar.gz.directive.asc *** Repeat all these steps for bison-2.3b.tar.bz2. +** Update Bison manual on www.gnu.org. + +*** You need a non-anonymous checkout of the web pages directory. + + $ cvs -d YOUR_USERID@cvs.savannah.gnu.org:/web/bison checkout bison + +*** Get familiar with the instructions for web page maintainers. +http://www.gnu.org/server/standards/readme_index.html +http://www.gnu.org/server/standards/README.software.html +especially the note about symlinks. + +*** Build the web pages. +Assuming BISON_CHECKOUT refers to a checkout of the Bison dir, and +BISON_WWW_CHECKOUT refers to the web directory created above, do: + + $ cd $BISON_CHECKOUT/doc + $ make stamp-vti + $ ../build-aux/gendocs.sh -o "$BISON_WWW_CHECKOUT/manual" \ + bison "Bison - GNU parser generator" + $ cd $BISON_WWW_CHECKOUT + +Verify that the result looks sane. + +*** Commit the modified and the new files. + +*** Remove old files. +Find the files which have not been overwritten (because they belonged to +sections that have been removed or renamed): + + $ cd manual/html_node + $ ls -lt + +Remove these files and commit their removal to CVS. For each of these +files, add a line to the file .symlinks. This will ensure that +hyperlinks to the removed files will redirect to the entire manual; this +is better than a 404 error. + +There is a problem with 'index.html' being written twice (once for POSIX +function 'index', once for the table of contents); you can ignore this +issue. + ** Announce To generate a template announcement file: diff --git a/bootstrap.conf b/bootstrap.conf index bcab1b89..c7596c17 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -1,6 +1,6 @@ # Bootstrap configuration. -# Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2006, 2007, 2008, 2009 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 @@ -17,12 +17,12 @@ # gnulib modules used by this package. gnulib_modules=' - announce-gen argmatch config-h c-strcase configmake - dirname error extensions fopen-safer getopt gettext git-version-gen - gnumakefile hash inttypes javacomp-script javaexec-script malloc - mbswidth obstack quote quotearg stdbool stpcpy strerror strtoul - strverscmp unistd unistd-safer unlocked-io unsetenv verify - warnings xalloc xalloc-die xstrndup + announce-gen argmatch config-h c-strcase configmake dirname error + extensions fopen-safer gendocs getopt gettext git-version-gen + gnumakefile hash inttypes javacomp-script javaexec-script malloc + mbswidth obstack quote quotearg stdbool stpcpy strerror strtoul + strverscmp unistd unistd-safer unlocked-io unsetenv verify warnings + xalloc xalloc-die xstrndup ' # Additional xgettext options to use. Use "\\\newline" to break lines. diff --git a/build-aux/.cvsignore b/build-aux/.cvsignore index 2edd4b15..771f0efc 100644 --- a/build-aux/.cvsignore +++ b/build-aux/.cvsignore @@ -6,6 +6,7 @@ config.guess config.rpath config.sub depcomp +gendocs.sh git-version-gen install-sh javacomp.sh.in diff --git a/build-aux/.gitignore b/build-aux/.gitignore index db9bb9f6..29d77959 100644 --- a/build-aux/.gitignore +++ b/build-aux/.gitignore @@ -6,6 +6,7 @@ /config.rpath /config.sub /depcomp +/gendocs.sh /git-version-gen /install-sh /javacomp.sh.in diff --git a/doc/.cvsignore b/doc/.cvsignore index 0376b3e7..28087990 100644 --- a/doc/.cvsignore +++ b/doc/.cvsignore @@ -1,4 +1,6 @@ +*.info* Makefile +Makefile.in bison.1 bison.aux bison.cp @@ -15,11 +17,10 @@ bison.toc bison.tp bison.vr cross-options.texi -Makefile.in +gendocs_template refcard.dvi refcard.log refcard.ps -*.info* stamp-vti version.texi yacc.1 diff --git a/doc/.gitignore b/doc/.gitignore index 1d55073d..341c2b19 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -1,4 +1,6 @@ +/*.info* /Makefile +/Makefile.in /bison.1 /bison.aux /bison.cp @@ -15,11 +17,10 @@ /bison.tp /bison.vr /cross-options.texi -/Makefile.in +/gendocs_template /refcard.dvi /refcard.log /refcard.ps -/*.info* /stamp-vti /version.texi /yacc.1 From f490771b4bc4aaed04d2927c0fc8cfbe774fa701 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Sat, 4 Apr 2009 02:45:01 -0400 Subject: [PATCH 030/404] * ChangeLog: Update copyright. --- ChangeLog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1b7afc4c..6de34795 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21201,8 +21201,8 @@ ----- Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, - 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 - Free Software Foundation, Inc. + 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2007, 2008, 2009 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, are permitted provided the copyright notice and this From 8ba62e3e10ae35a50dd4ae0cf4d87b3ffe00852c Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Sat, 4 Apr 2009 21:12:23 -0400 Subject: [PATCH 031/404] Replace BISON_PROG_GNU_M4 with Autoconf's AC_PROG_GNU_M4. If the first m4 in $PATH is wrong, it keeps looking. Moreover, its requirements for a correct m4 are stricter. * m4/m4.m4: Replace with Autoconf 2.63's m4/m4.m4. * configure.ac: Update to use AC_PROG_GNU_M4. Reported by Eric Blake. --- ChangeLog | 9 +++++++ configure.ac | 9 +++---- m4/m4.m4 | 71 +++++++++++++++++++++++++++++++++------------------- 3 files changed, 57 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6de34795..e3d6dddd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-04-04 Joel E. Denny + + Replace BISON_PROG_GNU_M4 with Autoconf's AC_PROG_GNU_M4. + If the first m4 in $PATH is wrong, it keeps looking. Moreover, its + requirements for a correct m4 are stricter. + * m4/m4.m4: Replace with Autoconf 2.63's m4/m4.m4. + * configure.ac: Update to use AC_PROG_GNU_M4. + Reported by Eric Blake. + 2009-04-03 Joel E. Denny Help with updating web manual. diff --git a/configure.ac b/configure.ac index f1ebd8de..0954c31b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # Configure template for GNU Bison. -*-Autoconf-*- # -# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software -# Foundation, Inc. +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# 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 @@ -92,10 +92,7 @@ AC_SUBST([YACC_LIBRARY]) AC_PROG_LEX AC_PROG_YACC AC_PROG_RANLIB -BISON_PROG_GNU_M4 -if test x"$ac_cv_prog_gnu_m4" != xyes; then - AC_MSG_ERROR([GNU M4 1.4 is required]) -fi +AC_PROG_GNU_M4 AC_DEFINE_UNQUOTED([M4], ["$M4"], [Define to the GNU M4 executable name.]) AM_MISSING_PROG([HELP2MAN], [help2man]) AC_PATH_PROG([XSLTPROC], [xsltproc]) diff --git a/m4/m4.m4 b/m4/m4.m4 index be0140f0..f27d8c05 100644 --- a/m4/m4.m4 +++ b/m4/m4.m4 @@ -1,27 +1,46 @@ -# Copyright 2000 Free Software Foundation, Inc. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# m4.m4 serial 5 +dnl Copyright (C) 2000, 2006, 2007, 2008 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. -# BISON_PROG_GNU_M4 -# ----------------- -# Check for GNU m4, at least 1.3 (supports frozen files). -AC_DEFUN([BISON_PROG_GNU_M4], -[AC_PATH_PROGS(M4, gm4 gnum4 m4, m4) -AC_CACHE_CHECK(whether m4 supports frozen files, ac_cv_prog_gnu_m4, -[ac_cv_prog_gnu_m4=no -if test x"$M4" != x; then - case `$M4 --help < /dev/null 2>&1` in - *reload-state*) ac_cv_prog_gnu_m4=yes ;; - esac -fi])]) +# AC_PROG_GNU_M4 +# -------------- +# Check for GNU M4, at least 1.4.5 (all earlier versions had a bug in +# trace support: +# http://lists.gnu.org/archive/html/bug-gnu-utils/2006-11/msg00096.html) +# Also, check whether --error-output (through 1.4.x) or --debugfile (2.0) +# is supported, and AC_SUBST M4_DEBUGFILE accordingly. +AC_DEFUN([AC_PROG_GNU_M4], + [AC_ARG_VAR([M4], [Location of GNU M4 1.4.5 or later. Defaults to the first + program of `m4', `gm4', or `gnum4' on PATH that meets Autoconf needs.]) + AC_CACHE_CHECK([for GNU M4 that supports accurate traces], [ac_cv_path_M4], + [rm -f conftest.m4f +AC_PATH_PROGS_FEATURE_CHECK([M4], [m4 gm4 gnum4], + [dnl Creative quoting here to avoid raw dnl and ifdef in configure. + # Root out GNU M4 1.4.4, as well as non-GNU m4 that ignore -t, -F. + ac_snippet=change'quote(<,>)in''dir(,mac,bug)d'nl + test -z "`$ac_path_M4 -F conftest.m4f &1`" \ + && test -z "`echo $ac_snippet | $ac_path_M4 --trace=mac 2>&1`" \ + && test -f conftest.m4f \ + && ac_cv_path_M4=$ac_path_M4 ac_path_M4_found=: + rm -f conftest.m4f], + [AC_MSG_ERROR([no acceptable m4 could be found in \$PATH. +GNU M4 1.4.5 or later is required; 1.4.11 is recommended])])]) + M4=$ac_cv_path_M4 + AC_CACHE_CHECK([how m4 supports trace files], [ac_cv_prog_gnu_m4_debugfile], + [case `$M4 --help < /dev/null 2>&1` in + *debugfile*) ac_cv_prog_gnu_m4_debugfile=--debugfile ;; + *) ac_cv_prog_gnu_m4_debugfile=--error-output ;; + esac]) + AC_SUBST([M4_DEBUGFILE], [$ac_cv_prog_gnu_m4_debugfile]) +]) + +# Compatibility for bootstrapping with Autoconf 2.61. +dnl FIXME - replace this with AC_PREREQ([2.62]) after the release. +# AC_PATH_PROGS_FEATURE_CHECK was added the same time the slightly broken, +# undocumented _AC_PATH_PROG_FEATURE_CHECK was deleted. +m4_ifndef([AC_PATH_PROGS_FEATURE_CHECK], + [m4_define([AC_PATH_PROGS_FEATURE_CHECK], + [_AC_PATH_PROG_FEATURE_CHECK([$1], [$2], [$3], [$5]) +])]) From 0d2b2ab0334393ea6e8e25aacdcc511937cf7bd8 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 22 Jul 2008 10:24:53 +0200 Subject: [PATCH 032/404] Remove spurious initial empty lines. * data/glr.c, data/glr.cc, data/lalr1.cc, data/lalr1.java, * data/yacc.c: End the @output lines with an @. --- ChangeLog | 6 ++++ data/glr.c | 4 +-- data/glr.cc | 4 +-- data/lalr1.cc | 6 ++-- data/lalr1.java | 78 ++++++++++++++++++++++++------------------------- data/yacc.c | 4 +-- 6 files changed, 54 insertions(+), 48 deletions(-) diff --git a/ChangeLog b/ChangeLog index e3d6dddd..157cf954 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-11-04 Akim Demaille + + Remove spurious initial empty lines. + * data/glr.c, data/glr.cc, data/lalr1.cc, data/lalr1.java, + * data/yacc.c: End the @output lines with an @. + 2009-04-04 Joel E. Denny Replace BISON_PROG_GNU_M4 with Autoconf's AC_PROG_GNU_M4. diff --git a/data/glr.c b/data/glr.c index 84637e0e..53b7fa17 100644 --- a/data/glr.c +++ b/data/glr.c @@ -148,7 +148,7 @@ m4_define([b4_rhs_location], # We do want M4 expansion after # for CPP macros. m4_changecom() m4_divert_push(0)dnl -@output(b4_parser_file_name@) +@output(b4_parser_file_name@)@ b4_copyright([Skeleton implementation for Bison GLR parsers in C], [2002, 2003, 2004, 2005, 2006]) [ @@ -2637,7 +2637,7 @@ dnl glr.cc produces its own header. dnl m4_if(b4_skeleton, ["glr.c"], [b4_defines_if( -[@output(b4_spec_defines_file@) +[@output(b4_spec_defines_file@)@ b4_copyright([Skeleton interface for Bison GLR parsers in C], [2002, 2003, 2004, 2005, 2006]) diff --git a/data/glr.cc b/data/glr.cc index ea04b28d..afd0e613 100644 --- a/data/glr.cc +++ b/data/glr.cc @@ -1,7 +1,7 @@ -*- C -*- # C++ GLR skeleton for Bison -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, # Inc. # This program is free software: you can redistribute it and/or modify @@ -217,7 +217,7 @@ m4_include(b4_pkgdatadir/[glr.c]) m4_popdef([b4_parse_param]) m4_divert_push(0) -@output(b4_spec_defines_file@) +@output(b4_spec_defines_file@)@ b4_copyright([Skeleton interface for Bison GLR parsers in C++], [2002, 2003, 2004, 2005, 2006])[ diff --git a/data/lalr1.cc b/data/lalr1.cc index ca1dfccd..603786e5 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -33,7 +33,7 @@ m4_include(b4_pkgdatadir/[location.cc]) m4_changecom() m4_divert_push(0)dnl b4_defines_if( -[@output(b4_spec_defines_file@) +[@output(b4_spec_defines_file@)@ b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++], [2002, 2003, 2004, 2005, 2006, 2007, 2008]) dnl FIXME: This is wrong, we want computed header guards. @@ -298,7 +298,7 @@ b4_percent_code_get([[provides]])[]dnl [#endif /* ! defined PARSER_HEADER_H */] ])dnl -@output(b4_parser_file_name@) +@output(b4_parser_file_name@)@ b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++], [2002, 2003, 2004, 2005, 2006, 2007, 2008]) b4_percent_code_get([[top]])[]dnl @@ -1055,7 +1055,7 @@ b4_error_verbose_if([, int tok])[) ]b4_epilogue dnl -@output(b4_dir_prefix[]stack.hh@) +@output(b4_dir_prefix[]stack.hh@)@ b4_copyright([Stack handling for Bison parsers in C++], [2002, 2003, 2004, 2005, 2006, 2007, 2008])[ diff --git a/data/lalr1.java b/data/lalr1.java index 7e220d98..c855a75f 100644 --- a/data/lalr1.java +++ b/data/lalr1.java @@ -23,7 +23,7 @@ m4_ifval(m4_defn([b4_symbol_destructors]), []) m4_divert_push(0)dnl -@output(b4_parser_file_name@) +@output(b4_parser_file_name@)@ b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java], [2007, 2008]) @@ -130,7 +130,7 @@ b4_token_enums(b4_tokens) /** * Entry point for the scanner. Returns the token identifier corresponding * to the next token and prepares to return the semantic value - * ]b4_locations_if([and beginning/ending positions ])[of the token. + * ]b4_locations_if([and beginning/ending positions ])[of the token. * @@return the token identifier corresponding to the next token. */ int yylex () ]b4_maybe_throws([b4_lex_throws])[; @@ -228,11 +228,11 @@ b4_lexer_if([[ public int size = 16; public int height = -1; - + public final void push (int state, ]b4_yystype[ value]dnl - b4_locations_if([, ]b4_location_type[ loc])[) { + b4_locations_if([, ]b4_location_type[ loc])[) { height++; - if (size == height) + if (size == height) { int[] newStateStack = new int[size * 2]; System.arraycopy (stateStack, 0, newStateStack, 0, height); @@ -241,7 +241,7 @@ b4_lexer_if([[ ]b4_location_type[[] newLocStack = new ]b4_location_type[[size * 2]; System.arraycopy (locStack, 0, newLocStack, 0, height); locStack = newLocStack;]]) - + b4_yystype[[] newValueStack = new ]b4_yystype[[size * 2]; System.arraycopy (valueStack, 0, newValueStack, 0, height); valueStack = newValueStack; @@ -283,7 +283,7 @@ b4_lexer_if([[ public void print (java.io.PrintStream out) { out.print ("Stack now"); - + for (int i = 0; i < height; i++) { out.print (' '); @@ -337,7 +337,7 @@ b4_lexer_if([[ /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, use the top of the stack. - + Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. */ @@ -345,7 +345,7 @@ b4_lexer_if([[ yyval = yystack.valueAt (yylen - 1); else yyval = yystack.valueAt (0); - + yy_reduce_print (yyn, yystack); switch (yyn) @@ -482,11 +482,11 @@ m4_popdef([b4_at_dollar])])dnl yycdebug ("Entering state " + yystate + "\n"); if (yydebug > 0) yystack.print (yyDebugStream); - + /* Accept? */ if (yystate == yyfinal_) return true; - + /* Take a decision. First try without lookahead. */ yyn = yypact_[yystate]; if (yyn == yypact_ninf_) @@ -494,7 +494,7 @@ m4_popdef([b4_at_dollar])])dnl label = YYDEFAULT; break; } - + /* Read a lookahead token. */ if (yychar == yyempty_) { @@ -502,10 +502,10 @@ m4_popdef([b4_at_dollar])])dnl yychar = yylex ();] b4_locations_if([[ yylloc = new ]b4_location_type[(yylexer.getStartPos (), - yylexer.getEndPos ());]]) + yylexer.getEndPos ());]]) yylval = yylexer.getLVal ();[ } - + /* Convert token to internal form. */ if (yychar <= EOF) { @@ -516,15 +516,15 @@ m4_popdef([b4_at_dollar])])dnl { yytoken = yytranslate_ (yychar); yy_symbol_print ("Next token is", yytoken, - yylval]b4_locations_if([, yylloc])[); + yylval]b4_locations_if([, yylloc])[); } - + /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) label = YYDEFAULT; - + /* <= 0 means reduce or error. */ else if ((yyn = yytable_[yyn]) <= 0) { @@ -536,27 +536,27 @@ m4_popdef([b4_at_dollar])])dnl label = YYREDUCE; } } - + else { /* Shift the lookahead token. */ yy_symbol_print ("Shifting", yytoken, - yylval]b4_locations_if([, yylloc])[); - + yylval]b4_locations_if([, yylloc])[); + /* Discard the token being shifted. */ yychar = yyempty_; - + /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus_ > 0) --yyerrstatus_; - + yystate = yyn; yystack.push (yystate, yylval]b4_locations_if([, yylloc])[); label = YYNEWSTATE; } break; - + /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ @@ -567,7 +567,7 @@ m4_popdef([b4_at_dollar])])dnl else label = YYREDUCE; break; - + /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ @@ -576,7 +576,7 @@ m4_popdef([b4_at_dollar])])dnl label = yyaction (yyn, yystack, yylen); yystate = yystack.stateAt (0); break; - + /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ @@ -587,13 +587,13 @@ m4_popdef([b4_at_dollar])])dnl ++yynerrs_; yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yystate, yytoken)); } - + ]b4_locations_if([yyerrloc = yylloc;])[ if (yyerrstatus_ == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ - + if (yychar <= EOF) { /* Return failure if at end of input. */ @@ -603,17 +603,17 @@ m4_popdef([b4_at_dollar])])dnl else yychar = yyempty_; } - + /* Else will try to reuse lookahead token after shifting the error token. */ label = YYERRLAB1; break; - + /*---------------------------------------------------. | errorlab -- error raised explicitly by YYERROR. | `---------------------------------------------------*/ case YYERROR: - + ]b4_locations_if([yyerrloc = yystack.locationAt (yylen - 1);])[ /* Do not reclaim the symbols of the rule which action triggered this YYERROR. */ @@ -622,13 +622,13 @@ m4_popdef([b4_at_dollar])])dnl yystate = yystack.stateAt (0); label = YYERRLAB1; break; - + /*-------------------------------------------------------------. | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ case YYERRLAB1: yyerrstatus_ = 3; /* Each real token shifted decrements this. */ - + for (;;) { yyn = yypact_[yystate]; @@ -642,18 +642,18 @@ m4_popdef([b4_at_dollar])])dnl break; } } - + /* Pop the current state because it cannot handle the error token. */ if (yystack.height == 1) return false; - + ]b4_locations_if([yyerrloc = yystack.locationAt (0);])[ yystack.pop (); yystate = yystack.stateAt (0); if (yydebug > 0) yystack.print (yyDebugStream); } - + ]b4_locations_if([ /* Muck with the stack to setup for yylloc. */ yystack.push (0, null, yylloc); @@ -664,16 +664,16 @@ m4_popdef([b4_at_dollar])])dnl /* Shift the error token. */ yy_symbol_print ("Shifting", yystos_[yyn], yylval]b4_locations_if([, yyloc])[); - + yystate = yyn; yystack.push (yyn, yylval]b4_locations_if([, yyloc])[); label = YYNEWSTATE; break; - + /* Accept. */ case YYACCEPT: return true; - + /* Abort. */ case YYABORT: return false; @@ -842,7 +842,7 @@ m4_popdef([b4_at_dollar])])dnl for (int yyi = 0; yyi < yynrhs; yyi++) yy_symbol_print (" $" + (yyi + 1) + " =", yyrhs_[yyprhs_[yyrule] + yyi], - ]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([, + ]b4_rhs_value(yynrhs, yyi + 1)b4_locations_if([, b4_rhs_location(yynrhs, yyi + 1)])[); } diff --git a/data/yacc.c b/data/yacc.c index 19f77a5f..940b4a7a 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -153,7 +153,7 @@ m4_define([b4_rhs_location], # We do want M4 expansion after # for CPP macros. m4_changecom() m4_divert_push(0)dnl -@output(b4_parser_file_name@) +@output(b4_parser_file_name@)@ b4_copyright([Skeleton implementation for Bison's Yacc-like parsers in C],dnl ' [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006])[ @@ -1674,7 +1674,7 @@ yypushreturn: ]b4_epilogue b4_defines_if( -[@output(b4_spec_defines_file@) +[@output(b4_spec_defines_file@)@ b4_copyright([Skeleton interface for Bison's Yacc-like parsers in C],dnl ' [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006]) From c19178bfaf07d8c56af805e310573595ad67cee9 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Mon, 6 Apr 2009 00:39:49 -0400 Subject: [PATCH 033/404] Remove spurious initial empty lines. * data/location.cc: End the @output lines with an @. --- ChangeLog | 5 +++++ data/location.cc | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 157cf954..c42c0d7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-04-04 Joel E. Denny + + Remove spurious initial empty lines. + * data/location.cc: End the @output lines with an @. + 2008-11-04 Akim Demaille Remove spurious initial empty lines. diff --git a/data/location.cc b/data/location.cc index 2adde81a..d21e362a 100644 --- a/data/location.cc +++ b/data/location.cc @@ -19,7 +19,7 @@ # We do want M4 expansion after # for CPP macros. m4_changecom() m4_divert_push(0)dnl -@output(b4_dir_prefix[]position.hh@) +@output(b4_dir_prefix[]position.hh@)@ b4_copyright([Positions for Bison parsers in C++], [2002, 2003, 2004, 2005, 2006, 2007, 2009])[ @@ -144,7 +144,7 @@ b4_copyright([Positions for Bison parsers in C++], ]b4_namespace_close[ #endif // not BISON_POSITION_HH] -@output(b4_dir_prefix[]location.hh@) +@output(b4_dir_prefix[]location.hh@)@ b4_copyright([Locations for Bison parsers in C++], [2002, 2003, 2004, 2005, 2006, 2007, 2009])[ From 0213d65176bad71e1d33b257b5a6933525fef8a2 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 29 Jul 2008 12:41:48 +0200 Subject: [PATCH 034/404] Handle more general types of option arguments. * build-aux/cross-options.pl: The argument ends at the first space, not the first non-symbol character. Use @var for each word appearing the argument description. (cherry picked from commit 74eae918c3bf3772d260cb25777d9a998172a401) --- ChangeLog | 7 +++++++ build-aux/cross-options.pl | 25 ++++++++++++++++++------- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index c42c0d7b..43ed79a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-11-07 Akim Demaille + + Handle more general types of option arguments. + * build-aux/cross-options.pl: The argument ends at the first + space, not the first non-symbol character. + Use @var for each word appearing the argument description. + 2009-04-04 Joel E. Denny Remove spurious initial empty lines. diff --git a/build-aux/cross-options.pl b/build-aux/cross-options.pl index 31733e72..2cec3696 100755 --- a/build-aux/cross-options.pl +++ b/build-aux/cross-options.pl @@ -7,19 +7,27 @@ use strict; my %option; while (<>) { - if (/^\s* # Initial spaces. - (?:(-\w),\s+)? # $1: Possible short option. - (--[-\w]+) # $2: Long option. - (\[?) # $3: '[' iff the argument is optional. - (?:=([-\w]+))? # $4: Possible argument name. + if (/^\s* # Initial spaces. + (?:(-\w),\s+)? # $1: $short: Possible short option. + (--[-\w]+) # $2: $long: Long option. + (\[?) # $3: $opt: '[' iff the argument is optional. + (?:=(\S+))? # $4: $arg: Possible argument name. + \s # Spaces. /x) { my ($short, $long, $opt, $arg) = ($1, $2, $3, $4); $short = defined $short ? '@option{' . $short . '}' : ''; if ($arg) { + # if $opt, $arg contains the closing ]. + substr ($arg, -1) = '' + if $opt eq '['; $arg =~ s/^=//; - $arg = '@var{' . lc ($arg) . '}'; + $arg = lc ($arg); + # If the argument is compite (e.g., for --define[=NAME[=VALUE]]), + # put each word in @var, to build @var{name}[=@var{value}], not + # @var{name[=value]}]. + $arg =~ s/(\w+)/\@var{$1}/g; $arg = '[' . $arg . ']' if $opt eq '['; $option{"$long=$arg"} = $short ? "$short $arg" : ''; @@ -33,5 +41,8 @@ while (<>) foreach my $long (sort keys %option) { - printf "\@item %-40s \@tab %s\n", '@option{' . $long . '}', $option{$long}; + # Avoid trailing spaces. + printf ("\@item %-40s \@tab%s\n", + '@option{' . $long . '}', + $option{$long} ? " $option{$long}" : ""); } From f67c40374e6d6d02da9e43f88606b658ec2fb526 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 29 Jul 2008 12:44:28 +0200 Subject: [PATCH 035/404] Fix --help. * src/getargs.c (usage): Fix help string for -W. (cherry picked from commit 9b9e0a7d46123c50e51f6742eba1bfa0d091b8aa) --- ChangeLog | 5 +++++ src/getargs.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 43ed79a3..4b994e07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-11-07 Akim Demaille + + Fix --help. + * src/getargs.c (usage): Fix help string for -W. + 2008-11-07 Akim Demaille Handle more general types of option arguments. diff --git a/src/getargs.c b/src/getargs.c index f36f25bc..35594cc8 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -265,7 +265,7 @@ Operation modes:\n\ --print-localedir output directory containing locale-dependent data\n\ --print-datadir output directory containing skeletons and XSLT\n\ -y, --yacc emulate POSIX Yacc\n\ - -W, --warnings=[CATEGORY] report the warnings falling in CATEGORY\n\ + -W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\ \n\ "), stdout); From ecd1b61cd4998286c42ce9f1555167af73024156 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Mon, 6 Apr 2009 02:16:39 -0400 Subject: [PATCH 036/404] Fix options documentation. * build-aux/cross-options.pl: As in --help output, write optional arguments as [=ARG] not =[ARG]. * doc/bison.texinfo (Bison Options): Add -W/--warnings argument. --- ChangeLog | 7 +++++++ build-aux/cross-options.pl | 9 ++++++--- doc/bison.texinfo | 8 ++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b994e07..68aa54f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-04-06 Joel E. Denny + + Fix options documentation. + * build-aux/cross-options.pl: As in --help output, write optional + arguments as [=ARG] not =[ARG]. + * doc/bison.texinfo (Bison Options): Add -W/--warnings argument. + 2008-11-07 Akim Demaille Fix --help. diff --git a/build-aux/cross-options.pl b/build-aux/cross-options.pl index 2cec3696..58772775 100755 --- a/build-aux/cross-options.pl +++ b/build-aux/cross-options.pl @@ -28,9 +28,12 @@ while (<>) # put each word in @var, to build @var{name}[=@var{value}], not # @var{name[=value]}]. $arg =~ s/(\w+)/\@var{$1}/g; - $arg = '[' . $arg . ']' - if $opt eq '['; - $option{"$long=$arg"} = $short ? "$short $arg" : ''; + my $long_arg = "=$arg"; + if ($opt eq '[') { + $long_arg = "[$long_arg]"; + $arg = "[$arg]"; + } + $option{"$long$long_arg"} = $short ? "$short $arg" : ''; } else { diff --git a/doc/bison.texinfo b/doc/bison.texinfo index d4a9cc31..daeb61f8 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -34,8 +34,8 @@ This manual (@value{UPDATED}) is for @acronym{GNU} Bison (version @value{VERSION}), the @acronym{GNU} parser generator. Copyright @copyright{} 1988, 1989, 1990, 1991, 1992, 1993, 1995, 1998, -1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software -Foundation, Inc. +1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free +Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -7783,8 +7783,8 @@ traditional Yacc grammars. If your grammar uses a Bison extension like @samp{%glr-parser}, Bison might not be Yacc-compatible even if this option is specified. -@item -W -@itemx --warnings +@item -W [@var{category}] +@itemx --warnings[=@var{category}] Output warnings falling in @var{category}. @var{category} can be one of: @table @code From 006faedfd3944ade7a33b437d11c0d02c324112c Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Mon, 6 Apr 2009 04:28:29 -0400 Subject: [PATCH 037/404] * NEWS (2.5): New stub. --- ChangeLog | 4 ++++ NEWS | 2 ++ 2 files changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 68aa54f3..21f99a02 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-04-06 Joel E. Denny + + * NEWS (2.5): New stub. + 2009-04-06 Joel E. Denny Fix options documentation. diff --git a/NEWS b/NEWS index 69c6d3b2..2c3238fe 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ Bison News ---------- +* Changes in version 2.5 (????-??-??): + * Changes in version 2.4.2 (????-??-??): * Changes in version 2.4.1 (2008-12-11): From 33d2a860792a7c4e11a99ea9bc10c6802f5a2063 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 7 Aug 2008 20:46:28 +0200 Subject: [PATCH 038/404] Require the generation of parse-gram.output. * src/Makefile.am (YACC): Pass --report=all. (cherry picked from commit 432ac57aaae89de7a4305dc72c5a5b716c6defc4) --- ChangeLog | 5 +++++ src/Makefile.am | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 21f99a02..18236ab7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-11-09 Akim Demaille + + Require the generation of parse-gram.output. + * src/Makefile.am (YACC): Pass --report=all. + 2009-04-06 Joel E. Denny * NEWS (2.5): New stub. diff --git a/src/Makefile.am b/src/Makefile.am index afe6d088..a5cf94ee 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,7 +24,7 @@ LDADD = ../lib/libbison.a $(LIBINTL) # Use our own Bison to build the parser. Of course, you ought to # keep a sane version of Bison nearby... -YACC = ../tests/bison -y --warnings=all,error +YACC = ../tests/bison -y --warnings=all,error --report=all bin_PROGRAMS = bison bin_SCRIPTS = $(YACC_SCRIPT) From 75c21b618d2ee31e72f7b78b4a03d400514e433f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 29 Jul 2008 12:47:41 +0200 Subject: [PATCH 039/404] Initialize the muscle table before parsing the command line. * src/getargs.c (quotearg.h, muscle_tab.h): Include. (getargs): Define file_name. * src/main.c (main): Initialize muscle_tab before calling getargs. * src/muscle_tab.c (muscle_init): No longer define file_name, as its value is not available yet. --- ChangeLog | 10 ++++++++++ src/getargs.c | 3 +++ src/main.c | 5 ++--- src/muscle_tab.c | 5 ++--- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 18236ab7..f6d67157 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-11-07 Akim Demaille + + Initialize the muscle table before parsing the command line. + * src/getargs.c (quotearg.h, muscle_tab.h): Include. + (getargs): Define file_name. + * src/main.c (main): Initialize muscle_tab before calling + getargs. + * src/muscle_tab.c (muscle_init): No longer define file_name, as + its value is not available yet. + 2008-11-09 Akim Demaille Require the generation of parse-gram.output. diff --git a/src/getargs.c b/src/getargs.c index 35594cc8..56cee921 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -26,6 +26,7 @@ #include #include #include +#include /* Hack to get to declare getopt with a prototype. */ #if lint && ! defined __GNU_LIBRARY__ @@ -43,6 +44,7 @@ #include "complain.h" #include "files.h" #include "getargs.h" +#include "muscle_tab.h" #include "uniqstr.h" bool debug_flag; @@ -623,4 +625,5 @@ getargs (int argc, char *argv[]) } current_file = grammar_file = uniqstr_new (argv[optind]); + MUSCLE_INSERT_C_STRING ("file_name", grammar_file); } diff --git a/src/main.c b/src/main.c index 9b472f1e..b3ef70ac 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,7 @@ /* Top level entry point of Bison. Copyright (C) 1984, 1986, 1989, 1992, 1995, 2000, 2001, 2002, 2004, - 2005, 2006, 2007 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -62,6 +62,7 @@ main (int argc, char *argv[]) (void) textdomain (PACKAGE); uniqstrs_new (); + muscle_init (); getargs (argc, argv); @@ -72,8 +73,6 @@ main (int argc, char *argv[]) if (trace_flag & trace_bitsets) bitset_stats_enable (); - muscle_init (); - /* Read the input. Copy some parts of it to FGUARD, FACTION, FTABLE and FATTRS. In file reader.c. The other parts are recorded in the grammar; see gram.h. */ diff --git a/src/muscle_tab.c b/src/muscle_tab.c index 43415716..0265e45a 100644 --- a/src/muscle_tab.c +++ b/src/muscle_tab.c @@ -1,7 +1,7 @@ /* Muscle table manager for Bison. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 Free Software - Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free + Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -85,7 +85,6 @@ muscle_init (void) /* Version and input file. */ MUSCLE_INSERT_STRING ("version", VERSION); - MUSCLE_INSERT_C_STRING ("file_name", grammar_file); } From e14c68313b82fa4b2f2fd8df5937e3945b488b04 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 29 Jul 2008 12:52:19 +0200 Subject: [PATCH 040/404] -D, --define. * src/getargs.c (usage): Document -D. Fix help string for --locations. (command_line_location): New. (short_options, long_options, getargs): Support -D, --define. (getargs): Move -d support at the right place. * doc/bison.texinfo (Bison Options): Update. * tests/input.at (%define, --define): New. (cherry picked from commit 58697c6d89f2db69aa2321fe92fc388f87bf2a3c) --- ChangeLog | 11 +++++++++++ doc/bison.texinfo | 5 +++++ src/getargs.c | 43 +++++++++++++++++++++++++++++++++++++------ tests/input.at | 28 +++++++++++++++++++++++++++- 4 files changed, 80 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index f6d67157..e7fb5418 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-11-07 Akim Demaille + + -D, --define. + * src/getargs.c (usage): Document -D. + Fix help string for --locations. + (command_line_location): New. + (short_options, long_options, getargs): Support -D, --define. + (getargs): Move -d support at the right place. + * doc/bison.texinfo (Bison Options): Update. + * tests/input.at (%define, --define): New. + 2008-11-07 Akim Demaille Initialize the muscle table before parsing the command line. diff --git a/doc/bison.texinfo b/doc/bison.texinfo index daeb61f8..9d9fa3dc 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -7835,6 +7835,11 @@ In the parser file, define the macro @code{YYDEBUG} to 1 if it is not already defined, so that the debugging facilities are compiled. @xref{Tracing, ,Tracing Your Parser}. +@item -D @var{name}[=@var{value}] +@itemx --define=@var{name}[=@var{value}] +Same as running @samp{%define @var{name} "@var{value}"} (@pxref{Decl +Summary, ,%define}). + @item -L @var{language} @itemx --language=@var{language} Specify the programming language for the generated parser, as if diff --git a/src/getargs.c b/src/getargs.c index 56cee921..ae54f81c 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -277,7 +277,8 @@ Parser:\n\ (this is an experimental feature)\n\ -S, --skeleton=FILE specify the skeleton to use\n\ -t, --debug instrument the parser for debugging\n\ - --locations enable locations computation\n\ + --locations enable location support\n\ + -D, --define=NAME[=VALUE] same as `%define NAME \"VALUE\"'\n\ -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\ -l, --no-lines don't generate `#line' directives\n\ -k, --token-table include a table of token names\n\ @@ -413,6 +414,7 @@ language_argmatch (char const *arg, int prio, location const *loc) /* Shorts options. Should be computed from long_options. */ static char const short_options[] = + "D:" "L:" "S:" "T::" @@ -479,6 +481,7 @@ static struct option const long_options[] = /* Parser. */ { "debug", no_argument, 0, 't' }, + { "define", required_argument, 0, 'D' }, { "locations", no_argument, 0, LOCATIONS_OPTION }, { "no-lines", no_argument, 0, 'l' }, { "raw", no_argument, 0, 0 }, @@ -497,6 +500,19 @@ static struct option const long_options[] = # define AS_FILE_NAME(File) (File) #endif +/* Build a location for the current command line argument. */ +static +location +command_line_location() +{ + location res; + /* "" is used in GCC's messages about -D. */ + boundary_set (&res.start, uniqstr_new (""), optind, -1); + res.end = res.start; + return res; +} + + void getargs (int argc, char *argv[]) { @@ -506,15 +522,23 @@ getargs (int argc, char *argv[]) != -1) switch (c) { + /* ASCII Sorting for short options (i.e., upper case then + lower case), and then long-only options. */ + case 0: /* Certain long options cause getopt_long to return 0. */ break; - case 'd': - /* Here, the -d and --defines options are differentiated. */ - defines_flag = true; - if (optarg) - spec_defines_file = xstrdup (AS_FILE_NAME (optarg)); + case 'D': /* -DNAME[=VALUE]. */ + { + char* name = optarg; + char* value = strchr (optarg, '='); + if (value) + *value++ = 0; + else + value = ""; + muscle_percent_define_insert (name, command_line_location (), value); + } break; case 'I': @@ -548,6 +572,13 @@ getargs (int argc, char *argv[]) spec_file_prefix = AS_FILE_NAME (optarg); break; + case 'd': + /* Here, the -d and --defines options are differentiated. */ + defines_flag = true; + if (optarg) + spec_defines_file = xstrdup (AS_FILE_NAME (optarg)); + break; + case 'g': graph_flag = true; if (optarg) diff --git a/tests/input.at b/tests/input.at index 8bf61faa..bb036c38 100644 --- a/tests/input.at +++ b/tests/input.at @@ -1,5 +1,5 @@ # Checking the Bison scanner. -*- Autotest -*- -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, # Inc. # This program is free software: you can redistribute it and/or modify @@ -821,6 +821,32 @@ input.y:5.9-16: warning: %define variable `special2' is not used AT_CLEANUP + +## ------------------- ## +## %define, --define. ## +## ------------------- ## + +AT_SETUP([%define, --define]) + +AT_DATA([input.y], +[[%define var "value1" +%% +start: ; +]]) + +AT_BISON_CHECK([[input.y -DFOO -DFOO -Dvar=value]], [0], [], +[[:4: warning: %define variable `FOO' redefined +:3: warning: previous definition +input.y:1.9-11: warning: %define variable `var' redefined +:5: warning: previous definition +:3: warning: %define variable `FOO' is not used +:4: warning: %define variable `FOO' is not used +:5: warning: %define variable `var' is not used +input.y:1.9-11: warning: %define variable `var' is not used +]]) + +AT_CLEANUP + ## --------------------------- ## ## %define Boolean variables. ## ## --------------------------- ## From e186a284863938a406f562630a3bdc48737a664a Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 29 Jul 2008 13:30:02 +0200 Subject: [PATCH 041/404] Pass command line location to skeleton_arg and language_argmatch. * src/getargs.h, src/getargs.c (skeleton_arg, language_argmatch): The location argument is now mandatory. Adjust all dependencies. (getargs): Use command_line_location. --- ChangeLog | 8 ++++++++ src/getargs.c | 20 ++++++++------------ src/getargs.h | 4 ++-- src/parse-gram.c | 7 +++++-- src/parse-gram.y | 4 ++-- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7fb5418..e7b3f1c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-11-07 Akim Demaille + + Pass command line location to skeleton_arg and language_argmatch. + * src/getargs.h, src/getargs.c (skeleton_arg, language_argmatch): + The location argument is now mandatory. + Adjust all dependencies. + (getargs): Use command_line_location. + 2008-11-07 Akim Demaille -D, --define. diff --git a/src/getargs.c b/src/getargs.c index ae54f81c..a8d1c548 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -361,7 +361,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ `--------------------------------------*/ void -skeleton_arg (char const *arg, int prio, location const *loc) +skeleton_arg (char const *arg, int prio, location loc) { if (prio < skeleton_prio) { @@ -372,15 +372,12 @@ skeleton_arg (char const *arg, int prio, location const *loc) { char const *msg = _("multiple skeleton declarations are invalid"); - if (loc) - complain_at (*loc, msg); - else - complain (msg); + complain_at (loc, msg); } } void -language_argmatch (char const *arg, int prio, location const *loc) +language_argmatch (char const *arg, int prio, location loc) { char const *msg; @@ -401,10 +398,7 @@ language_argmatch (char const *arg, int prio, location const *loc) else return; - if (loc) - complain_at (*loc, msg, arg); - else - complain (msg, arg); + complain_at (loc, msg, arg); } /*----------------------. @@ -546,11 +540,13 @@ getargs (int argc, char *argv[]) break; case 'L': - language_argmatch (optarg, command_line_prio, NULL); + language_argmatch (optarg, command_line_prio, + command_line_location ()); break; case 'S': - skeleton_arg (AS_FILE_NAME (optarg), command_line_prio, NULL); + skeleton_arg (AS_FILE_NAME (optarg), command_line_prio, + command_line_location ()); break; case 'T': diff --git a/src/getargs.h b/src/getargs.h index eb7f448e..8d27e717 100644 --- a/src/getargs.h +++ b/src/getargs.h @@ -135,7 +135,7 @@ extern int warnings_flag; void getargs (int argc, char *argv[]); /* Used by parse-gram.y. */ -void language_argmatch (char const *arg, int prio, location const *loc); -void skeleton_arg (const char *arg, int prio, location const *loc); +void language_argmatch (char const *arg, int prio, location loc); +void skeleton_arg (const char *arg, int prio, location loc); #endif /* !GETARGS_H_ */ diff --git a/src/parse-gram.c b/src/parse-gram.c index b7938dcd..516e4f4b 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -1994,7 +1994,10 @@ yyreduce: /* Line 1455 of yacc.c */ #line 257 "parse-gram.y" - { language_argmatch ((yyvsp[(2) - (2)].chars), grammar_prio, &(yylsp[(1) - (2)])); } + { language_argmatch ((yyvsp[(2) - (2)].chars), grammar_prio, (yylsp[(1) - (2)])); } + +/* Line 1457 of yacc.c */ +#line 2036 "../../../src/parse-gram.c" break; case 19: @@ -2110,7 +2113,7 @@ yyreduce: skeleton_user = uniqstr_new (skeleton_build); free (skeleton_build); } - skeleton_arg (skeleton_user, grammar_prio, &(yylsp[(1) - (2)])); + skeleton_arg (skeleton_user, grammar_prio, (yylsp[(1) - (2)])); } break; diff --git a/src/parse-gram.y b/src/parse-gram.y index a8526b24..83b02e36 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -254,7 +254,7 @@ prologue_declaration: muscle_code_grow ("initial_action", action.code, @2); code_scanner_last_string_free (); } -| "%language" STRING { language_argmatch ($2, grammar_prio, &@1); } +| "%language" STRING { language_argmatch ($2, grammar_prio, @1); } | "%lex-param" "{...}" { add_param ("lex_param", $2, @2); } | "%locations" { locations_flag = true; } | "%name-prefix" STRING { spec_name_prefix = $2; } @@ -300,7 +300,7 @@ prologue_declaration: skeleton_user = uniqstr_new (skeleton_build); free (skeleton_build); } - skeleton_arg (skeleton_user, grammar_prio, &@1); + skeleton_arg (skeleton_user, grammar_prio, @1); } | "%token-table" { token_table_flag = true; } | "%verbose" { report_flag |= report_states; } From 11c4e57daf46a0f465716621d56e780bf7b0c860 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 25 Aug 2008 13:43:00 +0200 Subject: [PATCH 042/404] AT_FULL_COMPILE. * tests/actions.at, tests/regression.at: Use it. --- ChangeLog | 5 +++++ tests/actions.at | 8 ++------ tests/regression.at | 12 ++---------- 3 files changed, 9 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index e7b3f1c3..2c876aa2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-11-11 Akim Demaille + + AT_FULL_COMPILE. + * tests/actions.at, tests/regression.at: Use it. + 2008-11-07 Akim Demaille Pass command line location to skeleton_arg and language_argmatch. diff --git a/tests/actions.at b/tests/actions.at index 602eac8c..afbc94db 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -1,5 +1,5 @@ # Executing Actions. -*- Autotest -*- -# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software # Foundation, Inc. # This program is free software: you can redistribute it and/or modify @@ -367,11 +367,7 @@ main (int argc, const char *argv[]) } ]]) -AT_LALR1_CC_IF( - [AT_BISON_CHECK([-o input.cc input.y]) - AT_COMPILE_CXX([input])], - [AT_BISON_CHECK([-o input.c input.y]) - AT_COMPILE([input])]) +AT_FULL_COMPILE([input]) # Check the location of "empty" diff --git a/tests/regression.at b/tests/regression.at index 6bfc8d09..fa2278a8 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -939,11 +939,7 @@ m4_define([AT_CHECK_DANCER], AT_BISON_OPTION_PUSHDEFS([$1]) _AT_DATA_DANCER_Y([$1]) AT_BISON_CHECK([-o dancer.c dancer.y]) -AT_LALR1_CC_IF( - [AT_BISON_CHECK([-o dancer.cc dancer.y]) - AT_COMPILE_CXX([dancer])], - [AT_BISON_CHECK([-o dancer.c dancer.y]) - AT_COMPILE([dancer])]) +AT_FULL_COMPILE([dancer]) AT_PARSER_CHECK([./dancer], 1, [], [syntax error, unexpected ':' ]) @@ -1039,11 +1035,7 @@ m4_define([AT_CHECK_EXPECT2], AT_BISON_OPTION_PUSHDEFS([$1]) _AT_DATA_EXPECT2_Y([$1]) AT_BISON_CHECK([-o expect2.c expect2.y]) -AT_LALR1_CC_IF( - [AT_BISON_CHECK([-o expect2.cc expect2.y]) - AT_COMPILE_CXX([expect2])], - [AT_BISON_CHECK([-o expect2.c expect2.y]) - AT_COMPILE([expect2])]) +AT_FULL_COMPILE([expect2]) AT_PARSER_CHECK([./expect2], 1, [], [syntax error, unexpected '+', expecting A or B ]) From 6f5be1abf7a9b83edfe86ca81b31e786bcc710c8 Mon Sep 17 00:00:00 2001 From: Di-an Jan Date: Mon, 17 Nov 2008 11:01:41 +0100 Subject: [PATCH 043/404] Handle --enable-gcc-warnings. * src/getargs.c (command_line_location): Set parameters to void. --- ChangeLog | 5 +++++ src/getargs.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 2c876aa2..e4c83d24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-11-17 Di-an Jan + + Handle --enable-gcc-warnings. + * src/getargs.c (command_line_location): Set parameters to void. + 2008-11-11 Akim Demaille AT_FULL_COMPILE. diff --git a/src/getargs.c b/src/getargs.c index a8d1c548..45557733 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -497,7 +497,7 @@ static struct option const long_options[] = /* Build a location for the current command line argument. */ static location -command_line_location() +command_line_location (void) { location res; /* "" is used in GCC's messages about -D. */ From 10fa0146e2051fbd536fb69acd9634fea4b4fbde Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Mon, 17 Nov 2008 10:36:28 -0500 Subject: [PATCH 044/404] Fix last warning from --enable-gcc-warnings. * src/getargs.c (getargs): Don't assign const address to non-const pointer. (cherry picked from commit a8beef7e6a9f6b75fa249d59b4c79585190540b6) --- ChangeLog | 6 ++++++ src/getargs.c | 11 +++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index e4c83d24..dcfd0a5a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-11-17 Joel E. Denny + + Fix last warning from --enable-gcc-warnings. + * src/getargs.c (getargs): Don't assign const address to non-const + pointer. + 2008-11-17 Di-an Jan Handle --enable-gcc-warnings. diff --git a/src/getargs.c b/src/getargs.c index 45557733..fddc023b 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -527,11 +527,14 @@ getargs (int argc, char *argv[]) { char* name = optarg; char* value = strchr (optarg, '='); + char const * muscle_value = ""; if (value) - *value++ = 0; - else - value = ""; - muscle_percent_define_insert (name, command_line_location (), value); + { + *value++ = 0; + muscle_value = value; + } + muscle_percent_define_insert (name, command_line_location (), + muscle_value); } break; From c4eb1e841e579e79e861007994e3902bb6cf5fb2 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Mon, 17 Nov 2008 10:51:17 -0500 Subject: [PATCH 045/404] Simplify last patch slightly. * src/getargs.c (getargs): Here. (cherry picked from commit 9ce405ce1dd2ff7d495dafe6201b87669549f98b) --- ChangeLog | 5 +++++ src/getargs.c | 8 ++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index dcfd0a5a..14e2674c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2008-11-17 Joel E. Denny + + Simplify last patch slightly. + * src/getargs.c (getargs): Here. + 2008-11-17 Joel E. Denny Fix last warning from --enable-gcc-warnings. diff --git a/src/getargs.c b/src/getargs.c index fddc023b..5601e981 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -527,14 +527,10 @@ getargs (int argc, char *argv[]) { char* name = optarg; char* value = strchr (optarg, '='); - char const * muscle_value = ""; if (value) - { - *value++ = 0; - muscle_value = value; - } + *value++ = 0; muscle_percent_define_insert (name, command_line_location (), - muscle_value); + value ? value : ""); } break; From e3ee30b88ff74bd7ea699e6b9a162a42d6cbd0df Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 7 Dec 2008 22:14:11 +0100 Subject: [PATCH 046/404] Install autoconf as a submodule to get m4sugar. * .gitmodules: Add submodules/autoconf. * data/m4sugar/foreach.m4, data/m4sugar/m4sugar.m4: Now links into submodules/autoconf. (cherry picked from commit 6c63b895fbfda2182e148a95aff855e303bdbc30) --- .gitmodules | 3 + ChangeLog | 7 + data/m4sugar/foreach.m4 | 401 +----- data/m4sugar/m4sugar.m4 | 2790 +-------------------------------------- 4 files changed, 12 insertions(+), 3189 deletions(-) mode change 100644 => 120000 data/m4sugar/foreach.m4 mode change 100644 => 120000 data/m4sugar/m4sugar.m4 diff --git a/.gitmodules b/.gitmodules index 009ae439..b50d66ee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "gnulib"] path = gnulib url = git://git.savannah.gnu.org/gnulib.git +[submodule "submodules/autoconf"] + path = submodules/autoconf + url = git://git.sv.gnu.org/autoconf.git diff --git a/ChangeLog b/ChangeLog index 14e2674c..929d5e4b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-12-08 Akim Demaille + + Install autoconf as a submodule to get m4sugar. + * .gitmodules: Add submodules/autoconf. + * data/m4sugar/foreach.m4, data/m4sugar/m4sugar.m4: Now links into + submodules/autoconf. + 2008-11-17 Joel E. Denny Simplify last patch slightly. diff --git a/data/m4sugar/foreach.m4 b/data/m4sugar/foreach.m4 deleted file mode 100644 index cd4d1fc8..00000000 --- a/data/m4sugar/foreach.m4 +++ /dev/null @@ -1,400 +0,0 @@ -# -*- Autoconf -*- -# This file is part of Autoconf. -# foreach-based replacements for recursive functions. -# Speeds up GNU M4 1.4.x by avoiding quadratic $@ recursion, but penalizes -# GNU M4 1.6 by requiring more memory and macro expansions. -# -# Copyright (C) 2008 Free Software Foundation, Inc. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception, the Free Software Foundation gives unlimited -# permission to copy, distribute and modify the configure scripts that -# are the output of Autoconf. You need not follow the terms of the GNU -# General Public License when using or distributing such scripts, even -# though portions of the text of Autoconf appear in them. The GNU -# General Public License (GPL) does govern all other use of the material -# that constitutes the Autoconf program. -# -# Certain portions of the Autoconf source text are designed to be copied -# (in certain cases, depending on the input) into the output of -# Autoconf. We call these the "data" portions. The rest of the Autoconf -# source text consists of comments plus executable code that decides which -# of the data portions to output in any given case. We call these -# comments and executable code the "non-data" portions. Autoconf never -# copies any of the non-data portions into its output. -# -# This special exception to the GPL applies to versions of Autoconf -# released by the Free Software Foundation. When you make and -# distribute a modified version of Autoconf, you may extend this special -# exception to the GPL to apply to your modified version as well, *unless* -# your modified version has the potential to copy into its output some -# of the text that was the non-data portion of the version that you started -# with. (In other words, unless your change moves or copies text from -# the non-data portions to the data portions.) If your modification has -# such potential, you must delete any notice of this special exception -# to the GPL from your modified version. -# -# Written by Eric Blake. -# - -# In M4 1.4.x, every byte of $@ is rescanned. This means that an -# algorithm on n arguments that recurses with one less argument each -# iteration will scan n * (n + 1) / 2 arguments, for O(n^2) time. In -# M4 1.6, this was fixed so that $@ is only scanned once, then -# back-references are made to information stored about the scan. -# Thus, n iterations need only scan n arguments, for O(n) time. -# Additionally, in M4 1.4.x, recursive algorithms did not clean up -# memory very well, requiring O(n^2) memory rather than O(n) for n -# iterations. -# -# This file is designed to overcome the quadratic nature of $@ -# recursion by writing a variant of m4_foreach that uses m4_for rather -# than $@ recursion to operate on the list. This involves more macro -# expansions, but avoids the need to rescan a quadratic number of -# arguments, making these replacements very attractive for M4 1.4.x. -# On the other hand, in any version of M4, expanding additional macros -# costs additional time; therefore, in M4 1.6, where $@ recursion uses -# fewer macros, these replacements actually pessimize performance. -# Additionally, the use of $10 to mean the tenth argument violates -# POSIX; although all versions of m4 1.4.x support this meaning, a -# future m4 version may switch to take it as the first argument -# concatenated with a literal 0, so the implementations in this file -# are not future-proof. Thus, this file is conditionally included as -# part of m4_init(), only when it is detected that M4 probably has -# quadratic behavior (ie. it lacks the macro __m4_version__). -# -# Please keep this file in sync with m4sugar.m4. - -# m4_foreach(VARIABLE, LIST, EXPRESSION) -# -------------------------------------- -# Expand EXPRESSION assigning each value of the LIST to VARIABLE. -# LIST should have the form `item_1, item_2, ..., item_n', i.e. the -# whole list must *quoted*. Quote members too if you don't want them -# to be expanded. -# -# This version minimizes the number of times that $@ is evaluated by -# using m4_for to generate a boilerplate into VARIABLE then passing $@ -# to that temporary macro. Thus, the recursion is done in m4_for -# without reparsing any user input, and is not quadratic. For an idea -# of how this works, note that m4_foreach(i,[1,2],[i]) defines i to be -# m4_define([$1],[$3])$2[]m4_define([$1],[$4])$2[]m4_popdef([i]) -# then calls i([i],[i],[1],[2]). -m4_define([m4_foreach], -[m4_if([$2], [], [], [_$0([$1], [$3], $2)])]) - -m4_define([_m4_foreach], -[m4_define([$1], m4_pushdef([$1])_m4_for([$1], [3], [$#], [1], - [$0_([1], [2], _m4_defn([$1]))])[m4_popdef([$1])])m4_indir([$1], $@)]) - -m4_define([_m4_foreach_], -[[m4_define([$$1], [$$3])$$2[]]]) - -# m4_case(SWITCH, VAL1, IF-VAL1, VAL2, IF-VAL2, ..., DEFAULT) -# ----------------------------------------------------------- -# Find the first VAL that SWITCH matches, and expand the corresponding -# IF-VAL. If there are no matches, expand DEFAULT. -# -# Use m4_for to create a temporary macro in terms of a boilerplate -# m4_if with final cleanup. If $# is even, we have DEFAULT; if it is -# odd, then rounding the last $# up in the temporary macro is -# harmless. For example, both m4_case(1,2,3,4,5) and -# m4_case(1,2,3,4,5,6) result in the intermediate _m4_case being -# m4_if([$1],[$2],[$3],[$1],[$4],[$5],_m4_popdef([_m4_case])[$6]) -m4_define([m4_case], -[m4_if(m4_eval([$# <= 2]), [1], [$2], -[m4_pushdef([_$0], [m4_if(]m4_for([_m4_count], [2], m4_decr([$#]), [2], - [_$0_([1], _m4_count, m4_incr(_m4_count))])[_m4_popdef( - [_$0])]m4_dquote($m4_eval([($# + 1) & ~1]))[)])_$0($@)])]) - -m4_define([_m4_case_], -[[[$$1],[$$2],[$$3],]]) - -# m4_bmatch(SWITCH, RE1, VAL1, RE2, VAL2, ..., DEFAULT) -# ----------------------------------------------------- -# m4 equivalent of -# -# if (SWITCH =~ RE1) -# VAL1; -# elif (SWITCH =~ RE2) -# VAL2; -# elif ... -# ... -# else -# DEFAULT -# -# We build the temporary macro _m4_b: -# m4_define([_m4_b], _m4_defn([_m4_bmatch]))_m4_b([$1], [$2], [$3])... -# _m4_b([$1], [$m-1], [$m])_m4_b([], [], [$m+1]_m4_popdef([_m4_b])) -# then invoke m4_unquote(_m4_b($@)), for concatenation with later text. -m4_define([m4_bmatch], -[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])], - [$#], 1, [m4_fatal([$0: too few arguments: $#: $1])], - [$#], 2, [$2], - [m4_define([_m4_b], m4_pushdef([_m4_b])[m4_define([_m4_b], - _m4_defn([_$0]))]_m4_for([_m4_b], [3], m4_eval([($# + 1) / 2 * 2 - 1]), - [2], [_$0_([1], m4_decr(_m4_b), _m4_b)])[_m4_b([], [],]m4_dquote( - [$]m4_incr(_m4_b))[_m4_popdef([_m4_b]))])m4_unquote(_m4_b($@))])]) - -m4_define([_m4_bmatch], -[m4_if(m4_bregexp([$1], [$2]), [-1], [], [[$3]m4_define([$0])])]) - -m4_define([_m4_bmatch_], -[[_m4_b([$$1], [$$2], [$$3])]]) - - -# m4_cond(TEST1, VAL1, IF-VAL1, TEST2, VAL2, IF-VAL2, ..., [DEFAULT]) -# ------------------------------------------------------------------- -# Similar to m4_if, except that each TEST is expanded when encountered. -# If the expansion of TESTn matches the string VALn, the result is IF-VALn. -# The result is DEFAULT if no tests passed. This macro allows -# short-circuiting of expensive tests, where it pays to arrange quick -# filter tests to run first. -# -# m4_cond already guarantees either 3*n or 3*n + 1 arguments, 1 <= n. -# We only have to speed up _m4_cond, by building the temporary _m4_c: -# m4_define([_m4_c], _m4_defn([m4_unquote]))_m4_c([m4_if(($1), [($2)], -# [[$3]m4_define([_m4_c])])])_m4_c([m4_if(($4), [($5)], -# [[$6]m4_define([_m4_c])])])..._m4_c([m4_if(($m-2), [($m-1)], -# [[$m]m4_define([_m4_c])])])_m4_c([[$m+1]]_m4_popdef([_m4_c])) -# We invoke m4_unquote(_m4_c($@)), for concatenation with later text. -m4_define([_m4_cond], -[m4_define([_m4_c], m4_pushdef([_m4_c])[m4_define([_m4_c], - _m4_defn([m4_unquote]))]_m4_for([_m4_c], [2], m4_eval([$# / 3 * 3 - 1]), [3], - [$0_(m4_decr(_m4_c), _m4_c, m4_incr(_m4_c))])[_m4_c(]m4_dquote(m4_dquote( - [$]m4_eval([$# / 3 * 3 + 1])))[_m4_popdef([_m4_c]))])m4_unquote(_m4_c($@))]) - -m4_define([_m4_cond_], -[[_m4_c([m4_if(($$1), [($$2)], [[$$3]m4_define([_m4_c])])])]]) - -# m4_bpatsubsts(STRING, RE1, SUBST1, RE2, SUBST2, ...) -# ---------------------------------------------------- -# m4 equivalent of -# -# $_ = STRING; -# s/RE1/SUBST1/g; -# s/RE2/SUBST2/g; -# ... -# -# m4_bpatsubsts already validated an odd number of arguments; we only -# need to speed up _m4_bpatsubsts. To avoid nesting, we build the -# temporary _m4_p: -# m4_define([_m4_p], [$1])m4_define([_m4_p], -# m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$2], [$3]))m4_define([_m4_p], -# m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$4], [$5]))m4_define([_m4_p],... -# m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$m-1], [$m]))m4_unquote( -# _m4_defn([_m4_p])_m4_popdef([_m4_p])) -m4_define([_m4_bpatsubsts], -[m4_define([_m4_p], m4_pushdef([_m4_p])[m4_define([_m4_p], - ]m4_dquote([$]1)[)]_m4_for([_m4_p], [3], [$#], [2], [$0_(m4_decr(_m4_p), - _m4_p)])[m4_unquote(_m4_defn([_m4_p])_m4_popdef([_m4_p]))])_m4_p($@)]) - -m4_define([_m4_bpatsubsts_], -[[m4_define([_m4_p], -m4_bpatsubst(m4_dquote(_m4_defn([_m4_p])), [$$1], [$$2]))]]) - -# m4_shiftn(N, ...) -# ----------------- -# Returns ... shifted N times. Useful for recursive "varargs" constructs. -# -# m4_shiftn already validated arguments; we only need to speed up -# _m4_shiftn. If N is 3, then we build the temporary _m4_s, defined as -# ,[$5],[$6],...,[$m]_m4_popdef([_m4_s]) -# before calling m4_shift(_m4_s($@)). -m4_define([_m4_shiftn], -[m4_if(m4_incr([$1]), [$#], [], [m4_define([_m4_s], - m4_pushdef([_m4_s])_m4_for([_m4_s], m4_eval([$1 + 2]), [$#], [1], - [[,]m4_dquote([$]_m4_s)])[_m4_popdef([_m4_s])])m4_shift(_m4_s($@))])]) - -# m4_do(STRING, ...) -# ------------------ -# This macro invokes all its arguments (in sequence, of course). It is -# useful for making your macros more structured and readable by dropping -# unnecessary dnl's and have the macros indented properly. -# -# Here, we use the temporary macro _m4_do, defined as -# $1[]$2[]...[]$n[]_m4_popdef([_m4_do]) -m4_define([m4_do], -[m4_if([$#], [0], [], - [m4_define([_$0], m4_pushdef([_$0])_m4_for([_$0], [1], [$#], [1], - [$_$0[[]]])[_m4_popdef([_$0])])_$0($@)])]) - -# m4_dquote_elt(ARGS) -# ------------------- -# Return ARGS as an unquoted list of double-quoted arguments. -# -# m4_foreach to the rescue. It's easier to shift off the leading comma. -m4_define([m4_dquote_elt], -[m4_shift(m4_foreach([_m4_elt], [$@], [,m4_dquote(_m4_defn([_m4_elt]))]))]) - -# m4_reverse(ARGS) -# ---------------- -# Output ARGS in reverse order. -# -# Invoke _m4_r($@) with the temporary _m4_r built as -# [$m], [$m-1], ..., [$2], [$1]_m4_popdef([_m4_r]) -m4_define([m4_reverse], -[m4_if([$#], [0], [], [$#], [1], [[$1]], -[m4_define([_m4_r], m4_dquote([$$#])m4_pushdef([_m4_r])_m4_for([_m4_r], - m4_decr([$#]), [1], [-1], - [[, ]m4_dquote([$]_m4_r)])[_m4_popdef([_m4_r])])_m4_r($@)])]) - - -# m4_map(MACRO, LIST) -# ------------------- -# Invoke MACRO($1), MACRO($2) etc. where $1, $2... are the elements -# of LIST. $1, $2... must in turn be lists, appropriate for m4_apply. -# -# m4_map/m4_map_sep only execute once; the speedup comes in fixing -# _m4_map. The mismatch in () is intentional, since $1 supplies the -# opening `(' (but it sure looks odd!). Build the temporary _m4_m: -# $1, [$3])$1, [$4])...$1, [$m])_m4_popdef([_m4_m]) -m4_define([_m4_map], -[m4_if([$#], [2], [], - [m4_define([_m4_m], m4_pushdef([_m4_m])_m4_for([_m4_m], [3], [$#], [1], - [$0_([1], _m4_m)])[_m4_popdef([_m4_m])])_m4_m($@)])]) - -m4_define([_m4_map_], -[[$$1, [$$2])]]) - -# m4_transform(EXPRESSION, ARG...) -# -------------------------------- -# Expand EXPRESSION([ARG]) for each argument. More efficient than -# m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))]) -# -# Invoke the temporary macro _m4_transform, defined as: -# $1([$2])[]$1([$3])[]...$1([$m])[]_m4_popdef([_m4_transform]) -m4_define([m4_transform], -[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], - [$#], [1], [], - [m4_define([_$0], m4_pushdef([_$0])_m4_for([_$0], [2], [$#], [1], - [_$0_([1], _$0)])[_m4_popdef([_$0])])_$0($@)])]) - -m4_define([_m4_transform_], -[[$$1([$$2])[]]]) - -# m4_transform_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...) -# -------------------------------------------------------------- -# Perform a pairwise grouping of consecutive ARGs, by expanding -# EXPRESSION([ARG1], [ARG2]). If there are an odd number of ARGs, the -# final argument is expanded with END-EXPR([ARGn]). -# -# Build the temporary macro _m4_transform_pair, with the $2([$m+1]) -# only output if $# is odd: -# $1([$3], [$4])[]$1([$5], [$6])[]...$1([$m-1], -# [$m])[]m4_default([$2], [$1])([$m+1])[]_m4_popdef([_m4_transform_pair]) -m4_define([m4_transform_pair], -[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], - [$#], [1], [m4_fatal([$0: too few arguments: $#: $1])], - [$#], [2], [], - [$#], [3], [m4_default([$2], [$1])([$3])[]], - [m4_define([_$0], m4_pushdef([_$0])_m4_for([_$0], [3], - m4_eval([$# / 2 * 2 - 1]), [2], [_$0_([1], _$0, m4_incr(_$0))])_$0_end( - [1], [2], [$#])[_m4_popdef([_$0])])_$0($@)])]) - -m4_define([_m4_transform_pair_], -[[$$1([$$2], [$$3])[]]]) - -m4_define([_m4_transform_pair_end], -[m4_if(m4_eval([$3 & 1]), [1], [[m4_default([$$2], [$$1])([$$3])[]]])]) - -# m4_join(SEP, ARG1, ARG2...) -# --------------------------- -# Produce ARG1SEPARG2...SEPARGn. Avoid back-to-back SEP when a given ARG -# is the empty string. No expansion is performed on SEP or ARGs. -# -# Use a self-modifying separator, since we don't know how many -# arguments might be skipped before a separator is first printed, but -# be careful if the separator contains $. m4_foreach to the rescue. -m4_define([m4_join], -[m4_pushdef([_m4_sep], [m4_define([_m4_sep], _m4_defn([m4_echo]))])]dnl -[m4_foreach([_m4_arg], [m4_shift($@)], - [m4_ifset([_m4_arg], [_m4_sep([$1])_m4_defn([_m4_arg])])])]dnl -[_m4_popdef([_m4_sep])]) - -# m4_joinall(SEP, ARG1, ARG2...) -# ------------------------------ -# Produce ARG1SEPARG2...SEPARGn. An empty ARG results in back-to-back SEP. -# No expansion is performed on SEP or ARGs. -# -# A bit easier than m4_join. m4_foreach to the rescue. -m4_define([m4_joinall], -[[$2]m4_if(m4_eval([$# <= 2]), [1], [], - [m4_foreach([_m4_arg], [m4_shift2($@)], - [[$1]_m4_defn([_m4_arg])])])]) - -# m4_list_cmp(A, B) -# ----------------- -# Compare the two lists of integer expressions A and B. -# -# m4_list_cmp takes care of any side effects; we only override -# _m4_list_cmp_raw, where we can safely expand lists multiple times. -# First, insert padding so that both lists are the same length; the -# trailing +0 is necessary to handle a missing list. Next, create a -# temporary macro to perform pairwise comparisons until an inequality -# is found. For example, m4_list_cmp([1], [1,2]) creates _m4_cmp as -# m4_if(m4_eval([($1) != ($3)]), [1], [m4_cmp([$1], [$3])], -# m4_eval([($2) != ($4)]), [1], [m4_cmp([$2], [$4])], -# [0]_m4_popdef([_m4_cmp], [_m4_size])) -# then calls _m4_cmp([1+0], [0], [1], [2+0]) -m4_define([_m4_list_cmp_raw], -[m4_if([$1], [$2], 0, [m4_pushdef( - [_m4_size])_m4_list_cmp($1+0_m4_list_pad(m4_count($1), m4_count($2)), - $2+0_m4_list_pad(m4_count($2), m4_count($1)))])]) - -m4_define([_m4_list_pad], -[m4_if(m4_eval($1 < $2), [1], - [_m4_for([_m4_size], m4_incr([$1]), [$2], [1], [,0])])]) - -m4_define([_m4_list_cmp], -[m4_define([_m4_size], m4_eval([$# >> 1]))]dnl -[m4_define([_m4_cmp], m4_pushdef([_m4_cmp])[m4_if(]_m4_for([_m4_cmp], - [1], _m4_size, [1], [$0_(_m4_cmp, m4_eval(_m4_cmp + _m4_size))])[ - [0]_m4_popdef([_m4_cmp], [_m4_size]))])_m4_cmp($@)]) - -m4_define([_m4_list_cmp_], -[[m4_eval([($$1) != ($$2)]), [1], [m4_cmp([$$1], [$$2])], -]]) - -# m4_max(EXPR, ...) -# m4_min(EXPR, ...) -# ----------------- -# Return the decimal value of the maximum (or minimum) in a series of -# integer expressions. -# -# m4_foreach to the rescue; we only need to replace _m4_minmax. Here, -# we need a temporary macro to track the best answer so far, so that -# the foreach expression is tractable. -m4_define([_m4_minmax], -[m4_pushdef([_m4_best], m4_eval([$2]))m4_foreach([_m4_arg], [m4_shift2($@)], - [m4_define([_m4_best], $1(_m4_best, _m4_defn([_m4_arg])))])]dnl -[_m4_best[]_m4_popdef([_m4_best])]) - -# m4_set_add_all(SET, VALUE...) -# ----------------------------- -# Add each VALUE into SET. This is O(n) in the number of VALUEs, and -# can be faster than calling m4_set_add for each VALUE. -# -# m4_foreach to the rescue. If no deletions have occurred, then avoid -# the speed penalty of m4_set_add. -m4_define([m4_set_add_all], -[m4_if([$#], [0], [], [$#], [1], [], - [m4_define([_m4_set_size($1)], m4_eval(m4_set_size([$1]) - + m4_len(m4_foreach([_m4_arg], [m4_shift($@)], - m4_ifdef([_m4_set_cleanup($1)], - [[m4_set_add([$1], _m4_defn([_m4_arg]))]], - [[m4_ifdef([_m4_set([$1],]_m4_defn([_m4_arg])[)], [], - [m4_define([_m4_set([$1],]_m4_defn([_m4_arg])[)], - [1])m4_pushdef([_m4_set([$1])], - _m4_defn([_m4_arg]))-])]])))))])]) diff --git a/data/m4sugar/foreach.m4 b/data/m4sugar/foreach.m4 new file mode 120000 index 00000000..ac0583a6 --- /dev/null +++ b/data/m4sugar/foreach.m4 @@ -0,0 +1 @@ +../../submodules/autoconf/lib/m4sugar/foreach.m4 \ No newline at end of file diff --git a/data/m4sugar/m4sugar.m4 b/data/m4sugar/m4sugar.m4 deleted file mode 100644 index 6fbd3431..00000000 --- a/data/m4sugar/m4sugar.m4 +++ /dev/null @@ -1,2789 +0,0 @@ -divert(-1)# -*- Autoconf -*- -# This file is part of Autoconf. -# Base M4 layer. -# Requires GNU M4. -# -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, -# 2008 Free Software Foundation, Inc. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# As a special exception, the Free Software Foundation gives unlimited -# permission to copy, distribute and modify the configure scripts that -# are the output of Autoconf. You need not follow the terms of the GNU -# General Public License when using or distributing such scripts, even -# though portions of the text of Autoconf appear in them. The GNU -# General Public License (GPL) does govern all other use of the material -# that constitutes the Autoconf program. -# -# Certain portions of the Autoconf source text are designed to be copied -# (in certain cases, depending on the input) into the output of -# Autoconf. We call these the "data" portions. The rest of the Autoconf -# source text consists of comments plus executable code that decides which -# of the data portions to output in any given case. We call these -# comments and executable code the "non-data" portions. Autoconf never -# copies any of the non-data portions into its output. -# -# This special exception to the GPL applies to versions of Autoconf -# released by the Free Software Foundation. When you make and -# distribute a modified version of Autoconf, you may extend this special -# exception to the GPL to apply to your modified version as well, *unless* -# your modified version has the potential to copy into its output some -# of the text that was the non-data portion of the version that you started -# with. (In other words, unless your change moves or copies text from -# the non-data portions to the data portions.) If your modification has -# such potential, you must delete any notice of this special exception -# to the GPL from your modified version. -# -# Written by Akim Demaille. -# - -# Set the quotes, whatever the current quoting system. -changequote() -changequote([, ]) - -# Some old m4's don't support m4exit. But they provide -# equivalent functionality by core dumping because of the -# long macros we define. -ifdef([__gnu__], , -[errprint(M4sugar requires GNU M4. Install it before installing M4sugar or -set the M4 environment variable to its absolute file name.) -m4exit(2)]) - - -## ------------------------------- ## -## 1. Simulate --prefix-builtins. ## -## ------------------------------- ## - -# m4_define -# m4_defn -# m4_undefine -define([m4_define], defn([define])) -define([m4_defn], defn([defn])) -define([m4_undefine], defn([undefine])) - -m4_undefine([define]) -m4_undefine([defn]) -m4_undefine([undefine]) - - -# m4_copy(SRC, DST) -# ----------------- -# Define DST as the definition of SRC. -# What's the difference between: -# 1. m4_copy([from], [to]) -# 2. m4_define([to], [from($@)]) -# Well, obviously 1 is more expensive in space. Maybe 2 is more expensive -# in time, but because of the space cost of 1, it's not that obvious. -# Nevertheless, one huge difference is the handling of `$0'. If `from' -# uses `$0', then with 1, `to''s `$0' is `to', while it is `from' in 2. -# The user would certainly prefer to see `to'. -m4_define([m4_copy], -[m4_define([$2], m4_defn([$1]))]) - - -# m4_rename(SRC, DST) -# ------------------- -# Rename the macro SRC to DST. -m4_define([m4_rename], -[m4_copy([$1], [$2])m4_undefine([$1])]) - - -# m4_rename_m4(MACRO-NAME) -# ------------------------ -# Rename MACRO-NAME to m4_MACRO-NAME. -m4_define([m4_rename_m4], -[m4_rename([$1], [m4_$1])]) - - -# m4_copy_unm4(m4_MACRO-NAME) -# --------------------------- -# Copy m4_MACRO-NAME to MACRO-NAME. -m4_define([m4_copy_unm4], -[m4_copy([$1], m4_bpatsubst([$1], [^m4_\(.*\)], [[\1]]))]) - - -# Some m4 internals have names colliding with tokens we might use. -# Rename them a` la `m4 --prefix-builtins'. Conditionals first, since -# some subsequent renames are conditional. -m4_rename_m4([ifdef]) -m4_rename([ifelse], [m4_if]) - -m4_rename_m4([builtin]) -m4_rename_m4([changecom]) -m4_rename_m4([changequote]) -m4_ifdef([changeword],dnl conditionally available in 1.4.x -[m4_undefine([changeword])]) -m4_rename_m4([debugfile]) -m4_rename_m4([debugmode]) -m4_rename_m4([decr]) -m4_undefine([divert]) -m4_rename_m4([divnum]) -m4_rename_m4([dumpdef]) -m4_rename_m4([errprint]) -m4_rename_m4([esyscmd]) -m4_rename_m4([eval]) -m4_rename_m4([format]) -m4_undefine([include]) -m4_rename_m4([incr]) -m4_rename_m4([index]) -m4_rename_m4([indir]) -m4_rename_m4([len]) -m4_rename([m4exit], [m4_exit]) -m4_undefine([m4wrap]) -m4_ifdef([mkstemp],dnl added in M4 1.4.8 -[m4_rename_m4([mkstemp]) -m4_copy([m4_mkstemp], [m4_maketemp]) -m4_undefine([maketemp])], -[m4_rename_m4([maketemp]) -m4_copy([m4_maketemp], [m4_mkstemp])]) -m4_rename([patsubst], [m4_bpatsubst]) -m4_rename_m4([popdef]) -m4_rename_m4([pushdef]) -m4_rename([regexp], [m4_bregexp]) -m4_rename_m4([shift]) -m4_undefine([sinclude]) -m4_rename_m4([substr]) -m4_ifdef([symbols],dnl present only in alpha-quality 1.4o -[m4_rename_m4([symbols])]) -m4_rename_m4([syscmd]) -m4_rename_m4([sysval]) -m4_rename_m4([traceoff]) -m4_rename_m4([traceon]) -m4_rename_m4([translit]) -m4_undefine([undivert]) - - -## ------------------- ## -## 2. Error messages. ## -## ------------------- ## - - -# m4_location -# ----------- -m4_define([m4_location], -[__file__:__line__]) - - -# m4_errprintn(MSG) -# ----------------- -# Same as `errprint', but with the missing end of line. -m4_define([m4_errprintn], -[m4_errprint([$1 -])]) - - -# m4_warning(MSG) -# --------------- -# Warn the user. -m4_define([m4_warning], -[m4_errprintn(m4_location[: warning: $1])]) - - -# m4_fatal(MSG, [EXIT-STATUS]) -# ---------------------------- -# Fatal the user. :) -m4_define([m4_fatal], -[m4_errprintn(m4_location[: error: $1])dnl -m4_expansion_stack_dump()dnl -m4_exit(m4_if([$2],, 1, [$2]))]) - - -# m4_assert(EXPRESSION, [EXIT-STATUS = 1]) -# ---------------------------------------- -# This macro ensures that EXPRESSION evaluates to true, and exits if -# EXPRESSION evaluates to false. -m4_define([m4_assert], -[m4_if(m4_eval([$1]), 0, - [m4_fatal([assert failed: $1], [$2])])]) - - - -## ------------- ## -## 3. Warnings. ## -## ------------- ## - - -# _m4_warn(CATEGORY, MESSAGE, STACK-TRACE) -# ---------------------------------------- -# Report a MESSAGE to the user if the CATEGORY of warnings is enabled. -# This is for traces only. -# The STACK-TRACE is a \n-separated list of "LOCATION: MESSAGE". -# -# Within m4, the macro is a no-op. This macro really matters -# when autom4te post-processes the trace output. -m4_define([_m4_warn], []) - - -# m4_warn(CATEGORY, MESSAGE) -# -------------------------- -# Report a MESSAGE to the user if the CATEGORY of warnings is enabled. -m4_define([m4_warn], -[_m4_warn([$1], [$2], -m4_ifdef([m4_expansion_stack], - [_m4_defn([m4_expansion_stack]) -m4_location[: the top level]]))dnl -]) - - - -## ------------------- ## -## 4. File inclusion. ## -## ------------------- ## - - -# We also want to neutralize include (and sinclude for symmetry), -# but we want to extend them slightly: warn when a file is included -# several times. This is, in general, a dangerous operation, because -# too many people forget to quote the first argument of m4_define. -# -# For instance in the following case: -# m4_define(foo, [bar]) -# then a second reading will turn into -# m4_define(bar, [bar]) -# which is certainly not what was meant. - -# m4_include_unique(FILE) -# ----------------------- -# Declare that the FILE was loading; and warn if it has already -# been included. -m4_define([m4_include_unique], -[m4_ifdef([m4_include($1)], - [m4_warn([syntax], [file `$1' included several times])])dnl -m4_define([m4_include($1)])]) - - -# m4_include(FILE) -# ---------------- -# Like the builtin include, but warns against multiple inclusions. -m4_define([m4_include], -[m4_include_unique([$1])dnl -m4_builtin([include], [$1])]) - - -# m4_sinclude(FILE) -# ----------------- -# Like the builtin sinclude, but warns against multiple inclusions. -m4_define([m4_sinclude], -[m4_include_unique([$1])dnl -m4_builtin([sinclude], [$1])]) - - - -## ------------------------------------ ## -## 5. Additional branching constructs. ## -## ------------------------------------ ## - -# Both `m4_ifval' and `m4_ifset' tests against the empty string. The -# difference is that `m4_ifset' is specialized on macros. -# -# In case of arguments of macros, eg. $1, it makes little difference. -# In the case of a macro `FOO', you don't want to check `m4_ifval(FOO, -# TRUE)', because if `FOO' expands with commas, there is a shifting of -# the arguments. So you want to run `m4_ifval([FOO])', but then you just -# compare the *string* `FOO' against `', which, of course fails. -# -# So you want the variation `m4_ifset' that expects a macro name as $1. -# If this macro is both defined and defined to a non empty value, then -# it runs TRUE, etc. - - -# m4_ifval(COND, [IF-TRUE], [IF-FALSE]) -# ------------------------------------- -# If COND is not the empty string, expand IF-TRUE, otherwise IF-FALSE. -# Comparable to m4_ifdef. -m4_define([m4_ifval], -[m4_if([$1], [], [$3], [$2])]) - - -# m4_n(TEXT) -# ---------- -# If TEXT is not empty, return TEXT and a new line, otherwise nothing. -m4_define([m4_n], -[m4_if([$1], - [], [], - [$1 -])]) - - -# m4_ifvaln(COND, [IF-TRUE], [IF-FALSE]) -# -------------------------------------- -# Same as `m4_ifval', but add an extra newline to IF-TRUE or IF-FALSE -# unless that argument is empty. -m4_define([m4_ifvaln], -[m4_if([$1], - [], [m4_n([$3])], - [m4_n([$2])])]) - - -# m4_ifset(MACRO, [IF-TRUE], [IF-FALSE]) -# -------------------------------------- -# If MACRO has no definition, or of its definition is the empty string, -# expand IF-FALSE, otherwise IF-TRUE. -m4_define([m4_ifset], -[m4_ifdef([$1], - [m4_ifval(_m4_defn([$1]), [$2], [$3])], - [$3])]) - - -# m4_ifndef(NAME, [IF-NOT-DEFINED], [IF-DEFINED]) -# ----------------------------------------------- -m4_define([m4_ifndef], -[m4_ifdef([$1], [$3], [$2])]) - - -# m4_case(SWITCH, VAL1, IF-VAL1, VAL2, IF-VAL2, ..., DEFAULT) -# ----------------------------------------------------------- -# m4 equivalent of -# switch (SWITCH) -# { -# case VAL1: -# IF-VAL1; -# break; -# case VAL2: -# IF-VAL2; -# break; -# ... -# default: -# DEFAULT; -# break; -# }. -# All the values are optional, and the macro is robust to active -# symbols properly quoted. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_case], -[m4_if([$#], 0, [], - [$#], 1, [], - [$#], 2, [$2], - [$1], [$2], [$3], - [$0([$1], m4_shift3($@))])]) - - -# m4_bmatch(SWITCH, RE1, VAL1, RE2, VAL2, ..., DEFAULT) -# ----------------------------------------------------- -# m4 equivalent of -# -# if (SWITCH =~ RE1) -# VAL1; -# elif (SWITCH =~ RE2) -# VAL2; -# elif ... -# ... -# else -# DEFAULT -# -# All the values are optional, and the macro is robust to active symbols -# properly quoted. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_bmatch], -[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])], - [$#], 1, [m4_fatal([$0: too few arguments: $#: $1])], - [$#], 2, [$2], - [m4_if(m4_bregexp([$1], [$2]), -1, [$0([$1], m4_shift3($@))], - [$3])])]) - - -# m4_car(LIST) -# m4_cdr(LIST) -# ------------ -# Manipulate m4 lists. -m4_define([m4_car], [[$1]]) -m4_define([m4_cdr], -[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], - [$#], 1, [], - [m4_dquote(m4_shift($@))])]) - -# _m4_cdr(LIST) -# ------------- -# Like m4_cdr, except include a leading comma unless only one element -# remains. Why? Because comparing a large list against [] is more -# expensive in expansion time than comparing the number of arguments; so -# _m4_cdr can be used to reduce the number of arguments when it is time -# to end recursion. -m4_define([_m4_cdr], -[m4_if([$#], 1, [], - [, m4_dquote(m4_shift($@))])]) - - - -# m4_cond(TEST1, VAL1, IF-VAL1, TEST2, VAL2, IF-VAL2, ..., [DEFAULT]) -# ------------------------------------------------------------------- -# Similar to m4_if, except that each TEST is expanded when encountered. -# If the expansion of TESTn matches the string VALn, the result is IF-VALn. -# The result is DEFAULT if no tests passed. This macro allows -# short-circuiting of expensive tests, where it pays to arrange quick -# filter tests to run first. -# -# For an example, consider a previous implementation of _AS_QUOTE_IFELSE: -# -# m4_if(m4_index([$1], [\]), [-1], [$2], -# m4_eval(m4_index([$1], [\\]) >= 0), [1], [$2], -# m4_eval(m4_index([$1], [\$]) >= 0), [1], [$2], -# m4_eval(m4_index([$1], [\`]) >= 0), [1], [$3], -# m4_eval(m4_index([$1], [\"]) >= 0), [1], [$3], -# [$2]) -# -# Here, m4_index is computed 5 times, and m4_eval 4, even if $1 contains -# no backslash. It is more efficient to do: -# -# m4_cond([m4_index([$1], [\])], [-1], [$2], -# [m4_eval(m4_index([$1], [\\]) >= 0)], [1], [$2], -# [m4_eval(m4_index([$1], [\$]) >= 0)], [1], [$2], -# [m4_eval(m4_index([$1], [\`]) >= 0)], [1], [$3], -# [m4_eval(m4_index([$1], [\"]) >= 0)], [1], [$3], -# [$2]) -# -# In the common case of $1 with no backslash, only one m4_index expansion -# occurs, and m4_eval is avoided altogether. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_cond], -[m4_if([$#], [0], [m4_fatal([$0: cannot be called without arguments])], - [$#], [1], [$1], - m4_eval([$# % 3]), [2], [m4_fatal([$0: missing an argument])], - [_$0($@)])]) - -m4_define([_m4_cond], -[m4_if(($1), [($2)], [$3], - [$#], [3], [], - [$#], [4], [$4], - [$0(m4_shift3($@))])]) - - -## ---------------------------------------- ## -## 6. Enhanced version of some primitives. ## -## ---------------------------------------- ## - -# m4_bpatsubsts(STRING, RE1, SUBST1, RE2, SUBST2, ...) -# ---------------------------------------------------- -# m4 equivalent of -# -# $_ = STRING; -# s/RE1/SUBST1/g; -# s/RE2/SUBST2/g; -# ... -# -# All the values are optional, and the macro is robust to active symbols -# properly quoted. -# -# I would have liked to name this macro `m4_bpatsubst', unfortunately, -# due to quotation problems, I need to double quote $1 below, therefore -# the anchors are broken :( I can't let users be trapped by that. -# -# Recall that m4_shift3 always results in an argument. Hence, we need -# to distinguish between a final deletion vs. ending recursion. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_bpatsubsts], -[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])], - [$#], 1, [m4_fatal([$0: too few arguments: $#: $1])], - [$#], 2, [m4_unquote(m4_builtin([patsubst], [[$1]], [$2]))], - [$#], 3, [m4_unquote(m4_builtin([patsubst], [[$1]], [$2], [$3]))], - [_$0($@m4_if(m4_eval($# & 1), 0, [,]))])]) -m4_define([_m4_bpatsubsts], -[m4_if([$#], 2, [$1], - [$0(m4_builtin([patsubst], [[$1]], [$2], [$3]), - m4_shift3($@))])]) - - -# m4_define_default(MACRO, VALUE) -# ------------------------------- -# If MACRO is undefined, set it to VALUE. -m4_define([m4_define_default], -[m4_ifndef([$1], [m4_define($@)])]) - - -# m4_default(EXP1, EXP2) -# ---------------------- -# Returns EXP1 if non empty, otherwise EXP2. -# -# This macro is called on hot paths, so inline the contents of m4_ifval, -# for one less round of expansion. -m4_define([m4_default], -[m4_if([$1], [], [$2], [$1])]) - - -# m4_defn(NAME) -# ------------- -# Like the original, except guarantee a warning when using something which is -# undefined (unlike M4 1.4.x). This replacement is not a full-featured -# replacement: if any of the defined macros contain unbalanced quoting, but -# when pasted together result in a well-quoted string, then only native m4 -# support is able to get it correct. But that's where quadrigraphs come in -# handy, if you really need unbalanced quotes inside your macros. -# -# This macro is called frequently, so minimize the amount of additional -# expansions by skipping m4_ifndef. Better yet, if __m4_version__ exists, -# (added in M4 1.6), then let m4 do the job for us (see m4_init). -# -# _m4_defn is for internal use only - it bypasses the wrapper, so it -# must only be used on one argument at a time, and only on macros -# known to be defined. Make sure this still works if the user renames -# m4_defn but not _m4_defn. -m4_copy([m4_defn], [_m4_defn]) -m4_define([m4_defn], -[m4_if([$#], [0], [[$0]], - [$#], [1], [m4_ifdef([$1], [_m4_defn([$1])], - [m4_fatal([$0: undefined macro: $1])])], - [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])]) - - -# _m4_dumpdefs_up(NAME) -# --------------------- -m4_define([_m4_dumpdefs_up], -[m4_ifdef([$1], - [m4_pushdef([_m4_dumpdefs], _m4_defn([$1]))dnl -m4_dumpdef([$1])dnl -_m4_popdef([$1])dnl -_m4_dumpdefs_up([$1])])]) - - -# _m4_dumpdefs_down(NAME) -# ----------------------- -m4_define([_m4_dumpdefs_down], -[m4_ifdef([_m4_dumpdefs], - [m4_pushdef([$1], _m4_defn([_m4_dumpdefs]))dnl -_m4_popdef([_m4_dumpdefs])dnl -_m4_dumpdefs_down([$1])])]) - - -# m4_dumpdefs(NAME) -# ----------------- -# Similar to `m4_dumpdef(NAME)', but if NAME was m4_pushdef'ed, display its -# value stack (most recent displayed first). -m4_define([m4_dumpdefs], -[_m4_dumpdefs_up([$1])dnl -_m4_dumpdefs_down([$1])]) - - -# m4_popdef(NAME) -# --------------- -# Like the original, except guarantee a warning when using something which is -# undefined (unlike M4 1.4.x). -# -# This macro is called frequently, so minimize the amount of additional -# expansions by skipping m4_ifndef. Better yet, if __m4_version__ exists, -# (added in M4 1.6), then let m4 do the job for us (see m4_init). -# -# _m4_popdef is for internal use only - it bypasses the wrapper, so it -# must only be used on macros known to be defined. Make sure this -# still works if the user renames m4_popdef but not _m4_popdef. -m4_copy([m4_popdef], [_m4_popdef]) -m4_define([m4_popdef], -[m4_if([$#], [0], [[$0]], - [$#], [1], [m4_ifdef([$1], [_m4_popdef([$1])], - [m4_fatal([$0: undefined macro: $1])])], - [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])]) - - -# m4_shiftn(N, ...) -# ----------------- -# Returns ... shifted N times. Useful for recursive "varargs" constructs. -# -# Autoconf does not use this macro, because it is inherently slower than -# calling the common cases of m4_shift2 or m4_shift3 directly. But it -# might as well be fast for other clients, such as Libtool. One way to -# do this is to expand $@ only once in _m4_shiftn (otherwise, for long -# lists, the expansion of m4_if takes twice as much memory as what the -# list itself occupies, only to throw away the unused branch). The end -# result is strictly equivalent to -# m4_if([$1], 1, [m4_shift(,m4_shift(m4_shift($@)))], -# [_m4_shiftn(m4_decr([$1]), m4_shift(m4_shift($@)))]) -# but with the final `m4_shift(m4_shift($@)))' shared between the two -# paths. The first leg uses a no-op m4_shift(,$@) to balance out the (). -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_shiftn], -[m4_assert(0 < $1 && $1 < $#)_$0($@)]) - -m4_define([_m4_shiftn], -[m4_if([$1], 1, [m4_shift(], - [$0(m4_decr([$1])]), m4_shift(m4_shift($@)))]) - -# m4_shift2(...) -# m4_shift3(...) -# ----------------- -# Returns ... shifted twice, and three times. Faster than m4_shiftn. -m4_define([m4_shift2], [m4_shift(m4_shift($@))]) -m4_define([m4_shift3], [m4_shift(m4_shift(m4_shift($@)))]) - -# _m4_shift2(...) -# _m4_shift3(...) -# --------------- -# Like m4_shift2 or m4_shift3, except include a leading comma unless shifting -# consumes all arguments. Why? Because in recursion, it is nice to -# distinguish between 1 element left and 0 elements left, based on how many -# arguments this shift expands to. -m4_define([_m4_shift2], -[m4_if([$#], [2], [], - [, m4_shift(m4_shift($@))])]) -m4_define([_m4_shift3], -[m4_if([$#], [3], [], - [, m4_shift(m4_shift(m4_shift($@)))])]) - - -# m4_undefine(NAME) -# ----------------- -# Like the original, except guarantee a warning when using something which is -# undefined (unlike M4 1.4.x). -# -# This macro is called frequently, so minimize the amount of additional -# expansions by skipping m4_ifndef. Better yet, if __m4_version__ exists, -# (added in M4 1.6), then let m4 do the job for us (see m4_init). -# -# _m4_undefine is for internal use only - it bypasses the wrapper, so -# it must only be used on macros known to be defined. Make sure this -# still works if the user renames m4_undefine but not _m4_undefine. -m4_copy([m4_undefine], [_m4_undefine]) -m4_define([m4_undefine], -[m4_if([$#], [0], [[$0]], - [$#], [1], [m4_ifdef([$1], [_m4_undefine([$1])], - [m4_fatal([$0: undefined macro: $1])])], - [m4_foreach([_m4_macro], [$@], [$0(_m4_defn([_m4_macro]))])])]) - -# _m4_wrap(PRE, POST) -# ------------------- -# Helper macro for m4_wrap and m4_wrap_lifo. Allows nested calls to -# m4_wrap within wrapped text. Use _m4_defn and _m4_popdef for speed. -m4_define([_m4_wrap], -[m4_ifdef([$0_text], - [m4_define([$0_text], [$1]_m4_defn([$0_text])[$2])], - [m4_builtin([m4wrap], [m4_unquote( - _m4_defn([$0_text])_m4_popdef([$0_text]))])m4_define([$0_text], [$1$2])])]) - -# m4_wrap(TEXT) -# ------------- -# Append TEXT to the list of hooks to be executed at the end of input. -# Whereas the order of the original may be LIFO in the underlying m4, -# this version is always FIFO. -m4_define([m4_wrap], -[_m4_wrap([], [$1[]])]) - -# m4_wrap_lifo(TEXT) -# ------------------ -# Prepend TEXT to the list of hooks to be executed at the end of input. -# Whereas the order of m4_wrap may be FIFO in the underlying m4, this -# version is always LIFO. -m4_define([m4_wrap_lifo], -[_m4_wrap([$1[]])]) - -## ------------------------- ## -## 7. Quoting manipulation. ## -## ------------------------- ## - - -# m4_apply(MACRO, LIST) -# --------------------- -# Invoke MACRO, with arguments provided from the quoted list of -# comma-separated quoted arguments. If LIST is empty, invoke MACRO -# without arguments. The expansion will not be concatenated with -# subsequent text. -m4_define([m4_apply], -[m4_if([$2], [], [$1], [$1($2)])[]]) - -# _m4_apply(MACRO, LIST) -# ---------------------- -# Like m4_apply, except do nothing if LIST is empty. -m4_define([_m4_apply], -[m4_if([$2], [], [], [$1($2)[]])]) - - -# m4_count(ARGS) -# -------------- -# Return a count of how many ARGS are present. -m4_define([m4_count], [$#]) - - -# m4_do(STRING, ...) -# ------------------ -# This macro invokes all its arguments (in sequence, of course). It is -# useful for making your macros more structured and readable by dropping -# unnecessary dnl's and have the macros indented properly. No concatenation -# occurs after a STRING; use m4_unquote(m4_join(,STRING)) for that. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_do], -[m4_if([$#], 0, [], - [$#], 1, [$1[]], - [$1[]$0(m4_shift($@))])]) - - -# m4_dquote(ARGS) -# --------------- -# Return ARGS as a quoted list of quoted arguments. -m4_define([m4_dquote], [[$@]]) - - -# m4_dquote_elt(ARGS) -# ------------------- -# Return ARGS as an unquoted list of double-quoted arguments. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_dquote_elt], -[m4_if([$#], [0], [], - [$#], [1], [[[$1]]], - [[[$1]],$0(m4_shift($@))])]) - - -# m4_echo(ARGS) -# ------------- -# Return the ARGS, with the same level of quoting. Whitespace after -# unquoted commas are consumed. -m4_define([m4_echo], [$@]) - - -# m4_expand(ARG) -# -------------- -# Return the expansion of ARG as a single string. Unlike m4_quote($1), this -# correctly preserves whitespace following single-quoted commas that appeared -# within ARG. -# -# m4_define([active], [ACT, IVE]) -# m4_define([active2], [[ACT, IVE]]) -# m4_quote(active, active2) -# => ACT,IVE,ACT, IVE -# m4_expand([active, active2]) -# => ACT, IVE, ACT, IVE -# -# Unfortunately, due to limitations in m4, ARG must expand to something -# with balanced quotes (use quadrigraphs to get around this). The input -# is not likely to have unbalanced -=<{(/)}>=- quotes, and it is possible -# to have unbalanced (), provided it was specified with proper [] quotes. -# -# Exploit that extra () will group unquoted commas and the following -# whitespace, then convert () to []. m4_bpatsubst can't handle newlines -# inside $1, and m4_substr strips quoting. So we (ab)use m4_changequote. -m4_define([m4_expand], [_$0(-=<{($1)}>=-)]) -m4_define([_m4_expand], -[m4_changequote([-=<{(], [)}>=-])$1m4_changequote([, ])]) - - -# m4_ignore(ARGS) -# --------------- -# Expands to nothing. Useful for conditionally ignoring an arbitrary -# number of arguments (see _m4_list_cmp for an example). -m4_define([m4_ignore]) - - -# m4_make_list(ARGS) -# ------------------ -# Similar to m4_dquote, this creates a quoted list of quoted ARGS. This -# version is less efficient than m4_dquote, but separates each argument -# with a comma and newline, rather than just comma, for readability. -# When developing an m4sugar algorithm, you could temporarily use -# m4_pushdef([m4_dquote],m4_defn([m4_make_list])) -# around your code to make debugging easier. -m4_define([m4_make_list], [m4_join([, -], m4_dquote_elt($@))]) - - -# m4_noquote(STRING) -# ------------------ -# Return the result of ignoring all quotes in STRING and invoking the -# macros it contains. Amongst other things, this is useful for enabling -# macro invocations inside strings with [] blocks (for instance regexps -# and help-strings). On the other hand, since all quotes are disabled, -# any macro expanded during this time that relies on nested [] quoting -# will likely crash and burn. This macro is seldom useful; consider -# m4_unquote or m4_expand instead. -m4_define([m4_noquote], -[m4_changequote([-=<{(],[)}>=-])$1-=<{()}>=-m4_changequote([,])]) - - -# m4_quote(ARGS) -# -------------- -# Return ARGS as a single argument. Any whitespace after unquoted commas -# is stripped. There is always output, even when there were no arguments. -# -# It is important to realize the difference between `m4_quote(exp)' and -# `[exp]': in the first case you obtain the quoted *result* of the -# expansion of EXP, while in the latter you just obtain the string -# `exp'. -m4_define([m4_quote], [[$*]]) - - -# _m4_quote(ARGS) -# --------------- -# Like m4_quote, except that when there are no arguments, there is no -# output. For conditional scenarios (such as passing _m4_quote as the -# macro name in m4_mapall), this feature can be used to distinguish between -# one argument of the empty string vs. no arguments. However, in the -# normal case with arguments present, this is less efficient than m4_quote. -m4_define([_m4_quote], -[m4_if([$#], [0], [], [[$*]])]) - - -# m4_reverse(ARGS) -# ---------------- -# Output ARGS in reverse order. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_reverse], -[m4_if([$#], [0], [], [$#], [1], [[$1]], - [$0(m4_shift($@)), [$1]])]) - - -# m4_unquote(ARGS) -# ---------------- -# Remove one layer of quotes from each ARG, performing one level of -# expansion. For one argument, m4_unquote([arg]) is more efficient than -# m4_do([arg]), but for multiple arguments, the difference is that -# m4_unquote separates arguments with commas while m4_do concatenates. -# Follow this macro with [] if concatenation with subsequent text is -# undesired. -m4_define([m4_unquote], [$*]) - - -## -------------------------- ## -## 8. Implementing m4 loops. ## -## -------------------------- ## - - -# m4_for(VARIABLE, FIRST, LAST, [STEP = +/-1], EXPRESSION) -# -------------------------------------------------------- -# Expand EXPRESSION defining VARIABLE to FROM, FROM + 1, ..., TO with -# increments of STEP. Both limits are included, and bounds are -# checked for consistency. The algorithm is robust to indirect -# VARIABLE names. Changing VARIABLE inside EXPRESSION will not impact -# the number of iterations. -# -# Uses _m4_defn for speed, and avoid dnl in the macro body. -m4_define([m4_for], -[m4_pushdef([$1], m4_eval([$2]))]dnl -[m4_cond([m4_eval(([$3]) > ([$2]))], 1, - [m4_pushdef([_m4_step], m4_eval(m4_default([$4], - 1)))m4_assert(_m4_step > 0)_$0([$1], _m4_defn([$1]), - m4_eval((([$3]) - ([$2])) / _m4_step * _m4_step + ([$2])), - _m4_step, [$5])], - [m4_eval(([$3]) < ([$2]))], 1, - [m4_pushdef([_m4_step], m4_eval(m4_default([$4], - -1)))m4_assert(_m4_step < 0)_$0([$1], _m4_defn([$1]), - m4_eval((([$2]) - ([$3])) / -(_m4_step) * _m4_step + ([$2])), - _m4_step, [$5])], - [m4_pushdef([_m4_step])$5])[]]dnl -[m4_popdef([_m4_step], [$1])]) - - -# _m4_for(VARIABLE, COUNT, LAST, STEP, EXPRESSION) -# ------------------------------------------------ -# Core of the loop, no consistency checks, all arguments are plain -# numbers. Define VARIABLE to COUNT, expand EXPRESSION, then alter -# COUNT by STEP and iterate if COUNT is not LAST. -m4_define([_m4_for], -[m4_define([$1], [$2])$5[]m4_if([$2], [$3], [], - [$0([$1], m4_eval([$2 + $4]), [$3], [$4], [$5])])]) - - -# Implementing `foreach' loops in m4 is much more tricky than it may -# seem. For example, the old M4 1.4.4 manual had an incorrect example, -# which looked like this (when translated to m4sugar): -# -# | # foreach(VAR, (LIST), STMT) -# | m4_define([foreach], -# | [m4_pushdef([$1])_foreach([$1], [$2], [$3])m4_popdef([$1])]) -# | m4_define([_arg1], [$1]) -# | m4_define([_foreach], -# | [m4_if([$2], [()], , -# | [m4_define([$1], _arg1$2)$3[]_foreach([$1], (m4_shift$2), [$3])])]) -# -# But then if you run -# -# | m4_define(a, 1) -# | m4_define(b, 2) -# | m4_define(c, 3) -# | foreach([f], [([a], [(b], [c)])], [echo f -# | ]) -# -# it gives -# -# => echo 1 -# => echo (2,3) -# -# which is not what is expected. -# -# Of course the problem is that many quotes are missing. So you add -# plenty of quotes at random places, until you reach the expected -# result. Alternatively, if you are a quoting wizard, you directly -# reach the following implementation (but if you really did, then -# apply to the maintenance of m4sugar!). -# -# | # foreach(VAR, (LIST), STMT) -# | m4_define([foreach], [m4_pushdef([$1])_foreach($@)m4_popdef([$1])]) -# | m4_define([_arg1], [[$1]]) -# | m4_define([_foreach], -# | [m4_if($2, [()], , -# | [m4_define([$1], [_arg1$2])$3[]_foreach([$1], [(m4_shift$2)], [$3])])]) -# -# which this time answers -# -# => echo a -# => echo (b -# => echo c) -# -# Bingo! -# -# Well, not quite. -# -# With a better look, you realize that the parens are more a pain than -# a help: since anyway you need to quote properly the list, you end up -# with always using an outermost pair of parens and an outermost pair -# of quotes. Rejecting the parens both eases the implementation, and -# simplifies the use: -# -# | # foreach(VAR, (LIST), STMT) -# | m4_define([foreach], [m4_pushdef([$1])_foreach($@)m4_popdef([$1])]) -# | m4_define([_arg1], [$1]) -# | m4_define([_foreach], -# | [m4_if($2, [], , -# | [m4_define([$1], [_arg1($2)])$3[]_foreach([$1], [m4_shift($2)], [$3])])]) -# -# -# Now, just replace the `$2' with `m4_quote($2)' in the outer `m4_if' -# to improve robustness, and you come up with a nice implementation -# that doesn't require extra parentheses in the user's LIST. -# -# But wait - now the algorithm is quadratic, because every recursion of -# the algorithm keeps the entire LIST and merely adds another m4_shift to -# the quoted text. If the user has a lot of elements in LIST, you can -# bring the system to its knees with the memory m4 then requires, or trip -# the m4 --nesting-limit recursion factor. The only way to avoid -# quadratic growth is ensure m4_shift is expanded prior to the recursion. -# Hence the design below. -# -# The M4 manual now includes a chapter devoted to this issue, with -# the lessons learned from m4sugar. And still, this design is only -# optimal for M4 1.6; see foreach.m4 for yet more comments on why -# M4 1.4.x uses yet another implementation. - - -# m4_foreach(VARIABLE, LIST, EXPRESSION) -# -------------------------------------- -# -# Expand EXPRESSION assigning each value of the LIST to VARIABLE. -# LIST should have the form `item_1, item_2, ..., item_n', i.e. the -# whole list must *quoted*. Quote members too if you don't want them -# to be expanded. -# -# This macro is robust to active symbols: -# | m4_define(active, [ACT, IVE]) -# | m4_foreach(Var, [active, active], [-Var-]) -# => -ACT--IVE--ACT--IVE- -# -# | m4_foreach(Var, [[active], [active]], [-Var-]) -# => -ACT, IVE--ACT, IVE- -# -# | m4_foreach(Var, [[[active]], [[active]]], [-Var-]) -# => -active--active- -# -# This macro is called frequently, so avoid extra expansions such as -# m4_ifval and dnl. Also, since $2 might be quite large, try to use it -# as little as possible in _m4_foreach; each extra use requires that much -# more memory for expansion. So, rather than directly compare $2 against -# [] and use m4_car/m4_cdr for recursion, we instead unbox the list (which -# requires swapping the argument order in the helper), insert an ignored -# third argument, and use m4_shift3 to detect when recursion is complete. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_foreach], -[m4_if([$2], [], [], - [m4_pushdef([$1])_$0([$1], [$3], [], $2)m4_popdef([$1])])]) - -m4_define([_m4_foreach], -[m4_if([$#], [3], [], - [m4_define([$1], [$4])$2[]$0([$1], [$2], m4_shift3($@))])]) - - -# m4_foreach_w(VARIABLE, LIST, EXPRESSION) -# ---------------------------------------- -# -# Like m4_foreach, but the list is whitespace separated. -# -# This macro is robust to active symbols: -# m4_foreach_w([Var], [ active -# b act\ -# ive ], [-Var-])end -# => -active--b--active-end -# -m4_define([m4_foreach_w], -[m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])]) - - -# m4_map(MACRO, LIST) -# m4_mapall(MACRO, LIST) -# ---------------------- -# Invoke MACRO($1), MACRO($2) etc. where $1, $2... are the elements of -# LIST. $1, $2... must in turn be lists, appropriate for m4_apply. -# If LIST contains an empty sublist, m4_map skips the expansion of -# MACRO, while m4_mapall expands MACRO with no arguments. -# -# Since LIST may be quite large, we want to minimize how often it -# appears in the expansion. Rather than use m4_car/m4_cdr iteration, -# we unbox the list, ignore the second argument, and use m4_shift2 to -# detect the end of recursion. The mismatch in () is intentional; see -# _m4_map. For m4_map, an empty list behaves like an empty sublist -# and gets ignored; for m4_mapall, we must special-case the empty -# list. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_map], -[_m4_map([_m4_apply([$1]], [], $2)]) - -m4_define([m4_mapall], -[m4_if([$2], [], [], - [_m4_map([m4_apply([$1]], [], $2)])]) - - -# m4_map_sep(MACRO, SEPARATOR, LIST) -# m4_mapall_sep(MACRO, SEPARATOR, LIST) -# ------------------------------------- -# Invoke MACRO($1), SEPARATOR, MACRO($2), ..., MACRO($N) where $1, -# $2... $N are the elements of LIST, and are in turn lists appropriate -# for m4_apply. SEPARATOR is expanded, in order to allow the creation -# of a list of arguments by using a single-quoted comma as the -# separator. For each empty sublist, m4_map_sep skips the expansion -# of MACRO and SEPARATOR, while m4_mapall_sep expands MACRO with no -# arguments. -# -# For m4_mapall_sep, merely expand the first iteration without the -# separator, then include separator as part of subsequent recursion; -# but avoid extra expansion of LIST's side-effects via a helper macro. -# For m4_map_sep, things are trickier - we don't know if the first -# list element is an empty sublist, so we must define a self-modifying -# helper macro and use that as the separator instead. -m4_define([m4_map_sep], -[m4_pushdef([m4_Sep], [m4_define([m4_Sep], _m4_defn([m4_unquote]))])]dnl -[_m4_map([_m4_apply([m4_Sep([$2])[]$1]], [], $3)m4_popdef([m4_Sep])]) - -m4_define([m4_mapall_sep], -[m4_if([$3], [], [], [_$0([$1], [$2], $3)])]) - -m4_define([_m4_mapall_sep], -[m4_apply([$1], [$3])_m4_map([m4_apply([$2[]$1]], m4_shift2($@))]) - -# _m4_map(PREFIX, IGNORED, SUBLIST, ...) -# -------------------------------------- -# Common implementation for all four m4_map variants. The mismatch in -# the number of () is intentional. PREFIX must supply a form of -# m4_apply, the open `(', and the MACRO to be applied. Each iteration -# then appends `,', the current SUBLIST and the closing `)', then -# recurses to the next SUBLIST. IGNORED is an aid to ending recursion -# efficiently. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([_m4_map], -[m4_if([$#], [2], [], - [$1, [$3])$0([$1], m4_shift2($@))])]) - -# m4_transform(EXPRESSION, ARG...) -# -------------------------------- -# Expand EXPRESSION([ARG]) for each argument. More efficient than -# m4_foreach([var], [ARG...], [EXPRESSION(m4_defn([var]))]) -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_transform], -[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], - [$#], [1], [], - [$#], [2], [$1([$2])[]], - [$1([$2])[]$0([$1], m4_shift2($@))])]) - - -# m4_transform_pair(EXPRESSION, [END-EXPR = EXPRESSION], ARG...) -# -------------------------------------------------------------- -# Perform a pairwise grouping of consecutive ARGs, by expanding -# EXPRESSION([ARG1], [ARG2]). If there are an odd number of ARGs, the -# final argument is expanded with END-EXPR([ARGn]). -# -# For example: -# m4_define([show], [($*)m4_newline])dnl -# m4_transform_pair([show], [], [a], [b], [c], [d], [e])dnl -# => (a,b) -# => (c,d) -# => (e) -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_transform_pair], -[m4_if([$#], [0], [m4_fatal([$0: too few arguments: $#])], - [$#], [1], [m4_fatal([$0: too few arguments: $#: $1])], - [$#], [2], [], - [$#], [3], [m4_default([$2], [$1])([$3])[]], - [$#], [4], [$1([$3], [$4])[]], - [$1([$3], [$4])[]$0([$1], [$2], m4_shift(m4_shift3($@)))])]) - - -## --------------------------- ## -## 9. More diversion support. ## -## --------------------------- ## - - -# _m4_divert(DIVERSION-NAME or NUMBER) -# ------------------------------------ -# If DIVERSION-NAME is the name of a diversion, return its number, -# otherwise if it is a NUMBER return it. -m4_define([_m4_divert], -[m4_ifdef([_m4_divert($1)], - [m4_indir([_m4_divert($1)])], - [$1])]) - -# KILL is only used to suppress output. -m4_define([_m4_divert(KILL)], -1) - -# The empty diversion name is a synonym for 0. -m4_define([_m4_divert()], 0) - - -# _m4_divert_n_stack -# ------------------ -# Print m4_divert_stack with newline prepended, if it's nonempty. -m4_define([_m4_divert_n_stack], -[m4_ifdef([m4_divert_stack], [ -_m4_defn([m4_divert_stack])])]) - - -# m4_divert(DIVERSION-NAME) -# ------------------------- -# Change the diversion stream to DIVERSION-NAME. -m4_define([m4_divert], -[m4_define([m4_divert_stack], m4_location[: $0: $1]_m4_divert_n_stack)]dnl -[m4_builtin([divert], _m4_divert([$1]))]) - - -# m4_divert_push(DIVERSION-NAME) -# ------------------------------ -# Change the diversion stream to DIVERSION-NAME, while stacking old values. -m4_define([m4_divert_push], -[m4_pushdef([m4_divert_stack], m4_location[: $0: $1]_m4_divert_n_stack)]dnl -[m4_pushdef([_m4_divert_diversion], [$1])]dnl -[m4_builtin([divert], _m4_divert([$1]))]) - - -# m4_divert_pop([DIVERSION-NAME]) -# ------------------------------- -# Change the diversion stream to its previous value, unstacking it. -# If specified, verify we left DIVERSION-NAME. -# When we pop the last value from the stack, we divert to -1. -m4_define([m4_divert_pop], -[m4_ifndef([_m4_divert_diversion], - [m4_fatal([too many m4_divert_pop])])]dnl -[m4_if([$1], [], [], - [$1], _m4_defn([_m4_divert_diversion]), [], - [m4_fatal([$0($1): diversion mismatch: ]_m4_divert_n_stack)])]dnl -[_m4_popdef([m4_divert_stack], [_m4_divert_diversion])]dnl -[m4_builtin([divert], - m4_ifdef([_m4_divert_diversion], - [_m4_divert(_m4_defn([_m4_divert_diversion]))], - -1))]) - - -# m4_divert_text(DIVERSION-NAME, CONTENT) -# --------------------------------------- -# Output CONTENT into DIVERSION-NAME (which may be a number actually). -# An end of line is appended for free to CONTENT. -m4_define([m4_divert_text], -[m4_divert_push([$1])$2 -m4_divert_pop([$1])]) - - -# m4_divert_once(DIVERSION-NAME, CONTENT) -# --------------------------------------- -# Output CONTENT into DIVERSION-NAME once, if not already there. -# An end of line is appended for free to CONTENT. -m4_define([m4_divert_once], -[m4_expand_once([m4_divert_text([$1], [$2])])]) - - -# m4_undivert(DIVERSION-NAME) -# --------------------------- -# Undivert DIVERSION-NAME. Unlike the M4 version, this only takes a single -# diversion identifier, and should not be used to undivert files. -m4_define([m4_undivert], -[m4_builtin([undivert], _m4_divert([$1]))]) - - -## --------------------------------------------- ## -## 10. Defining macros with bells and whistles. ## -## --------------------------------------------- ## - -# `m4_defun' is basically `m4_define' but it equips the macro with the -# needed machinery for `m4_require'. A macro must be m4_defun'd if -# either it is m4_require'd, or it m4_require's. -# -# Two things deserve attention and are detailed below: -# 1. Implementation of m4_require -# 2. Keeping track of the expansion stack -# -# 1. Implementation of m4_require -# =============================== -# -# Of course m4_defun AC_PROVIDE's the macro, so that a macro which has -# been expanded is not expanded again when m4_require'd, but the -# difficult part is the proper expansion of macros when they are -# m4_require'd. -# -# The implementation is based on two ideas, (i) using diversions to -# prepare the expansion of the macro and its dependencies (by Franc,ois -# Pinard), and (ii) expand the most recently m4_require'd macros _after_ -# the previous macros (by Axel Thimm). -# -# -# The first idea: why use diversions? -# ----------------------------------- -# -# When a macro requires another, the other macro is expanded in new -# diversion, GROW. When the outer macro is fully expanded, we first -# undivert the most nested diversions (GROW - 1...), and finally -# undivert GROW. To understand why we need several diversions, -# consider the following example: -# -# | m4_defun([TEST1], [Test...REQUIRE([TEST2])1]) -# | m4_defun([TEST2], [Test...REQUIRE([TEST3])2]) -# | m4_defun([TEST3], [Test...3]) -# -# Because m4_require is not required to be first in the outer macros, we -# must keep the expansions of the various levels of m4_require separated. -# Right before executing the epilogue of TEST1, we have: -# -# GROW - 2: Test...3 -# GROW - 1: Test...2 -# GROW: Test...1 -# BODY: -# -# Finally the epilogue of TEST1 undiverts GROW - 2, GROW - 1, and -# GROW into the regular flow, BODY. -# -# GROW - 2: -# GROW - 1: -# GROW: -# BODY: Test...3; Test...2; Test...1 -# -# (The semicolons are here for clarification, but of course are not -# emitted.) This is what Autoconf 2.0 (I think) to 2.13 (I'm sure) -# implement. -# -# -# The second idea: first required first out -# ----------------------------------------- -# -# The natural implementation of the idea above is buggy and produces -# very surprising results in some situations. Let's consider the -# following example to explain the bug: -# -# | m4_defun([TEST1], [REQUIRE([TEST2a])REQUIRE([TEST2b])]) -# | m4_defun([TEST2a], []) -# | m4_defun([TEST2b], [REQUIRE([TEST3])]) -# | m4_defun([TEST3], [REQUIRE([TEST2a])]) -# | -# | AC_INIT -# | TEST1 -# -# The dependencies between the macros are: -# -# 3 --- 2b -# / \ is m4_require'd by -# / \ left -------------------- right -# 2a ------------ 1 -# -# If you strictly apply the rules given in the previous section you get: -# -# GROW - 2: TEST3 -# GROW - 1: TEST2a; TEST2b -# GROW: TEST1 -# BODY: -# -# (TEST2a, although required by TEST3 is not expanded in GROW - 3 -# because is has already been expanded before in GROW - 1, so it has -# been AC_PROVIDE'd, so it is not expanded again) so when you undivert -# the stack of diversions, you get: -# -# GROW - 2: -# GROW - 1: -# GROW: -# BODY: TEST3; TEST2a; TEST2b; TEST1 -# -# i.e., TEST2a is expanded after TEST3 although the latter required the -# former. -# -# Starting from 2.50, we use an implementation provided by Axel Thimm. -# The idea is simple: the order in which macros are emitted must be the -# same as the one in which macros are expanded. (The bug above can -# indeed be described as: a macro has been AC_PROVIDE'd before its -# dependent, but it is emitted after: the lack of correlation between -# emission and expansion order is guilty). -# -# How to do that? You keep the stack of diversions to elaborate the -# macros, but each time a macro is fully expanded, emit it immediately. -# -# In the example above, when TEST2a is expanded, but it's epilogue is -# not run yet, you have: -# -# GROW - 2: -# GROW - 1: TEST2a -# GROW: Elaboration of TEST1 -# BODY: -# -# The epilogue of TEST2a emits it immediately: -# -# GROW - 2: -# GROW - 1: -# GROW: Elaboration of TEST1 -# BODY: TEST2a -# -# TEST2b then requires TEST3, so right before the epilogue of TEST3, you -# have: -# -# GROW - 2: TEST3 -# GROW - 1: Elaboration of TEST2b -# GROW: Elaboration of TEST1 -# BODY: TEST2a -# -# The epilogue of TEST3 emits it: -# -# GROW - 2: -# GROW - 1: Elaboration of TEST2b -# GROW: Elaboration of TEST1 -# BODY: TEST2a; TEST3 -# -# TEST2b is now completely expanded, and emitted: -# -# GROW - 2: -# GROW - 1: -# GROW: Elaboration of TEST1 -# BODY: TEST2a; TEST3; TEST2b -# -# and finally, TEST1 is finished and emitted: -# -# GROW - 2: -# GROW - 1: -# GROW: -# BODY: TEST2a; TEST3; TEST2b: TEST1 -# -# The idea is simple, but the implementation is a bit evolved. If you -# are like me, you will want to see the actual functioning of this -# implementation to be convinced. The next section gives the full -# details. -# -# -# The Axel Thimm implementation at work -# ------------------------------------- -# -# We consider the macros above, and this configure.ac: -# -# AC_INIT -# TEST1 -# -# You should keep the definitions of _m4_defun_pro, _m4_defun_epi, and -# m4_require at hand to follow the steps. -# -# This implements tries not to assume that the current diversion is -# BODY, so as soon as a macro (m4_defun'd) is expanded, we first -# record the current diversion under the name _m4_divert_dump (denoted -# DUMP below for short). This introduces an important difference with -# the previous versions of Autoconf: you cannot use m4_require if you -# are not inside an m4_defun'd macro, and especially, you cannot -# m4_require directly from the top level. -# -# We have not tried to simulate the old behavior (better yet, we -# diagnose it), because it is too dangerous: a macro m4_require'd from -# the top level is expanded before the body of `configure', i.e., before -# any other test was run. I let you imagine the result of requiring -# AC_STDC_HEADERS for instance, before AC_PROG_CC was actually run.... -# -# After AC_INIT was run, the current diversion is BODY. -# * AC_INIT was run -# DUMP: undefined -# diversion stack: BODY |- -# -# * TEST1 is expanded -# The prologue of TEST1 sets _m4_divert_dump, which is the diversion -# where the current elaboration will be dumped, to the current -# diversion. It also m4_divert_push to GROW, where the full -# expansion of TEST1 and its dependencies will be elaborated. -# DUMP: BODY -# BODY: empty -# diversions: GROW, BODY |- -# -# * TEST1 requires TEST2a -# _m4_require_call m4_divert_pushes another temporary diversion, -# GROW - 1, and expands TEST2a in there. -# DUMP: BODY -# BODY: empty -# GROW - 1: TEST2a -# diversions: GROW - 1, GROW, BODY |- -# Than the content of the temporary diversion is moved to DUMP and the -# temporary diversion is popped. -# DUMP: BODY -# BODY: TEST2a -# diversions: GROW, BODY |- -# -# * TEST1 requires TEST2b -# Again, _m4_require_call pushes GROW - 1 and heads to expand TEST2b. -# DUMP: BODY -# BODY: TEST2a -# diversions: GROW - 1, GROW, BODY |- -# -# * TEST2b requires TEST3 -# _m4_require_call pushes GROW - 2 and expands TEST3 here. -# (TEST3 requires TEST2a, but TEST2a has already been m4_provide'd, so -# nothing happens.) -# DUMP: BODY -# BODY: TEST2a -# GROW - 2: TEST3 -# diversions: GROW - 2, GROW - 1, GROW, BODY |- -# Than the diversion is appended to DUMP, and popped. -# DUMP: BODY -# BODY: TEST2a; TEST3 -# diversions: GROW - 1, GROW, BODY |- -# -# * TEST1 requires TEST2b (contd.) -# The content of TEST2b is expanded... -# DUMP: BODY -# BODY: TEST2a; TEST3 -# GROW - 1: TEST2b, -# diversions: GROW - 1, GROW, BODY |- -# ... and moved to DUMP. -# DUMP: BODY -# BODY: TEST2a; TEST3; TEST2b -# diversions: GROW, BODY |- -# -# * TEST1 is expanded: epilogue -# TEST1's own content is in GROW... -# DUMP: BODY -# BODY: TEST2a; TEST3; TEST2b -# GROW: TEST1 -# diversions: BODY |- -# ... and it's epilogue moves it to DUMP and then undefines DUMP. -# DUMP: undefined -# BODY: TEST2a; TEST3; TEST2b; TEST1 -# diversions: BODY |- -# -# -# 2. Keeping track of the expansion stack -# ======================================= -# -# When M4 expansion goes wrong it is often extremely hard to find the -# path amongst macros that drove to the failure. What is needed is -# the stack of macro `calls'. One could imagine that GNU M4 would -# maintain a stack of macro expansions, unfortunately it doesn't, so -# we do it by hand. This is of course extremely costly, but the help -# this stack provides is worth it. Nevertheless to limit the -# performance penalty this is implemented only for m4_defun'd macros, -# not for define'd macros. -# -# The scheme is simplistic: each time we enter an m4_defun'd macros, -# we prepend its name in m4_expansion_stack, and when we exit the -# macro, we remove it (thanks to pushdef/popdef). -# -# In addition, we want to detect circular m4_require dependencies. -# Each time we expand a macro FOO we define _m4_expanding(FOO); and -# m4_require(BAR) simply checks whether _m4_expanding(BAR) is defined. - - -# m4_expansion_stack_push(TEXT) -# ----------------------------- -m4_define([m4_expansion_stack_push], -[m4_pushdef([m4_expansion_stack], - [$1]m4_ifdef([m4_expansion_stack], [ -_m4_defn([m4_expansion_stack])]))]) - - -# m4_expansion_stack_pop -# ---------------------- -m4_define([m4_expansion_stack_pop], -[m4_popdef([m4_expansion_stack])]) - - -# m4_expansion_stack_dump -# ----------------------- -# Dump the expansion stack. -m4_define([m4_expansion_stack_dump], -[m4_ifdef([m4_expansion_stack], - [m4_errprintn(_m4_defn([m4_expansion_stack]))])dnl -m4_errprintn(m4_location[: the top level])]) - - -# _m4_divert(GROW) -# ---------------- -# This diversion is used by the m4_defun/m4_require machinery. It is -# important to keep room before GROW because for each nested -# AC_REQUIRE we use an additional diversion (i.e., two m4_require's -# will use GROW - 2. More than 3 levels has never seemed to be -# needed.) -# -# ... -# - GROW - 2 -# m4_require'd code, 2 level deep -# - GROW - 1 -# m4_require'd code, 1 level deep -# - GROW -# m4_defun'd macros are elaborated here. - -m4_define([_m4_divert(GROW)], 10000) - - -# _m4_defun_pro(MACRO-NAME) -# ------------------------- -# The prologue for Autoconf macros. -# -# This is called frequently, so minimize the number of macro invocations -# by avoiding dnl and m4_defn overhead. -m4_define([_m4_defun_pro], -m4_do([[m4_ifdef([m4_expansion_stack], [], [_m4_defun_pro_outer[]])]], - [[m4_expansion_stack_push(_m4_defn( - [m4_location($1)])[: $1 is expanded from...])]], - [[m4_pushdef([_m4_expanding($1)])]])) - -m4_define([_m4_defun_pro_outer], -[m4_copy([_m4_divert_diversion], [_m4_divert_dump])m4_divert_push([GROW])]) - -# _m4_defun_epi(MACRO-NAME) -# ------------------------- -# The Epilogue for Autoconf macros. MACRO-NAME only helps tracing -# the PRO/EPI pairs. -# -# This is called frequently, so minimize the number of macro invocations -# by avoiding dnl and m4_popdef overhead. -m4_define([_m4_defun_epi], -m4_do([[_m4_popdef([_m4_expanding($1)])]], - [[m4_expansion_stack_pop()]], - [[m4_ifdef([m4_expansion_stack], [], [_m4_defun_epi_outer[]])]], - [[m4_provide([$1])]])) - -m4_define([_m4_defun_epi_outer], -[_m4_undefine([_m4_divert_dump])m4_divert_pop([GROW])m4_undivert([GROW])]) - - -# m4_defun(NAME, EXPANSION) -# ------------------------- -# Define a macro which automatically provides itself. Add machinery -# so the macro automatically switches expansion to the diversion -# stack if it is not already using it. In this case, once finished, -# it will bring back all the code accumulated in the diversion stack. -# This, combined with m4_require, achieves the topological ordering of -# macros. We don't use this macro to define some frequently called -# macros that are not involved in ordering constraints, to save m4 -# processing. -m4_define([m4_defun], -[m4_define([m4_location($1)], m4_location)dnl -m4_define([$1], - [_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])])]) - - -# m4_defun_once(NAME, EXPANSION) -# ------------------------------ -# As m4_defun, but issues the EXPANSION only once, and warns if used -# several times. -m4_define([m4_defun_once], -[m4_define([m4_location($1)], m4_location)dnl -m4_define([$1], - [m4_provide_if([$1], - [m4_warn([syntax], [$1 invoked multiple times])], - [_m4_defun_pro([$1])$2[]_m4_defun_epi([$1])])])]) - - -# m4_pattern_forbid(ERE, [WHY]) -# ----------------------------- -# Declare that no token matching the forbidden extended regular -# expression ERE should be seen in the output unless... -m4_define([m4_pattern_forbid], []) - - -# m4_pattern_allow(ERE) -# --------------------- -# ... that token also matches the allowed extended regular expression ERE. -# Both used via traces. -m4_define([m4_pattern_allow], []) - - -## --------------------------------- ## -## 11. Dependencies between macros. ## -## --------------------------------- ## - - -# m4_before(THIS-MACRO-NAME, CALLED-MACRO-NAME) -# --------------------------------------------- -# Issue a warning if CALLED-MACRO-NAME was called before THIS-MACRO-NAME. -m4_define([m4_before], -[m4_provide_if([$2], - [m4_warn([syntax], [$2 was called before $1])])]) - - -# m4_require(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK]) -# ----------------------------------------------------------- -# If NAME-TO-CHECK has never been expanded (actually, if it is not -# m4_provide'd), expand BODY-TO-EXPAND *before* the current macro -# expansion. Once expanded, emit it in _m4_divert_dump. Keep track -# of the m4_require chain in m4_expansion_stack. -# -# The normal cases are: -# -# - NAME-TO-CHECK == BODY-TO-EXPAND -# Which you can use for regular macros with or without arguments, e.g., -# m4_require([AC_PROG_CC], [AC_PROG_CC]) -# m4_require([AC_CHECK_HEADERS(limits.h)], [AC_CHECK_HEADERS(limits.h)]) -# which is just the same as -# m4_require([AC_PROG_CC]) -# m4_require([AC_CHECK_HEADERS(limits.h)]) -# -# - BODY-TO-EXPAND == m4_indir([NAME-TO-CHECK]) -# In the case of macros with irregular names. For instance: -# m4_require([AC_LANG_COMPILER(C)], [indir([AC_LANG_COMPILER(C)])]) -# which means `if the macro named `AC_LANG_COMPILER(C)' (the parens are -# part of the name, it is not an argument) has not been run, then -# call it.' -# Had you used -# m4_require([AC_LANG_COMPILER(C)], [AC_LANG_COMPILER(C)]) -# then m4_require would have tried to expand `AC_LANG_COMPILER(C)', i.e., -# call the macro `AC_LANG_COMPILER' with `C' as argument. -# -# You could argue that `AC_LANG_COMPILER', when it receives an argument -# such as `C' should dispatch the call to `AC_LANG_COMPILER(C)'. But this -# `extension' prevents `AC_LANG_COMPILER' from having actual arguments that -# it passes to `AC_LANG_COMPILER(C)'. -# -# This is called frequently, so minimize the number of macro invocations -# by avoiding dnl and other overhead on the common path. -m4_define([m4_require], -m4_do([[m4_ifdef([_m4_expanding($1)], - [m4_fatal([$0: circular dependency of $1])])]], - [[m4_ifdef([_m4_divert_dump], [], - [m4_fatal([$0($1): cannot be used outside of an ]dnl -m4_bmatch([$0], [^AC_], [[AC_DEFUN]], [[m4_defun]])['d macro])])]], - [[m4_provide_if([$1], - [], - [_m4_require_call([$1], [$2])])]])) - - -# _m4_require_call(NAME-TO-CHECK, [BODY-TO-EXPAND = NAME-TO-CHECK]) -# ----------------------------------------------------------------- -# If m4_require decides to expand the body, it calls this macro. -# -# This is called frequently, so minimize the number of macro invocations -# by avoiding dnl and other overhead on the common path. -m4_define([_m4_require_call], -m4_do([[m4_define([_m4_divert_grow], m4_decr(_m4_divert_grow))]], - [[m4_divert_push(_m4_divert_grow)]], - [[m4_default([$2], [$1]) -m4_provide_if([$1], - [], - [m4_warn([syntax], - [$1 is m4_require'd but not m4_defun'd])])]], - [[m4_divert(_m4_defn([_m4_divert_dump]))]], - [[m4_undivert(_m4_divert_grow)]], - [[m4_divert_pop(_m4_divert_grow)]], - [[m4_define([_m4_divert_grow], m4_incr(_m4_divert_grow))]])) - - -# _m4_divert_grow -# --------------- -# The counter for _m4_require_call. -m4_define([_m4_divert_grow], _m4_divert([GROW])) - - -# m4_expand_once(TEXT, [WITNESS = TEXT]) -# -------------------------------------- -# If TEXT has never been expanded, expand it *here*. Use WITNESS as -# as a memory that TEXT has already been expanded. -m4_define([m4_expand_once], -[m4_provide_if(m4_ifval([$2], [[$2]], [[$1]]), - [], - [m4_provide(m4_ifval([$2], [[$2]], [[$1]]))[]$1])]) - - -# m4_provide(MACRO-NAME) -# ---------------------- -m4_define([m4_provide], -[m4_define([m4_provide($1)])]) - - -# m4_provide_if(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) -# ------------------------------------------------------- -# If MACRO-NAME is provided do IF-PROVIDED, else IF-NOT-PROVIDED. -# The purpose of this macro is to provide the user with a means to -# check macros which are provided without letting her know how the -# information is coded. -m4_define([m4_provide_if], -[m4_ifdef([m4_provide($1)], - [$2], [$3])]) - - -## --------------------- ## -## 12. Text processing. ## -## --------------------- ## - - -# m4_cr_letters -# m4_cr_LETTERS -# m4_cr_Letters -# ------------- -m4_define([m4_cr_letters], [abcdefghijklmnopqrstuvwxyz]) -m4_define([m4_cr_LETTERS], [ABCDEFGHIJKLMNOPQRSTUVWXYZ]) -m4_define([m4_cr_Letters], -m4_defn([m4_cr_letters])dnl -m4_defn([m4_cr_LETTERS])dnl -) - - -# m4_cr_digits -# ------------ -m4_define([m4_cr_digits], [0123456789]) - - -# m4_cr_alnum -# ----------- -m4_define([m4_cr_alnum], -m4_defn([m4_cr_Letters])dnl -m4_defn([m4_cr_digits])dnl -) - - -# m4_cr_symbols1 -# m4_cr_symbols2 -# ------------------------------- -m4_define([m4_cr_symbols1], -m4_defn([m4_cr_Letters])dnl -_) - -m4_define([m4_cr_symbols2], -m4_defn([m4_cr_symbols1])dnl -m4_defn([m4_cr_digits])dnl -) - -# m4_cr_all -# --------- -# The character range representing everything, with `-' as the last -# character, since it is special to m4_translit. Use with care, because -# it contains characters special to M4 (fortunately, both ASCII and EBCDIC -# have [] in order, so m4_defn([m4_cr_all]) remains a valid string). It -# also contains characters special to terminals, so it should never be -# displayed in an error message. Also, attempts to map [ and ] to other -# characters via m4_translit must deal with the fact that m4_translit does -# not add quotes to the output. -# -# It is mainly useful in generating inverted character range maps, for use -# in places where m4_translit is faster than an equivalent m4_bpatsubst; -# the regex `[^a-z]' is equivalent to: -# m4_translit(m4_dquote(m4_defn([m4_cr_all])), [a-z]) -m4_define([m4_cr_all], -m4_translit(m4_dquote(m4_format(m4_dquote(m4_for( - ,1,255,,[[%c]]))m4_for([i],1,255,,[,i]))), [-])-) - - -# _m4_define_cr_not(CATEGORY) -# --------------------------- -# Define m4_cr_not_CATEGORY as the inverse of m4_cr_CATEGORY. -m4_define([_m4_define_cr_not], -[m4_define([m4_cr_not_$1], - m4_translit(m4_dquote(m4_defn([m4_cr_all])), - m4_defn([m4_cr_$1])))]) - - -# m4_cr_not_letters -# m4_cr_not_LETTERS -# m4_cr_not_Letters -# m4_cr_not_digits -# m4_cr_not_alnum -# m4_cr_not_symbols1 -# m4_cr_not_symbols2 -# ------------------ -# Inverse character sets -_m4_define_cr_not([letters]) -_m4_define_cr_not([LETTERS]) -_m4_define_cr_not([Letters]) -_m4_define_cr_not([digits]) -_m4_define_cr_not([alnum]) -_m4_define_cr_not([symbols1]) -_m4_define_cr_not([symbols2]) - - -# m4_newline -# ---------- -# Expands to a newline. Exists for formatting reasons. -m4_define([m4_newline], [ -]) - - -# m4_re_escape(STRING) -# -------------------- -# Escape RE active characters in STRING. -m4_define([m4_re_escape], -[m4_bpatsubst([$1], - [[][*+.?\^$]], [\\\&])]) - - -# m4_re_string -# ------------ -# Regexp for `[a-zA-Z_0-9]*' -# m4_dquote provides literal [] for the character class. -m4_define([m4_re_string], -m4_dquote(m4_defn([m4_cr_symbols2]))dnl -[*]dnl -) - - -# m4_re_word -# ---------- -# Regexp for `[a-zA-Z_][a-zA-Z_0-9]*' -m4_define([m4_re_word], -m4_dquote(m4_defn([m4_cr_symbols1]))dnl -m4_defn([m4_re_string])dnl -) - - -# m4_tolower(STRING) -# m4_toupper(STRING) -# ------------------ -# These macros convert STRING to lowercase or uppercase. -# -# Rather than expand the m4_defn each time, we inline them up front. -m4_define([m4_tolower], -[m4_translit([$1], ]m4_dquote(m4_defn([m4_cr_LETTERS]))[, - ]m4_dquote(m4_defn([m4_cr_letters]))[)]) -m4_define([m4_toupper], -[m4_translit([$1], ]m4_dquote(m4_defn([m4_cr_letters]))[, - ]m4_dquote(m4_defn([m4_cr_LETTERS]))[)]) - - -# m4_split(STRING, [REGEXP]) -# -------------------------- -# -# Split STRING into an m4 list of quoted elements. The elements are -# quoted with [ and ]. Beginning spaces and end spaces *are kept*. -# Use m4_strip to remove them. -# -# REGEXP specifies where to split. Default is [\t ]+. -# -# If STRING is empty, the result is an empty list. -# -# Pay attention to the m4_changequotes. When m4 reads the definition of -# m4_split, it still has quotes set to [ and ]. Luckily, these are matched -# in the macro body, so the definition is stored correctly. Use the same -# alternate quotes as m4_noquote; it must be unlikely to appear in $1. -# -# Also, notice that $1 is quoted twice, since we want the result to -# be quoted. Then you should understand that the argument of -# patsubst is -=<{(STRING)}>=- (i.e., with additional -=<{( and )}>=-). -# -# This macro is safe on active symbols, i.e.: -# m4_define(active, ACTIVE) -# m4_split([active active ])end -# => [active], [active], []end -# -# Optimize on regex of ` ' (space), since m4_foreach_w already guarantees -# that the list contains single space separators, and a common case is -# splitting a single-element list. This macro is called frequently, -# so avoid unnecessary dnl inside the definition. -m4_define([m4_split], -[m4_if([$1], [], [], - [$2], [ ], [m4_if(m4_index([$1], [ ]), [-1], [[[$1]]], [_$0($@)])], - [$2], [], [_$0([$1], [[ ]+])], - [_$0($@)])]) - -m4_define([_m4_split], -[m4_changequote([-=<{(],[)}>=-])]dnl -[[m4_bpatsubst(-=<{(-=<{($1)}>=-)}>=-, -=<{($2)}>=-, - -=<{(], [)}>=-)]m4_changequote([, ])]) - - - -# m4_flatten(STRING) -# ------------------ -# If STRING contains end of lines, replace them with spaces. If there -# are backslashed end of lines, remove them. This macro is safe with -# active symbols. -# m4_define(active, ACTIVE) -# m4_flatten([active -# act\ -# ive])end -# => active activeend -# -# In m4, m4_bpatsubst is expensive, so first check for a newline. -m4_define([m4_flatten], -[m4_if(m4_index([$1], [ -]), [-1], [[$1]], - [m4_translit(m4_bpatsubst([[[$1]]], [\\ -]), [ -], [ ])])]) - - -# m4_strip(STRING) -# ---------------- -# Expands into STRING with tabs and spaces singled out into a single -# space, and removing leading and trailing spaces. -# -# This macro is robust to active symbols. -# m4_define(active, ACTIVE) -# m4_strip([ active active ])end -# => active activeend -# -# First, notice that we guarantee trailing space. Why? Because regular -# expressions are greedy, and `.* ?' would always group the space into the -# .* portion. The algorithm is simpler by avoiding `?' at the end. The -# algorithm correctly strips everything if STRING is just ` '. -# -# Then notice the second pattern: it is in charge of removing the -# leading/trailing spaces. Why not just `[^ ]'? Because they are -# applied to over-quoted strings, i.e. more or less [STRING], due -# to the limitations of m4_bpatsubsts. So the leading space in STRING -# is the *second* character; equally for the trailing space. -m4_define([m4_strip], -[m4_bpatsubsts([$1 ], - [[ ]+], [ ], - [^. ?\(.*\) .$], [[[\1]]])]) - - -# m4_normalize(STRING) -# -------------------- -# Apply m4_flatten and m4_strip to STRING. -# -# The argument is quoted, so that the macro is robust to active symbols: -# -# m4_define(active, ACTIVE) -# m4_normalize([ act\ -# ive -# active ])end -# => active activeend - -m4_define([m4_normalize], -[m4_strip(m4_flatten([$1]))]) - - - -# m4_join(SEP, ARG1, ARG2...) -# --------------------------- -# Produce ARG1SEPARG2...SEPARGn. Avoid back-to-back SEP when a given ARG -# is the empty string. No expansion is performed on SEP or ARGs. -# -# Since the number of arguments to join can be arbitrarily long, we -# want to avoid having more than one $@ in the macro definition; -# otherwise, the expansion would require twice the memory of the already -# long list. Hence, m4_join merely looks for the first non-empty element, -# and outputs just that element; while _m4_join looks for all non-empty -# elements, and outputs them following a separator. The final trick to -# note is that we decide between recursing with $0 or _$0 based on the -# nested m4_if ending with `_'. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_join], -[m4_if([$#], [1], [], - [$#], [2], [[$2]], - [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift2($@))])]) -m4_define([_m4_join], -[m4_if([$#$2], [2], [], - [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift2($@))])]) - -# m4_joinall(SEP, ARG1, ARG2...) -# ------------------------------ -# Produce ARG1SEPARG2...SEPARGn. An empty ARG results in back-to-back SEP. -# No expansion is performed on SEP or ARGs. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_joinall], [[$2]_$0([$1], m4_shift($@))]) -m4_define([_m4_joinall], -[m4_if([$#], [2], [], [[$1$3]$0([$1], m4_shift2($@))])]) - -# m4_combine([SEPARATOR], PREFIX-LIST, [INFIX], SUFFIX...) -# -------------------------------------------------------- -# Produce the pairwise combination of every element in the quoted, -# comma-separated PREFIX-LIST with every element from the SUFFIX arguments. -# Each pair is joined with INFIX, and pairs are separated by SEPARATOR. -# No expansion occurs on SEPARATOR, INFIX, or elements of either list. -# -# For example: -# m4_combine([, ], [[a], [b], [c]], [-], [1], [2], [3]) -# => a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3 -# -# In order to have the correct number of SEPARATORs, we use a temporary -# variable that redefines itself after the first use. We must use defn -# rather than overquoting in case PREFIX or SUFFIX contains $1, but use -# _m4_defn for speed. Likewise, we compute the m4_shift3 only once, -# rather than in each iteration of the outer m4_foreach. -m4_define([m4_combine], -[m4_if(m4_eval([$# > 3]), [1], - [m4_pushdef([m4_Separator], [m4_define([m4_Separator], - _m4_defn([m4_echo]))])]]dnl -[[m4_foreach([m4_Prefix], [$2], - [m4_foreach([m4_Suffix], ]m4_dquote(m4_dquote(m4_shift3($@)))[, - [m4_Separator([$1])[]_m4_defn([m4_Prefix])[$3]_m4_defn( - [m4_Suffix])])])]]dnl -[[_m4_popdef([m4_Separator])])]) - - -# m4_append(MACRO-NAME, STRING, [SEPARATOR]) -# ------------------------------------------ -# Redefine MACRO-NAME to hold its former content plus `SEPARATOR`'STRING' -# at the end. It is valid to use this macro with MACRO-NAME undefined, -# in which case no SEPARATOR is added. Be aware that the criterion is -# `not being defined', and not `not being empty'. -# -# Note that neither STRING nor SEPARATOR are expanded here; rather, when -# you expand MACRO-NAME, they will be expanded at that point in time. -# -# This macro is robust to active symbols. It can be used to grow -# strings. -# -# | m4_define(active, ACTIVE)dnl -# | m4_append([sentence], [This is an])dnl -# | m4_append([sentence], [ active ])dnl -# | m4_append([sentence], [symbol.])dnl -# | sentence -# | m4_undefine([active])dnl -# | sentence -# => This is an ACTIVE symbol. -# => This is an active symbol. -# -# It can be used to define hooks. -# -# | m4_define(active, ACTIVE)dnl -# | m4_append([hooks], [m4_define([act1], [act2])])dnl -# | m4_append([hooks], [m4_define([act2], [active])])dnl -# | m4_undefine([active])dnl -# | act1 -# | hooks -# | act1 -# => act1 -# => -# => active -# -# It can also be used to create lists, although this particular usage was -# broken prior to autoconf 2.62. -# | m4_append([list], [one], [, ])dnl -# | m4_append([list], [two], [, ])dnl -# | m4_append([list], [three], [, ])dnl -# | list -# | m4_dquote(list) -# => one, two, three -# => [one],[two],[three] -# -# Note that m4_append can benefit from amortized O(n) m4 behavior, if -# the underlying m4 implementation is smart enough to avoid copying existing -# contents when enlarging a macro's definition into any pre-allocated storage -# (m4 1.4.x unfortunately does not implement this optimization). We do -# not implement m4_prepend, since it is inherently O(n^2) (pre-allocated -# storage only occurs at the end of a macro, so the existing contents must -# always be moved). -# -# Use _m4_defn for speed. -m4_define([m4_append], -[m4_define([$1], m4_ifdef([$1], [_m4_defn([$1])[$3]])[$2])]) - - -# m4_append_uniq(MACRO-NAME, STRING, [SEPARATOR], [IF-UNIQ], [IF-DUP]) -# -------------------------------------------------------------------- -# Like `m4_append', but append only if not yet present. Additionally, -# expand IF-UNIQ if STRING was appended, or IF-DUP if STRING was already -# present. Also, warn if SEPARATOR is not empty and occurs within STRING, -# as the algorithm no longer guarantees uniqueness. -# -# Note that while m4_append can be O(n) (depending on the quality of the -# underlying M4 implementation), m4_append_uniq is inherently O(n^2) -# because each append operation searches the entire string. -m4_define([m4_append_uniq], -[m4_ifval([$3], [m4_if(m4_index([$2], [$3]), [-1], [], - [m4_warn([syntax], - [$0: `$2' contains `$3'])])])_$0($@)]) -m4_define([_m4_append_uniq], -[m4_ifdef([$1], - [m4_if(m4_index([$3]_m4_defn([$1])[$3], [$3$2$3]), [-1], - [m4_append([$1], [$2], [$3])$4], [$5])], - [m4_define([$1], [$2])$4])]) - -# m4_append_uniq_w(MACRO-NAME, STRINGS) -# ------------------------------------- -# For each of the words in the whitespace separated list STRINGS, append -# only the unique strings to the definition of MACRO-NAME. -# -# Use _m4_defn for speed. -m4_define([m4_append_uniq_w], -[m4_foreach_w([m4_Word], [$2], - [_m4_append_uniq([$1], _m4_defn([m4_Word]), [ ])])]) - - -# m4_text_wrap(STRING, [PREFIX], [FIRST-PREFIX], [WIDTH]) -# ------------------------------------------------------- -# Expands into STRING wrapped to hold in WIDTH columns (default = 79). -# If PREFIX is given, each line is prefixed with it. If FIRST-PREFIX is -# specified, then the first line is prefixed with it. As a special case, -# if the length of FIRST-PREFIX is greater than that of PREFIX, then -# FIRST-PREFIX will be left alone on the first line. -# -# No expansion occurs on the contents STRING, PREFIX, or FIRST-PREFIX, -# although quadrigraphs are correctly recognized. -# -# Typical outputs are: -# -# m4_text_wrap([Short string */], [ ], [/* ], 20) -# => /* Short string */ -# -# m4_text_wrap([Much longer string */], [ ], [/* ], 20) -# => /* Much longer -# => string */ -# -# m4_text_wrap([Short doc.], [ ], [ --short ], 30) -# => --short Short doc. -# -# m4_text_wrap([Short doc.], [ ], [ --too-wide ], 30) -# => --too-wide -# => Short doc. -# -# m4_text_wrap([Super long documentation.], [ ], [ --too-wide ], 30) -# => --too-wide -# => Super long -# => documentation. -# -# FIXME: there is no checking of a longer PREFIX than WIDTH, but do -# we really want to bother with people trying each single corner -# of a software? -# -# This macro does not leave a trailing space behind the last word of a line, -# which complicates it a bit. The algorithm is otherwise stupid and simple: -# all the words are preceded by m4_Separator which is defined to empty for -# the first word, and then ` ' (single space) for all the others. -# -# The algorithm uses a helper that uses $2 through $4 directly, rather than -# using local variables, to avoid m4_defn overhead, or expansion swallowing -# any $. It also bypasses m4_popdef overhead with _m4_popdef since no user -# macro expansion occurs in the meantime. Also, the definition is written -# with m4_do, to avoid time wasted on dnl during expansion (since this is -# already a time-consuming macro). -m4_define([m4_text_wrap], -[_$0([$1], [$2], m4_if([$3], [], [[$2]], [[$3]]), - m4_if([$4], [], [79], [[$4]]))]) -m4_define([_m4_text_wrap], -m4_do(dnl set up local variables, to avoid repeated calculations -[[m4_pushdef([m4_Indent], m4_qlen([$2]))]], -[[m4_pushdef([m4_Cursor], m4_qlen([$3]))]], -[[m4_pushdef([m4_Separator], [m4_define([m4_Separator], [ ])])]], -dnl expand the first prefix, then check its length vs. regular prefix -dnl same length: nothing special -dnl prefix1 longer: output on line by itself, and reset cursor -dnl prefix1 shorter: pad to length of prefix, and reset cursor -[[[$3]m4_cond([m4_Cursor], m4_Indent, [], - [m4_eval(m4_Cursor > m4_Indent)], [1], [ -[$2]m4_define([m4_Cursor], m4_Indent)], - [m4_format([%*s], m4_max([0], - m4_eval(m4_Indent - m4_Cursor)), [])m4_define([m4_Cursor], m4_Indent)])]], -dnl now, for each word, compute the curser after the word is output, then -dnl check if the cursor would exceed the wrap column -dnl if so, reset cursor, and insert newline and prefix -dnl if not, insert the separator (usually a space) -dnl either way, insert the word -[[m4_foreach_w([m4_Word], [$1], - [m4_define([m4_Cursor], - m4_eval(m4_Cursor + m4_qlen(_m4_defn([m4_Word])) - + 1))m4_if(m4_eval(m4_Cursor > ([$4])), - [1], [m4_define([m4_Cursor], - m4_eval(m4_Indent + m4_qlen(_m4_defn([m4_Word])) + 1)) -[$2]], - [m4_Separator[]])_m4_defn([m4_Word])])]], -dnl finally, clean up the local variabls -[[_m4_popdef([m4_Separator], [m4_Cursor], [m4_Indent])]])) - - -# m4_text_box(MESSAGE, [FRAME-CHARACTER = `-']) -# --------------------------------------------- -# Turn MESSAGE into: -# ## ------- ## -# ## MESSAGE ## -# ## ------- ## -# using FRAME-CHARACTER in the border. -m4_define([m4_text_box], -[m4_pushdef([m4_Border], - m4_translit(m4_format([%*s], m4_qlen(m4_expand([$1])), []), - [ ], m4_if([$2], [], [[-]], [[$2]])))dnl -@%:@@%:@ m4_Border @%:@@%:@ -@%:@@%:@ $1 @%:@@%:@ -@%:@@%:@ m4_Border @%:@@%:@_m4_popdef([m4_Border])dnl -]) - - -# m4_qlen(STRING) -# --------------- -# Expands to the length of STRING after autom4te converts all quadrigraphs. -# -# Avoid bpatsubsts for the common case of no quadrigraphs. -m4_define([m4_qlen], -[m4_if(m4_index([$1], [@]), [-1], [m4_len([$1])], - [m4_len(m4_bpatsubst([[$1]], - [@\(\(<:\|:>\|S|\|%:\|\{:\|:\}\)\(@\)\|&t@\)], - [\3]))])]) - - -# m4_qdelta(STRING) -# ----------------- -# Expands to the net change in the length of STRING from autom4te converting the -# quadrigraphs in STRING. This number is always negative or zero. -m4_define([m4_qdelta], -[m4_eval(m4_qlen([$1]) - m4_len([$1]))]) - - - -## ----------------------- ## -## 13. Number processing. ## -## ----------------------- ## - -# m4_cmp(A, B) -# ------------ -# Compare two integer expressions. -# A < B -> -1 -# A = B -> 0 -# A > B -> 1 -m4_define([m4_cmp], -[m4_eval((([$1]) > ([$2])) - (([$1]) < ([$2])))]) - - -# m4_list_cmp(A, B) -# ----------------- -# -# Compare the two lists of integer expressions A and B. For instance: -# m4_list_cmp([1, 0], [1]) -> 0 -# m4_list_cmp([1, 0], [1, 0]) -> 0 -# m4_list_cmp([1, 2], [1, 0]) -> 1 -# m4_list_cmp([1, 2, 3], [1, 2]) -> 1 -# m4_list_cmp([1, 2, -3], [1, 2]) -> -1 -# m4_list_cmp([1, 0], [1, 2]) -> -1 -# m4_list_cmp([1], [1, 2]) -> -1 -# m4_define([xa], [oops])dnl -# m4_list_cmp([[0xa]], [5+5]) -> 0 -# -# Rather than face the overhead of m4_case, we use a helper function whose -# expansion includes the name of the macro to invoke on the tail, either -# m4_ignore or m4_unquote. This is particularly useful when comparing -# long lists, since less text is being expanded for deciding when to end -# recursion. The recursion is between a pair of macros that alternate -# which list is trimmed by one element; this is more efficient than -# calling m4_cdr on both lists from a single macro. Guarantee exactly -# one expansion of both lists' side effects. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_list_cmp], -[_$0_raw(m4_dquote($1), m4_dquote($2))]) - -m4_define([_m4_list_cmp_raw], -[m4_if([$1], [$2], [0], [_m4_list_cmp_1([$1], $2)])]) - -m4_define([_m4_list_cmp], -[m4_if([$1], [], [0m4_ignore], [$2], [0], [m4_unquote], [$2m4_ignore])]) - -m4_define([_m4_list_cmp_1], -[_m4_list_cmp_2([$2], [m4_shift2($@)], $1)]) - -m4_define([_m4_list_cmp_2], -[_m4_list_cmp([$1$3], m4_cmp([$3+0], [$1+0]))( - [_m4_list_cmp_1(m4_dquote(m4_shift3($@)), $2)])]) - -# m4_max(EXPR, ...) -# m4_min(EXPR, ...) -# ----------------- -# Return the decimal value of the maximum (or minimum) in a series of -# integer expressions. -# -# M4 1.4.x doesn't provide ?:. Hence this huge m4_eval. Avoid m4_eval -# if both arguments are identical, but be aware of m4_max(0xa, 10) (hence -# the use of <=, not just <, in the second multiply). -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_max], -[m4_if([$#], [0], [m4_fatal([too few arguments to $0])], - [$#], [1], [m4_eval([$1])], - [$#$1], [2$2], [m4_eval([$1])], - [$#], [2], [_$0($@)], - [_m4_minmax([_$0], $@)])]) - -m4_define([_m4_max], -[m4_eval((([$1]) > ([$2])) * ([$1]) + (([$1]) <= ([$2])) * ([$2]))]) - -m4_define([m4_min], -[m4_if([$#], [0], [m4_fatal([too few arguments to $0])], - [$#], [1], [m4_eval([$1])], - [$#$1], [2$2], [m4_eval([$1])], - [$#], [2], [_$0($@)], - [_m4_minmax([_$0], $@)])]) - -m4_define([_m4_min], -[m4_eval((([$1]) < ([$2])) * ([$1]) + (([$1]) >= ([$2])) * ([$2]))]) - -# _m4_minmax(METHOD, ARG1, ARG2...) -# --------------------------------- -# Common recursion code for m4_max and m4_min. METHOD must be _m4_max -# or _m4_min, and there must be at least two arguments to combine. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([_m4_minmax], -[m4_if([$#], [3], [$1([$2], [$3])], - [$0([$1], $1([$2], [$3]), m4_shift3($@))])]) - - -# m4_sign(A) -# ---------- -# The sign of the integer expression A. -m4_define([m4_sign], -[m4_eval((([$1]) > 0) - (([$1]) < 0))]) - - - -## ------------------------ ## -## 14. Version processing. ## -## ------------------------ ## - - -# m4_version_unletter(VERSION) -# ---------------------------- -# Normalize beta version numbers with letters to numeric expressions, which -# can then be handed to m4_eval for the purpose of comparison. -# -# Nl -> (N+1).-1.(l#) -# -# for example: -# [2.14a] -> [2.14+1.-1.[0r36:a]] -> 2.15.-1.10 -# [2.14b] -> [2.15+1.-1.[0r36:b]] -> 2.15.-1.11 -# [2.61aa.b] -> [2.61+1.-1.[0r36:aa],+1.-1.[0r36:b]] -> 2.62.-1.370.1.-1.11 -# -# This macro expects reasonable version numbers, but can handle double -# letters and does not expand any macros. Original version strings can -# use both `.' and `-' separators. -# -# Inline constant expansions, to avoid m4_defn overhead. -# _m4_version_unletter is the real workhorse used by m4_version_compare, -# but since [0r36:a] is less readable than 10, we provide a wrapper for -# human use. -m4_define([m4_version_unletter], -[m4_map_sep([m4_eval], [.], - m4_dquote(m4_dquote_elt(m4_unquote(_$0([$1])))))]) -m4_define([_m4_version_unletter], -[m4_bpatsubst(m4_translit([[[$1]]], [.-], [,,]),]dnl -m4_dquote(m4_dquote(m4_defn([m4_cr_Letters])))[[+], - [+1,-1,[0r36:\&]])]) - - -# m4_version_compare(VERSION-1, VERSION-2) -# ---------------------------------------- -# Compare the two version numbers and expand into -# -1 if VERSION-1 < VERSION-2 -# 0 if = -# 1 if > -# -# Since _m4_version_unletter does not output side effects, we can -# safely bypass the overhead of m4_version_cmp. -m4_define([m4_version_compare], -[_m4_list_cmp_raw(_m4_version_unletter([$1]), _m4_version_unletter([$2]))]) - - -# m4_PACKAGE_NAME -# m4_PACKAGE_TARNAME -# m4_PACKAGE_VERSION -# m4_PACKAGE_STRING -# m4_PACKAGE_BUGREPORT -# -------------------- -# If m4sugar/version.m4 is present, then define version strings. This -# file is optional, provided by Autoconf but absent in Bison. -m4_sinclude([m4sugar/version.m4]) - - -# m4_version_prereq(VERSION, [IF-OK], [IF-NOT = FAIL]) -# ---------------------------------------------------- -# Check this Autoconf version against VERSION. -m4_define([m4_version_prereq], -m4_ifdef([m4_PACKAGE_VERSION], -[[m4_if(m4_version_compare(]m4_dquote(m4_defn([m4_PACKAGE_VERSION]))[, [$1]), - [-1], - [m4_default([$3], - [m4_fatal([Autoconf version $1 or higher is required], - [63])])], - [$2])]], -[[m4_fatal([m4sugar/version.m4 not found])]])) - - -## ------------------ ## -## 15. Set handling. ## -## ------------------ ## - -# Autoconf likes to create arbitrarily large sets; for example, as of -# this writing, the configure.ac for coreutils tracks a set of more -# than 400 AC_SUBST. How do we track all of these set members, -# without introducing duplicates? We could use m4_append_uniq, with -# the set NAME residing in the contents of the macro NAME. -# Unfortunately, m4_append_uniq is quadratic for set creation, because -# it costs O(n) to search the string for each of O(n) insertions; not -# to mention that with m4 1.4.x, even using m4_append is slow, costing -# O(n) rather than O(1) per insertion. Other set operations, not used -# by Autoconf but still possible by manipulation of the definition -# tracked in macro NAME, include O(n) deletion of one element and O(n) -# computation of set size. Because the set is exposed to the user via -# the definition of a single macro, we cannot cache any data about the -# set without risking the cache being invalidated by the user -# redefining NAME. -# -# Can we do better? Yes, because m4 gives us an O(1) search function -# for free: ifdef. Additionally, even m4 1.4.x gives us an O(1) -# insert operation for free: pushdef. But to use these, we must -# represent the set via a group of macros; to keep the set consistent, -# we must hide the set so that the user can only manipulate it through -# accessor macros. The contents of the set are maintained through two -# access points; _m4_set([name]) is a pushdef stack of values in the -# set, useful for O(n) traversal of the set contents; while the -# existence of _m4_set([name],value) with no particular value is -# useful for O(1) querying of set membership. And since the user -# cannot externally manipulate the set, we are free to add additional -# caching macros for other performance improvements. Deletion can be -# O(1) per element rather than O(n), by reworking the definition of -# _m4_set([name],value) to be 0 or 1 based on current membership, and -# adding _m4_set_cleanup(name) to defer the O(n) cleanup of -# _m4_set([name]) until we have another reason to do an O(n) -# traversal. The existence of _m4_set_cleanup(name) can then be used -# elsewhere to determine if we must dereference _m4_set([name],value), -# or assume that definition implies set membership. Finally, size can -# be tracked in an O(1) fashion with _m4_set_size(name). -# -# The quoting in _m4_set([name],value) is chosen so that there is no -# ambiguity with a set whose name contains a comma, and so that we can -# supply the value via _m4_defn([_m4_set([name])]) without needing any -# quote manipulation. - -# m4_set_add(SET, VALUE, [IF-UNIQ], [IF-DUP]) -# ------------------------------------------- -# Add VALUE as an element of SET. Expand IF-UNIQ on the first -# addition, and IF-DUP if it is already in the set. Addition of one -# element is O(1), such that overall set creation is O(n). -# -# We do not want to add a duplicate for a previously deleted but -# unpruned element, but it is just as easy to check existence directly -# as it is to query _m4_set_cleanup($1). -m4_define([m4_set_add], -[m4_ifdef([_m4_set([$1],$2)], - [m4_if(m4_indir([_m4_set([$1],$2)]), [0], - [m4_define([_m4_set([$1],$2)], - [1])_m4_set_size([$1], [m4_incr])$3], [$4])], - [m4_define([_m4_set([$1],$2)], - [1])m4_pushdef([_m4_set([$1])], - [$2])_m4_set_size([$1], [m4_incr])$3])]) - -# m4_set_add_all(SET, VALUE...) -# ----------------------------- -# Add each VALUE into SET. This is O(n) in the number of VALUEs, and -# can be faster than calling m4_set_add for each VALUE. -# -# Implement two recursion helpers; the check variant is slower but -# handles the case where an element has previously been removed but -# not pruned. The recursion helpers ignore their second argument, so -# that we can use the faster m4_shift2 and 2 arguments, rather than -# _m4_shift2 and one argument, as the signal to end recursion. -# -# Please keep foreach.m4 in sync with any adjustments made here. -m4_define([m4_set_add_all], -[m4_define([_m4_set_size($1)], m4_eval(m4_set_size([$1]) - + m4_len(m4_ifdef([_m4_set_cleanup($1)], [_$0_check], [_$0])([$1], $@))))]) - -m4_define([_m4_set_add_all], -[m4_if([$#], [2], [], - [m4_ifdef([_m4_set([$1],$3)], [], - [m4_define([_m4_set([$1],$3)], [1])m4_pushdef([_m4_set([$1])], - [$3])-])$0([$1], m4_shift2($@))])]) - -m4_define([_m4_set_add_all_check], -[m4_if([$#], [2], [], - [m4_set_add([$1], [$3])$0([$1], m4_shift2($@))])]) - -# m4_set_contains(SET, VALUE, [IF-PRESENT], [IF-ABSENT]) -# ------------------------------------------------------ -# Expand IF-PRESENT if SET contains VALUE, otherwise expand IF-ABSENT. -# This is always O(1). -m4_define([m4_set_contains], -[m4_ifdef([_m4_set_cleanup($1)], - [m4_if(m4_ifdef([_m4_set([$1],$2)], - [m4_indir([_m4_set([$1],$2)])], [0]), [1], [$3], [$4])], - [m4_ifdef([_m4_set([$1],$2)], [$3], [$4])])]) - -# m4_set_contents(SET, [SEP]) -# --------------------------- -# Expand to a single string containing all the elements in SET, -# separated by SEP, without modifying SET. No provision is made for -# disambiguating set elements that contain non-empty SEP as a -# sub-string, or for recognizing a set that contains only the empty -# string. Order of the output is not guaranteed. If any elements -# have been previously removed from the set, this action will prune -# the unused memory. This is O(n) in the size of the set before -# pruning. -# -# Use _m4_popdef for speed. The existence of _m4_set_cleanup($1) -# determines which version of _1 helper we use. -m4_define([m4_set_contents], -[m4_ifdef([_m4_set_cleanup($1)], [_$0_1c], [_$0_1])([$1])_$0_2([$1], - [_m4_defn([_m4_set_($1)])], [[$2]])]) - -# _m4_set_contents_1(SET) -# _m4_set_contents_1c(SET) -# _m4_set_contents_2(SET, SEP, PREP) -# ---------------------------------- -# Expand to a list of quoted elements currently in the set, separated -# by SEP, and moving PREP in front of SEP on recursion. To avoid -# nesting limit restrictions, the algorithm must be broken into two -# parts; _1 destructively copies the stack in reverse into -# _m4_set_($1), producing no output; then _2 destructively copies -# _m4_set_($1) back into the stack in reverse. SEP is expanded while -# _m4_set_($1) contains the current element, so a SEP containing -# _m4_defn([_m4_set_($1)]) can produce output in the order the set was -# created. Behavior is undefined if SEP tries to recursively list or -# modify SET in any way other than calling m4_set_remove on the -# current element. Use _1 if all entries in the stack are guaranteed -# to be in the set, and _1c to prune removed entries. Uses _m4_defn -# and _m4_popdef for speed. -m4_define([_m4_set_contents_1], -[m4_ifdef([_m4_set([$1])], [m4_pushdef([_m4_set_($1)], - _m4_defn([_m4_set([$1])]))_m4_popdef([_m4_set([$1])])$0([$1])])]) - -m4_define([_m4_set_contents_1c], -[m4_ifdef([_m4_set([$1])], - [m4_set_contains([$1], _m4_defn([_m4_set([$1])]), - [m4_pushdef([_m4_set_($1)], _m4_defn([_m4_set([$1])]))], - [_m4_popdef([_m4_set([$1],]_m4_defn( - [_m4_set([$1])])[)])])_m4_popdef([_m4_set([$1])])$0([$1])], - [_m4_popdef([_m4_set_cleanup($1)])])]) - -m4_define([_m4_set_contents_2], -[m4_ifdef([_m4_set_($1)], [m4_pushdef([_m4_set([$1])], - _m4_defn([_m4_set_($1)]))$2[]_m4_popdef([_m4_set_($1)])$0([$1], [$3$2])])]) - -# m4_set_delete(SET) -# ------------------ -# Delete all elements in SET, and reclaim any memory occupied by the -# set. This is O(n) in the set size. -# -# Use _m4_defn and _m4_popdef for speed. -m4_define([m4_set_delete], -[m4_ifdef([_m4_set([$1])], - [_m4_popdef([_m4_set([$1],]_m4_defn([_m4_set([$1])])[)], - [_m4_set([$1])])$0([$1])], - [m4_ifdef([_m4_set_cleanup($1)], - [_m4_popdef([_m4_set_cleanup($1)])])m4_ifdef( - [_m4_set_size($1)], - [_m4_popdef([_m4_set_size($1)])])])]) - -# m4_set_difference(SET1, SET2) -# ----------------------------- -# Produce a LIST of quoted elements that occur in SET1 but not SET2. -# Output a comma prior to any elements, to distinguish the empty -# string from no elements. This can be directly used as a series of -# arguments, such as for m4_join, or wrapped inside quotes for use in -# m4_foreach. Order of the output is not guaranteed. -# -# Short-circuit the idempotence relation. Use _m4_defn for speed. -m4_define([m4_set_difference], -[m4_if([$1], [$2], [], - [m4_set_foreach([$1], [_m4_element], - [m4_set_contains([$2], _m4_defn([_m4_element]), [], - [,_m4_defn([_m4_element])])])])]) - -# m4_set_dump(SET, [SEP]) -# ----------------------- -# Expand to a single string containing all the elements in SET, -# separated by SEP, then delete SET. In general, if you only need to -# list the contents once, this is faster than m4_set_contents. No -# provision is made for disambiguating set elements that contain -# non-empty SEP as a sub-string. Order of the output is not -# guaranteed. This is O(n) in the size of the set before pruning. -# -# Use _m4_popdef for speed. Use existence of _m4_set_cleanup($1) to -# decide if more expensive recursion is needed. -m4_define([m4_set_dump], -[m4_ifdef([_m4_set_size($1)], - [_m4_popdef([_m4_set_size($1)])])m4_ifdef([_m4_set_cleanup($1)], - [_$0_check], [_$0])([$1], [], [$2])]) - -# _m4_set_dump(SET, SEP, PREP) -# _m4_set_dump_check(SET, SEP, PREP) -# ---------------------------------- -# Print SEP and the current element, then delete the element and -# recurse with empty SEP changed to PREP. The check variant checks -# whether the element has been previously removed. Use _m4_defn and -# _m4_popdef for speed. -m4_define([_m4_set_dump], -[m4_ifdef([_m4_set([$1])], - [[$2]_m4_defn([_m4_set([$1])])_m4_popdef([_m4_set([$1],]_m4_defn( - [_m4_set([$1])])[)], [_m4_set([$1])])$0([$1], [$2$3])])]) - -m4_define([_m4_set_dump_check], -[m4_ifdef([_m4_set([$1])], - [m4_set_contains([$1], _m4_defn([_m4_set([$1])]), - [[$2]_m4_defn([_m4_set([$1])])])_m4_popdef( - [_m4_set([$1],]_m4_defn([_m4_set([$1])])[)], - [_m4_set([$1])])$0([$1], [$2$3])], - [_m4_popdef([_m4_set_cleanup($1)])])]) - -# m4_set_empty(SET, [IF-EMPTY], [IF-ELEMENTS]) -# -------------------------------------------- -# Expand IF-EMPTY if SET has no elements, otherwise IF-ELEMENTS. -m4_define([m4_set_empty], -[m4_ifdef([_m4_set_size($1)], - [m4_if(m4_indir([_m4_set_size($1)]), [0], [$2], [$3])], [$2])]) - -# m4_set_foreach(SET, VAR, ACTION) -# -------------------------------- -# For each element of SET, define VAR to the element and expand -# ACTION. ACTION should not recursively list SET's contents, add -# elements to SET, nor delete any element from SET except the one -# currently in VAR. The order that the elements are visited in is not -# guaranteed. This is faster than the corresponding m4_foreach([VAR], -# m4_indir([m4_dquote]m4_set_listc([SET])), [ACTION]) -m4_define([m4_set_foreach], -[m4_pushdef([$2])m4_ifdef([_m4_set_cleanup($1)], - [_m4_set_contents_1c], [_m4_set_contents_1])([$1])_m4_set_contents_2([$1], - [m4_define([$2], _m4_defn([_m4_set_($1)]))$3[]])m4_popdef([$2])]) - -# m4_set_intersection(SET1, SET2) -# ------------------------------- -# Produce a LIST of quoted elements that occur in both SET1 or SET2. -# Output a comma prior to any elements, to distinguish the empty -# string from no elements. This can be directly used as a series of -# arguments, such as for m4_join, or wrapped inside quotes for use in -# m4_foreach. Order of the output is not guaranteed. -# -# Iterate over the smaller set, and short-circuit the idempotence -# relation. Use _m4_defn for speed. -m4_define([m4_set_intersection], -[m4_if([$1], [$2], [m4_set_listc([$1])], - m4_eval(m4_set_size([$2]) < m4_set_size([$1])), [1], [$0([$2], [$1])], - [m4_set_foreach([$1], [_m4_element], - [m4_set_contains([$2], _m4_defn([_m4_element]), - [,_m4_defn([_m4_element])])])])]) - -# m4_set_list(SET) -# m4_set_listc(SET) -# ----------------- -# Produce a LIST of quoted elements of SET. This can be directly used -# as a series of arguments, such as for m4_join or m4_set_add_all, or -# wrapped inside quotes for use in m4_foreach or m4_map. With -# m4_set_list, there is no way to distinguish an empty set from a set -# containing only the empty string; with m4_set_listc, a leading comma -# is output if there are any elements. -m4_define([m4_set_list], -[m4_ifdef([_m4_set_cleanup($1)], [_m4_set_contents_1c], - [_m4_set_contents_1])([$1])_m4_set_contents_2([$1], - [_m4_defn([_m4_set_($1)])], [,])]) - -m4_define([m4_set_listc], -[m4_ifdef([_m4_set_cleanup($1)], [_m4_set_contents_1c], - [_m4_set_contents_1])([$1])_m4_set_contents_2([$1], - [,_m4_defn([_m4_set_($1)])])]) - -# m4_set_remove(SET, VALUE, [IF-PRESENT], [IF-ABSENT]) -# ---------------------------------------------------- -# If VALUE is an element of SET, delete it and expand IF-PRESENT. -# Otherwise expand IF-ABSENT. Deleting a single value is O(1), -# although it leaves memory occupied until the next O(n) traversal of -# the set which will compact the set. -# -# Optimize if the element being removed is the most recently added, -# since defining _m4_set_cleanup($1) slows down so many other macros. -# In particular, this plays well with m4_set_foreach. -m4_define([m4_set_remove], -[m4_set_contains([$1], [$2], [_m4_set_size([$1], - [m4_decr])m4_if(_m4_defn([_m4_set([$1])]), [$2], - [_m4_popdef([_m4_set([$1],$2)], [_m4_set([$1])])], - [m4_define([_m4_set_cleanup($1)])m4_define( - [_m4_set([$1],$2)], [0])])$3], [$4])]) - -# m4_set_size(SET) -# ---------------- -# Expand to the number of elements currently in SET. This operation -# is O(1), and thus more efficient than m4_count(m4_set_list([SET])). -m4_define([m4_set_size], -[m4_ifdef([_m4_set_size($1)], [m4_indir([_m4_set_size($1)])], [0])]) - -# _m4_set_size(SET, ACTION) -# ------------------------- -# ACTION must be either m4_incr or m4_decr, and the size of SET is -# changed accordingly. If the set is empty, ACTION must not be -# m4_decr. -m4_define([_m4_set_size], -[m4_define([_m4_set_size($1)], - m4_ifdef([_m4_set_size($1)], [$2(m4_indir([_m4_set_size($1)]))], - [1]))]) - -# m4_set_union(SET1, SET2) -# ------------------------ -# Produce a LIST of double quoted elements that occur in either SET1 -# or SET2, without duplicates. Output a comma prior to any elements, -# to distinguish the empty string from no elements. This can be -# directly used as a series of arguments, such as for m4_join, or -# wrapped inside quotes for use in m4_foreach. Order of the output is -# not guaranteed. -# -# We can rely on the fact that m4_set_listc prunes SET1, so we don't -# need to check _m4_set([$1],element) for 0. Use _m4_defn for speed. -# Short-circuit the idempotence relation. -m4_define([m4_set_union], -[m4_set_listc([$1])m4_if([$1], [$2], [], [m4_set_foreach([$2], [_m4_element], - [m4_ifdef([_m4_set([$1],]_m4_defn([_m4_element])[)], [], - [,_m4_defn([_m4_element])])])])]) - - -## ------------------- ## -## 16. File handling. ## -## ------------------- ## - - -# It is a real pity that M4 comes with no macros to bind a diversion -# to a file. So we have to deal without, which makes us a lot more -# fragile than we should. - - -# m4_file_append(FILE-NAME, CONTENT) -# ---------------------------------- -m4_define([m4_file_append], -[m4_syscmd([cat >>$1 <<_m4eof -$2 -_m4eof -]) -m4_if(m4_sysval, [0], [], - [m4_fatal([$0: cannot write: $1])])]) - - - -## ------------------------ ## -## 17. Setting M4sugar up. ## -## ------------------------ ## - - -# m4_init -# ------- -# Initialize the m4sugar language. -m4_define([m4_init], -[# All the M4sugar macros start with `m4_', except `dnl' kept as is -# for sake of simplicity. -m4_pattern_forbid([^_?m4_]) -m4_pattern_forbid([^dnl$]) - -# If __m4_version__ is defined, we assume that we are being run by M4 -# 1.6 or newer, and thus that $@ recursion is linear and debugmode(d) -# is available for faster checks of dereferencing undefined macros. -# But if it is missing, we assume we are being run by M4 1.4.x, that -# $@ recursion is quadratic, and that we need foreach-based -# replacement macros. Use the raw builtin to avoid tripping up -# include tracing. -m4_ifdef([__m4_version__], -[m4_debugmode([+d]) -m4_copy([_m4_defn], [m4_defn]) -m4_copy([_m4_popdef], [m4_popdef]) -m4_copy([_m4_undefine], [m4_undefine])], -[m4_builtin([include], [m4sugar/foreach.m4])]) - -# _m4_divert_diversion should be defined: -m4_divert_push([KILL]) - -# Check the divert push/pop perfect balance. -m4_wrap([m4_divert_pop([]) - m4_ifdef([_m4_divert_diversion], - [m4_fatal([$0: unbalanced m4_divert_push:]_m4_divert_n_stack)])[]]) -]) diff --git a/data/m4sugar/m4sugar.m4 b/data/m4sugar/m4sugar.m4 new file mode 120000 index 00000000..301feb54 --- /dev/null +++ b/data/m4sugar/m4sugar.m4 @@ -0,0 +1 @@ +../../submodules/autoconf/lib/m4sugar/m4sugar.m4 \ No newline at end of file From 54d8d31419866b16121ea6ca08a80b0d08b832f0 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 8 Dec 2008 13:58:37 +0100 Subject: [PATCH 047/404] Really add autoconf as a submodule. * submodules/autoconf: New. (cherry picked from commit e5fa6147efaf1f15b832b6f62b09638979bc82ef) --- submodules/autoconf | 1 + 1 file changed, 1 insertion(+) create mode 160000 submodules/autoconf diff --git a/submodules/autoconf b/submodules/autoconf new file mode 160000 index 00000000..fb069ddf --- /dev/null +++ b/submodules/autoconf @@ -0,0 +1 @@ +Subproject commit fb069ddf299107885435573544279c07df9d0b50 From e80b068ce1fabb922bf71ea2c528aba6f151280f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Wed, 31 Dec 2008 16:55:12 +0100 Subject: [PATCH 048/404] Copyright years. * data/glr.c: Add 2007 and 2008 here, consistenly with the comments. --- ChangeLog | 5 +++++ data/glr.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 929d5e4b..50e8fba9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-02-25 Akim Demaille + + Copyright years. + * data/glr.c: Add 2007 and 2008 here, consistenly with the comments. + 2008-12-08 Akim Demaille Install autoconf as a submodule to get m4sugar. diff --git a/data/glr.c b/data/glr.c index 53b7fa17..0b4ad52c 100644 --- a/data/glr.c +++ b/data/glr.c @@ -150,7 +150,7 @@ m4_changecom() m4_divert_push(0)dnl @output(b4_parser_file_name@)@ b4_copyright([Skeleton implementation for Bison GLR parsers in C], - [2002, 2003, 2004, 2005, 2006]) + [2002, 2003, 2004, 2005, 2006, 2007, 2008]) [ /* C GLR parser skeleton written by Paul Hilfinger. */ @@ -2639,7 +2639,7 @@ m4_if(b4_skeleton, ["glr.c"], [b4_defines_if( [@output(b4_spec_defines_file@)@ b4_copyright([Skeleton interface for Bison GLR parsers in C], - [2002, 2003, 2004, 2005, 2006]) + [2002, 2003, 2004, 2005, 2006, 2007, 2008]) b4_shared_declarations From 72183df4da75116a496099c856097f7f049b2d8a Mon Sep 17 00:00:00 2001 From: Di-an Jan Date: Thu, 20 Nov 2008 12:36:30 -0800 Subject: [PATCH 049/404] Improves options in the manual. * doc/bison.texinfo (-g, -x): Add space before argument. (Option Cross Key): Implement FIXME: listing directives also. * build-aux/cross-options.pl: Read from rather than <>. (Short Option): Special case -d. Put arguments inside @option. (Bison Directive): Add column, automatically extracted from src/scan-gram.l (actual name passed as the first argument) with special case for %define. * doc/Makefile.am (doc/cross-options.texi): Pass src/scan-gram.l to build-aux/cross-options.pl. * src/getargs.c (usage): Document limitations of cross-options.pl. * src/scan-gram.l: Likewise. --- ChangeLog | 15 ++++++++++++++ build-aux/cross-options.pl | 41 ++++++++++++++++++++++++++++---------- doc/Makefile.am | 3 ++- doc/bison.texinfo | 9 ++++----- src/getargs.c | 5 +++++ src/scan-gram.l | 11 ++++++++-- 6 files changed, 66 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 50e8fba9..37dd3a6e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2008-11-20 Di-an Jan + + Improves options in the manual. + * doc/bison.texinfo (-g, -x): Add space before argument. + (Option Cross Key): Implement FIXME: listing directives also. + * build-aux/cross-options.pl: Read from rather than <>. + (Short Option): Special case -d. Put arguments inside @option. + (Bison Directive): Add column, automatically extracted from + src/scan-gram.l (actual name passed as the first argument) + with special case for %define. + * doc/Makefile.am (doc/cross-options.texi): Pass src/scan-gram.l + to build-aux/cross-options.pl. + * src/getargs.c (usage): Document limitations of cross-options.pl. + * src/scan-gram.l: Likewise. + 2009-02-25 Akim Demaille Copyright years. diff --git a/build-aux/cross-options.pl b/build-aux/cross-options.pl index 58772775..8d507254 100755 --- a/build-aux/cross-options.pl +++ b/build-aux/cross-options.pl @@ -5,7 +5,10 @@ use 5.005; use strict; my %option; -while (<>) +my %directive; +my $scanner = `grep -i '"%[a-z]' $ARGV[0]`; +$scanner =~ s/"\[-_\]"/-/g; +while () { if (/^\s* # Initial spaces. (?:(-\w),\s+)? # $1: $short: Possible short option. @@ -16,7 +19,10 @@ while (<>) /x) { my ($short, $long, $opt, $arg) = ($1, $2, $3, $4); - $short = defined $short ? '@option{' . $short . '}' : ''; + $short = '' if ! defined $short; + $short = '-d' if $long eq '--defines' && ! $short; + my $dir = '%' . substr($long, 2); + $dir = '' if index ($scanner, "\"$dir\"") < 0; if ($arg) { # if $opt, $arg contains the closing ]. @@ -24,6 +30,7 @@ while (<>) if $opt eq '['; $arg =~ s/^=//; $arg = lc ($arg); + my $dir_arg = $arg; # If the argument is compite (e.g., for --define[=NAME[=VALUE]]), # put each word in @var, to build @var{name}[=@var{value}], not # @var{name[=value]}]. @@ -33,19 +40,33 @@ while (<>) $long_arg = "[$long_arg]"; $arg = "[$arg]"; } - $option{"$long$long_arg"} = $short ? "$short $arg" : ''; - } - else - { - $option{"$long"} = "$short"; + # For arguments of directives: this only works if all arguments + # are strings and have the same syntax as on the command line. + if ($dir_arg eq 'name[=value]') + { + $dir_arg = '@var{name} ["@var{value}"]'; + } + else + { + $dir_arg =~ s/(\w+)/\@var{"$1"}/g; + $dir_arg = '[' . $dir_arg . ']' + if $opt eq '['; + } + $long = "$long$long_arg"; + $short = "$short $arg" if $short && $short ne '-d'; + $dir = "$dir $dir_arg" if $dir; } + $option{$long} = $short; + $directive{$long} = $dir; } } foreach my $long (sort keys %option) { # Avoid trailing spaces. - printf ("\@item %-40s \@tab%s\n", - '@option{' . $long . '}', - $option{$long} ? " $option{$long}" : ""); + print '@item @option{', $long, "}\n\@tab"; + print ' @option{', $option{$long}, '}' if $option{$long}; + print "\n\@tab"; + print ' @code{', $directive{$long}, '}' if $directive{$long}; + print "\n"; } diff --git a/doc/Makefile.am b/doc/Makefile.am index 36370fca..f5ff34b2 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -28,7 +28,8 @@ CROSS_OPTIONS_PL = $(top_srcdir)/build-aux/cross-options.pl $(srcdir)/cross-options.texi: $(top_srcdir)/src/getargs.c $(CROSS_OPTIONS_PL) -rm -f $@ $@.tmp cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) bison - $(top_builddir)/src/bison --help | perl $(CROSS_OPTIONS_PL) >$@.tmp + $(top_builddir)/src/bison --help \ + | perl $(CROSS_OPTIONS_PL) $(top_srcdir)/src/scan-gram.l >$@.tmp mv $@.tmp $@ MAINTAINERCLEANFILES = $(srcdir)/cross-options.texi diff --git a/doc/bison.texinfo b/doc/bison.texinfo index 9d9fa3dc..110f580e 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -7941,7 +7941,7 @@ Specify the @var{file} for the parser file. The other output files' names are constructed from @var{file} as described under the @samp{-v} and @samp{-d} options. -@item -g[@var{file}] +@item -g [@var{file}] @itemx --graph[=@var{file}] Output a graphical representation of the @acronym{LALR}(1) grammar automaton computed by Bison, in @uref{http://www.graphviz.org/, Graphviz} @@ -7950,7 +7950,7 @@ automaton computed by Bison, in @uref{http://www.graphviz.org/, Graphviz} If omitted and the grammar file is @file{foo.y}, the output file will be @file{foo.dot}. -@item -x[@var{file}] +@item -x [@var{file}] @itemx --xml[=@var{file}] Output an XML report of the @acronym{LALR}(1) automaton computed by Bison. @code{@var{file}} is optional. @@ -7963,12 +7963,11 @@ More user feedback will help to stabilize it.) @node Option Cross Key @section Option Cross Key -@c FIXME: How about putting the directives too? Here is a list of options, alphabetized by long option, to help you find the corresponding short option. -@multitable {@option{--defines=@var{defines-file}}} {@option{-b @var{file-prefix}XXX}} -@headitem Long Option @tab Short Option +@multitable {@option{--defines=@var{defines-file}}} {@option{-D @var{name}[=@var{value}]}} {@code{%nondeterministic-parser}} +@headitem Long Option @tab Short Option @tab Bison Directive @include cross-options.texi @end multitable diff --git a/src/getargs.c b/src/getargs.c index 5601e981..9ffa4cf5 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -246,6 +246,11 @@ usage (int status) program_name); else { + /* For ../build-aux/cross-options.pl to work, use the format: + ^ -S, --long[=ARGS] (whitespace) + A --long option is required. + Otherwise, add exceptions to ../build-aux/cross-options.pl. */ + printf (_("Usage: %s [OPTION]... FILE\n"), program_name); fputs (_("\ Generate LALR(1) and GLR parsers.\n\ diff --git a/src/scan-gram.l b/src/scan-gram.l index 697f52f0..292960cb 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -1,7 +1,7 @@ /* Bison Grammar Scanner -*- C -*- - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, - Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software + Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -152,6 +152,13 @@ splice (\\[ \f\t\v]*\n)* /*----------------------------. | Scanning Bison directives. | `----------------------------*/ + + /* For directives that are also command line options, the regex must be + "%..." + after "[-_]"s are removed, and the directive must match the --long + option name, with a single string argument. Otherwise, add exceptions + to ../build-aux/cross-options.pl. */ + { "%binary" return PERCENT_NONASSOC; From fadb13b5b32b5efb354d9083fd201d1dfdb30150 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Fri, 21 Nov 2008 21:21:52 +0100 Subject: [PATCH 050/404] Display the changes in cross-options.texi. * build-aux/cross-options.pl ($sep): New, to separate items. * doc/Makefile.am ($(srcdir)/cross-options.texi): Use diff to display the changes. --- ChangeLog | 9 ++++++++- build-aux/cross-options.pl | 3 +++ doc/Makefile.am | 4 +++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 37dd3a6e..6e00950d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-11-21 Akim Demaille + + Display the changes in cross-options.texi. + * build-aux/cross-options.pl ($sep): New, to separate items. + * doc/Makefile.am ($(srcdir)/cross-options.texi): Use diff to display + the changes. + 2008-11-20 Di-an Jan Improves options in the manual. @@ -5,7 +12,7 @@ (Option Cross Key): Implement FIXME: listing directives also. * build-aux/cross-options.pl: Read from rather than <>. (Short Option): Special case -d. Put arguments inside @option. - (Bison Directive): Add column, automatically extracted from + (Bison Directive): Add column, automatically extracted from src/scan-gram.l (actual name passed as the first argument) with special case for %define. * doc/Makefile.am (doc/cross-options.texi): Pass src/scan-gram.l diff --git a/build-aux/cross-options.pl b/build-aux/cross-options.pl index 8d507254..241c741b 100755 --- a/build-aux/cross-options.pl +++ b/build-aux/cross-options.pl @@ -61,9 +61,12 @@ while () } } +my $sep = ''; foreach my $long (sort keys %option) { # Avoid trailing spaces. + print $sep; + $sep = "\n"; print '@item @option{', $long, "}\n\@tab"; print ' @option{', $option{$long}, '}' if $option{$long}; print "\n\@tab"; diff --git a/doc/Makefile.am b/doc/Makefile.am index f5ff34b2..3c403275 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -26,10 +26,12 @@ clean-local: CROSS_OPTIONS_PL = $(top_srcdir)/build-aux/cross-options.pl $(srcdir)/cross-options.texi: $(top_srcdir)/src/getargs.c $(CROSS_OPTIONS_PL) - -rm -f $@ $@.tmp + mv -f $@ $@~ || : >$@~ + -rm -f $@.tmp cd $(top_builddir)/src && $(MAKE) $(AM_MAKEFLAGS) bison $(top_builddir)/src/bison --help \ | perl $(CROSS_OPTIONS_PL) $(top_srcdir)/src/scan-gram.l >$@.tmp + diff -u $@~ $@.tmp || true mv $@.tmp $@ MAINTAINERCLEANFILES = $(srcdir)/cross-options.texi From 96002de2e149fb4be00764aa29d766c3afe18fee Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 12 Aug 2008 21:11:53 +0200 Subject: [PATCH 051/404] muscles_output. * src/output.c (muscles_output): New, extracted from... (output_skeleton): here. Adjust. --- ChangeLog | 7 +++++++ src/output.c | 29 ++++++++++++++++++----------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6e00950d..f4c31a44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-11-10 Akim Demaille + + muscles_output. + * src/output.c (muscles_output): New, extracted from... + (output_skeleton): here. + Adjust. + 2008-11-21 Akim Demaille Display the changes in cross-options.texi. diff --git a/src/output.c b/src/output.c index 585b90e0..7eb35185 100644 --- a/src/output.c +++ b/src/output.c @@ -462,6 +462,23 @@ prepare_actions (void) 0, 1, conflict_list_cnt); } +/*--------------------------------------------. +| Output the definitions of all the muscles. | +`--------------------------------------------*/ + +static void +muscles_output (FILE *out) +{ + fputs ("m4_init()\n", out); + + user_actions_output (out); + merger_output (out); + token_definitions_output (out); + symbol_code_props_output (out, "destructors", &symbol_destructor_get); + symbol_code_props_output (out, "printers", &symbol_printer_get); + + muscles_m4_output (out); +} /*---------------------------. | Call the skeleton parser. | @@ -563,17 +580,7 @@ output_skeleton (void) if (! out) error (EXIT_FAILURE, get_errno (), "fdopen"); - - /* Output the definitions of all the muscles. */ - fputs ("m4_init()\n", out); - - user_actions_output (out); - merger_output (out); - token_definitions_output (out); - symbol_code_props_output (out, "destructors", &symbol_destructor_get); - symbol_code_props_output (out, "printers", &symbol_printer_get); - - muscles_m4_output (out); + muscles_output (out); xfclose (out); /* Read and process m4's output. */ From c65e52923780b0b20fbb8dcb2f14d14f08163798 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 12 Aug 2008 21:48:44 +0200 Subject: [PATCH 052/404] --trace=muscles * src/getargs.h, src/getargs.c (trace_muscle): New. (trace_types, trace_args): Support it. * src/output.c (output_skeleton): Use it. (cherry picked from commit 5263bea9f7d576c20938619af2197eb5b47a90c3) --- ChangeLog | 7 +++++++ src/getargs.c | 2 ++ src/getargs.h | 1 + src/output.c | 18 +++++++++++------- 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index f4c31a44..e3c305b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-11-10 Akim Demaille + + --trace=muscles + * src/getargs.h, src/getargs.c (trace_muscle): New. + (trace_types, trace_args): Support it. + * src/output.c (output_skeleton): Use it. + 2008-11-10 Akim Demaille muscles_output. diff --git a/src/getargs.c b/src/getargs.c index 9ffa4cf5..aebc2401 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -176,6 +176,7 @@ static const char * const trace_args[] = "grammar - reading, reducing the grammar", "resource - memory consumption (where available)", "sets - grammar sets: firsts, nullable etc.", + "muscles - m4 definitions passed to the skeleton", "tools - m4 invocation", "m4 - m4 traces", "skeleton - skeleton postprocessing", @@ -194,6 +195,7 @@ static const int trace_types[] = trace_grammar, trace_resource, trace_sets, + trace_muscles, trace_tools, trace_m4, trace_skeleton, diff --git a/src/getargs.h b/src/getargs.h index 8d27e717..11390674 100644 --- a/src/getargs.h +++ b/src/getargs.h @@ -106,6 +106,7 @@ enum trace trace_time = 1 << 8, /**< Time consumption. */ trace_skeleton = 1 << 9, /**< Skeleton postprocessing. */ trace_m4 = 1 << 10, /**< M4 traces. */ + trace_muscles = 1 << 11, /**< M4 definitions of the muscles. */ trace_all = ~0 /**< All of the above. */ }; /** What debug items bison displays during its run. */ diff --git a/src/output.c b/src/output.c index 7eb35185..f7251473 100644 --- a/src/output.c +++ b/src/output.c @@ -488,7 +488,6 @@ static void output_skeleton (void) { FILE *in; - FILE *out; int filter_fd[2]; char const *argv[9]; pid_t pid; @@ -576,12 +575,17 @@ output_skeleton (void) free (full_m4bison); free (full_skeleton); - out = fdopen (filter_fd[0], "w"); - if (! out) - error (EXIT_FAILURE, get_errno (), - "fdopen"); - muscles_output (out); - xfclose (out); + + if (trace_flag & trace_muscles) + muscles_output (stderr); + { + FILE *out = fdopen (filter_fd[0], "w"); + if (! out) + error (EXIT_FAILURE, get_errno (), + "fdopen"); + muscles_output (out); + xfclose (out); + } /* Read and process m4's output. */ timevar_push (TV_M4); From 4ecd3681992375013c8e8f532a5463eb17781424 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Mon, 6 Apr 2009 06:22:27 -0400 Subject: [PATCH 053/404] * NEWS (2.5): Describe new -D/--define feature. --- ChangeLog | 4 ++++ NEWS | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ChangeLog b/ChangeLog index e3c305b8..6beb8242 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-04-06 Joel E. Denny + + * NEWS (2.5): Describe new -D/--define feature. + 2008-11-10 Akim Demaille --trace=muscles diff --git a/NEWS b/NEWS index 2c3238fe..1a98c191 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,20 @@ Bison News * Changes in version 2.5 (????-??-??): +** %define can now be invoked via the command line. + + Each of these bison command-line options + + -D NAME=VALUE + --define=NAME=VALUE + + is equivalent to this grammar file declaration + + %define NAME "VALUE" + + for any NAME and VALUE. Omitting `=VALUE' on the command line is + equivalent to omitting `"VALUE"' in the declaration. + * Changes in version 2.4.2 (????-??-??): * Changes in version 2.4.1 (2008-12-11): From b4d71a96647c5ed06208ceb0aa0c7565c66dde3c Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Mon, 6 Apr 2009 22:05:38 -0600 Subject: [PATCH 054/404] Work around autoconf 2.63b bug in testsuite. * tests/output.at (AT_CHECK_OUTPUT_FILE_NAME): Avoid tripping autoconf bug related to # in test. Signed-off-by: Eric Blake (cherry picked from commit ab3a683f0560e4ec24a06754386ee8c76da6ef67) --- ChangeLog | 6 ++++++ tests/output.at | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6beb8242..cf5ba716 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-04-06 Eric Blake + + Work around autoconf 2.63b bug in testsuite. + * tests/output.at (AT_CHECK_OUTPUT_FILE_NAME): Avoid tripping + autoconf bug related to # in test. + 2009-04-06 Joel E. Denny * NEWS (2.5): Describe new -D/--define feature. diff --git a/tests/output.at b/tests/output.at index ce0a2b27..c4b96404 100644 --- a/tests/output.at +++ b/tests/output.at @@ -1,6 +1,6 @@ # Checking the output filenames. -*- Autotest -*- -# Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007, 2008 Free Software -# Foundation, Inc. +# Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007, 2008, 2009 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 @@ -206,7 +206,7 @@ m4_define([_m4_expand], [m4_changequote([-=<{(], [)}>=-])$1m4_changequote([, ])])]) AT_CHECK_OUTPUT_FILE_NAME([[(]]) AT_CHECK_OUTPUT_FILE_NAME([[)]]) -AT_CHECK_OUTPUT_FILE_NAME([[#]]) +AT_CHECK_OUTPUT_FILE_NAME([[@%:@]]) AT_CHECK_OUTPUT_FILE_NAME([[@@]]) AT_CHECK_OUTPUT_FILE_NAME([[@{]]) AT_CHECK_OUTPUT_FILE_NAME([[@}]]) From 7ba0d59da0ec8f6876a66ea81bb9f9190ddec358 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Fri, 10 Apr 2009 07:36:49 -0600 Subject: [PATCH 055/404] submodules: update to latest * submodules/autoconf: Use latest upstream Autoconf. Signed-off-by: Eric Blake --- ChangeLog | 5 +++++ submodules/autoconf | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cf5ba716..bcd9cc11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-04-10 Eric Blake + + submodules: update to latest + * submodules/autoconf: Use latest upstream Autoconf. + 2009-04-06 Eric Blake Work around autoconf 2.63b bug in testsuite. diff --git a/submodules/autoconf b/submodules/autoconf index fb069ddf..ef8940d9 160000 --- a/submodules/autoconf +++ b/submodules/autoconf @@ -1 +1 @@ -Subproject commit fb069ddf299107885435573544279c07df9d0b50 +Subproject commit ef8940d9b5a3fe2866027f82a535915da3e78829 From bd5df716a33f8c707dbba101f78dedf5feb9e9d5 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 13 Apr 2009 20:57:38 +0200 Subject: [PATCH 056/404] doc: minor fixes. * doc/bison.texinfo (Decl Summary): Fix entry about %debug. (Table of Symbols): Remove duplicate entry for %debug. --- ChangeLog | 6 ++++++ doc/bison.texinfo | 6 +----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index bcd9cc11..2469f912 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-04-14 Akim Demaille + + doc: minor fixes. + * doc/bison.texinfo (Decl Summary): Fix entry about %debug. + (Table of Symbols): Remove duplicate entry for %debug. + 2009-04-10 Eric Blake submodules: update to latest diff --git a/doc/bison.texinfo b/doc/bison.texinfo index 110f580e..c8fa086d 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -4834,8 +4834,8 @@ traditional Yacc prologue for C/C++, see @ref{Prologue Alternatives}. @deffn {Directive} %debug In the parser file, define the macro @code{YYDEBUG} to 1 if it is not already defined, so that the debugging facilities are compiled. -@end deffn @xref{Tracing, ,Tracing Your Parser}. +@end deffn @deffn {Directive} %define @var{variable} @deffnx {Directive} %define @var{variable} "@var{value}" @@ -9782,10 +9782,6 @@ Insert @var{code} verbatim into output parser source. Equip the parser for debugging. @xref{Decl Summary}. @end deffn -@deffn {Directive} %debug -Equip the parser for debugging. @xref{Decl Summary}. -@end deffn - @ifset defaultprec @deffn {Directive} %default-prec Assign a precedence to rules that lack an explicit @samp{%prec} From 42f4393a72c808c6858b29a2343884f12c187e19 Mon Sep 17 00:00:00 2001 From: Di-an Jan Date: Sun, 7 Dec 2008 21:54:45 -0800 Subject: [PATCH 057/404] Implement the FIXME that ends an user action with a semicolon if it seems necessary. * src/scan-code.l (flex rules section): Flag cpp directive from any `#' to the first unescaped end-of-line. Semicolon is not needed after `;', `{', '}', or cpp directives and is needed after any other token (whitespaces and comments have no effect). * tests/actions.at (Fix user actions without a trailing semicolon): New test. * tests/input.at (AT_CHECK_UNUSED_VALUES): Add semicolons to to make user actions complete statements. Adjust column numbers in error messages. * tests/regression.at (Fix user actions without a trailing semicolon): Remove. Covered by new test. (cherry picked from commit e8cd1ad655bcc704b06fb2f191dc3ac1df32b796) --- ChangeLog | 16 ++++++ src/scan-code.l | 64 ++++++++++++++++++------ tests/actions.at | 117 ++++++++++++++++++++++++++++++++++++++++++++ tests/input.at | 34 ++++++------- tests/regression.at | 24 --------- 5 files changed, 198 insertions(+), 57 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2469f912..5104afbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2008-12-07 Di-an Jan + + Implement the FIXME that ends an user action with a semicolon + if it seems necessary. + * src/scan-code.l (flex rules section): Flag cpp directive from + any `#' to the first unescaped end-of-line. Semicolon is not + needed after `;', `{', '}', or cpp directives and is needed after + any other token (whitespaces and comments have no effect). + * tests/actions.at (Fix user actions without a trailing semicolon): + New test. + * tests/input.at (AT_CHECK_UNUSED_VALUES): Add semicolons to + to make user actions complete statements. + Adjust column numbers in error messages. + * tests/regression.at (Fix user actions without a trailing semicolon): + Remove. Covered by new test. + 2009-04-14 Akim Demaille doc: minor fixes. diff --git a/src/scan-code.l b/src/scan-code.l index 13a78c27..c076213b 100644 --- a/src/scan-code.l +++ b/src/scan-code.l @@ -81,6 +81,19 @@ splice (\\[ \f\t\v]*\n)* /* Nesting level of the current code in braces. */ int braces_level = 0; + /* Whether a semicolon is probably needed. + The heuristic is that a semicolon is not needed after `{', `}', `;', + or a C preprocessor directive, and that whitespaces and comments + do not affect this flag. + Note that `{' does not need a semicolon because of `{}'. + A semicolon may be needed before a cpp direcive, but don't bother. */ + bool need_semicolon = false; + + /* Whether in a C preprocessor directive. Don't use a start condition + for this because, at the end of strings and comments, we still need + to know whether we're in a directive. */ + bool in_cpp = false; + /* This scanner is special: it is invoked only once, henceforth is expected to return only once. This initialization is therefore done once per action to translate. */ @@ -135,10 +148,12 @@ splice (\\[ \f\t\v]*\n)* "'" { STRING_GROW; BEGIN SC_CHARACTER; + need_semicolon = true; } "\"" { STRING_GROW; BEGIN SC_STRING; + need_semicolon = true; } "/"{splice}"*" { STRING_GROW; @@ -154,46 +169,63 @@ splice (\\[ \f\t\v]*\n)* { "$"("<"{tag}">")?(-?[0-9]+|"$") { handle_action_dollar (self->rule, yytext, *loc); + need_semicolon = true; } "@"(-?[0-9]+|"$") { handle_action_at (self->rule, yytext, *loc); + need_semicolon = true; } "$" { warn_at (*loc, _("stray `$'")); obstack_sgrow (&obstack_for_string, "$]["); + need_semicolon = true; } "@" { warn_at (*loc, _("stray `@'")); obstack_sgrow (&obstack_for_string, "@@"); + need_semicolon = true; + } + "[" { + obstack_sgrow (&obstack_for_string, "@{"); + need_semicolon = true; + } + "]" { + obstack_sgrow (&obstack_for_string, "@}"); + need_semicolon = true; } - "{" STRING_GROW; ++braces_level; + ";" STRING_GROW; need_semicolon = false; + "{" STRING_GROW; ++braces_level; need_semicolon = false; "}" { bool outer_brace = --braces_level == 0; /* As an undocumented Bison extension, append `;' before the last brace in braced code, so that the user code can omit trailing `;'. But do not append `;' if emulating Yacc, since Yacc does - not append one. Also, some output languages (like Java) do not - accept an extra semicolon, so don't append if the user specified - a skeleton or language. - - FIXME: Bison should warn if a semicolon seems to be necessary - here, and should omit the semicolon if it seems unnecessary - (e.g., after ';', '{', or '}', each followed by comments or - white space). Such a warning shouldn't depend on --yacc; it - should depend on a new --pedantic option, which would cause - Bison to warn if it detects an extension to POSIX. --pedantic - should also diagnose other Bison extensions like %yacc. - Perhaps there should also be a GCC-style --pedantic-errors - option, so that such warnings are diagnosed as errors. */ + not append one. */ if (outer_brace && !yacc_flag && language_prio == default_prio - && skeleton_prio == default_prio) - obstack_1grow (&obstack_for_string, ';'); + && skeleton_prio == default_prio && need_semicolon && ! in_cpp) + { + warn_at (*loc, _("a `;' might be needed at the end of action code")); + warn_at (*loc, _("future versions of Bison will not add the `;'")); + obstack_1grow (&obstack_for_string, ';'); + } STRING_GROW; + need_semicolon = false; } + + /* Preprocessing directives should only be recognized at the beginning + of lines, allowing whitespace including comments, but in C/C++, + `#' can only be the start of preprocessor directives or within + `#define' directives anyway, so don't bother with begin of line. */ + "#" STRING_GROW; in_cpp = true; + + {splice} STRING_GROW; + [\n\r] STRING_GROW; if (in_cpp) in_cpp = need_semicolon = false; + [ \t\f] STRING_GROW; + . STRING_GROW; need_semicolon = true; } diff --git a/tests/actions.at b/tests/actions.at index afbc94db..32bfc34e 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -1300,3 +1300,120 @@ AT_CLEANUP]) AT_CHECK_ACTION_LOCATIONS([[%initial-action]]) AT_CHECK_ACTION_LOCATIONS([[%destructor]]) AT_CHECK_ACTION_LOCATIONS([[%printer]]) + + +## ----------------------------------------------- ## +## Fix user actions without a trailing semicolon. ## +## ----------------------------------------------- ## + +AT_SETUP([[Fix user actions without a trailing semicolon]]) + +# This feature is undocumented, but we accidentally broke it in 2.3a, +# and there was a complaint at: +# . + +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 */ } +; +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 ; +} ; +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 {} +} ; + +testc +: 'a' { +#define TEST_MACRO_N \ +[]"broken\" $ @ $$ @$ [];\ +string;"} +| 'b' { +no_semi +#define TEST_MACRO_N \ +[]"broken\" $ @ $$ @$ [];\ +string;"} +]]) + +AT_BISON_CHECK([[-o input.c input.y]], [0], [], +[[input.y:8.48: warning: a `;' might be needed at the end of action code +input.y:8.48: warning: future versions of Bison will not add the `;' +input.y:9.48: warning: a `;' might be needed at the end of action code +input.y:9.48: warning: future versions of Bison will not add the `;' +input.y:10.48: warning: a `;' might be needed at the end of action code +input.y:10.48: warning: future versions of Bison will not add the `;' +input.y:11.48: warning: a `;' might be needed at the end of action code +input.y:11.48: warning: future versions of Bison will not add the `;' +input.y:12.48: warning: a `;' might be needed at the end of action code +input.y:12.48: warning: future versions of Bison will not add the `;' +input.y:13.48: warning: a `;' might be needed at the end of action code +input.y:13.48: warning: future versions of Bison will not add the `;' +input.y:20.1: warning: a `;' might be needed at the end of action code +input.y:20.1: warning: future versions of Bison will not add the `;' +input.y:21.1: warning: a `;' might be needed at the end of action code +input.y:21.1: warning: future versions of Bison will not add the `;' +input.y:22.1: warning: a `;' might be needed at the end of action code +input.y:22.1: warning: future versions of Bison will not add the `;' +input.y:23.1: warning: a `;' might be needed at the end of action code +input.y:23.1: warning: future versions of Bison will not add the `;' +input.y:24.1: warning: a `;' might be needed at the end of action code +input.y:24.1: warning: future versions of Bison will not add the `;' +input.y:25.1: warning: a `;' might be needed at the end of action code +input.y:25.1: warning: future versions of Bison will not add the `;' +input.y:31.1: warning: a `;' might be needed at the end of action code +input.y:31.1: warning: future versions of Bison will not add the `;' +input.y:32.1: warning: a `;' might be needed at the end of action code +input.y:32.1: warning: future versions of Bison will not add the `;' +input.y:33.1: warning: a `;' might be needed at the end of action code +input.y:33.1: warning: future versions of Bison will not add the `;' +input.y:34.1: warning: a `;' might be needed at the end of action code +input.y:34.1: warning: future versions of Bison will not add the `;' +input.y:35.1: warning: a `;' might be needed at the end of action code +input.y:35.1: warning: future versions of Bison will not add the `;' +input.y:36.1: warning: a `;' might be needed at the end of action code +input.y:36.1: warning: future versions of Bison will not add the `;' +]]) +AT_CHECK([[grep -c '/\* TEST:N:2 \*/ }$' input.c]], [0], [[3 +]]) +AT_CHECK([[grep -c '/\* TEST:Y:2 \*/ ;}$' input.c]], [0], [[6 +]]) +AT_CHECK([[sed -n '/TEST:N:1/{N +s/\n//gp}' input.c | grep -c '// TEST:N:1 [;{}]*}$']], [0], [[6 +]]) +AT_CHECK([[sed -n '/TEST:Y:1/{N +s/\n//gp}' input.c | grep -c '// TEST:Y:1 [;{}]*;}$']], [0], [[12 +]]) +AT_CHECK([[sed -n '/^#define TEST_MACRO_N/{N +N +s/\n//gp}' input.c | grep -F -xc '#define TEST_MACRO_N \[]"broken\" $ @ $$ @$ [];\string;"}']], + [0], [[2 +]]) + +AT_CLEANUP diff --git a/tests/input.at b/tests/input.at index bb036c38..57f3b641 100644 --- a/tests/input.at +++ b/tests/input.at @@ -97,16 +97,16 @@ m4_ifval($1, [ ], [_AT_UNUSED_VALUES_DECLARATIONS ])[[%% start: - 'a' a { $]2[ } | 'b' b { $]2[ } | 'c' c { $]2[ } | 'd' d { $]2[ } | 'e' e { $]2[ } -| 'f' f { $]2[ } | 'g' g { $]2[ } | 'h' h { $]2[ } | 'i' i { $]2[ } | 'j' j { $]2[ } -| 'k' k { $]2[ } | 'l' l { $]2[ } + 'a' a { $]2[; } | 'b' b { $]2[; } | 'c' c { $]2[; } | 'd' d { $]2[; } +| 'e' e { $]2[; } | 'f' f { $]2[; } | 'g' g { $]2[; } | 'h' h { $]2[; } +| 'i' i { $]2[; } | 'j' j { $]2[; } | 'k' k { $]2[; } | 'l' l { $]2[; } ; a: INT | INT { } INT { } INT { }; b: INT | /* empty */; -c: INT | INT { $]1[ } INT { $2 } INT { $4 }; -d: INT | INT { } INT { $]1[ } INT { $2 }; -e: INT | INT { } INT { } INT { $]1[ }; +c: INT | INT { $]1[; } INT { $2; } INT { $4; }; +d: INT | INT { } INT { $]1[; } INT { $2; }; +e: INT | INT { } INT { } INT { $]1[; }; f: INT | INT { } INT { } INT { $]$[ = $]1[ + $]3[ + $]5[; }; g: INT | INT { $$; } INT { $$; } INT { }; h: INT | INT { $$; } INT { $$ = $2; } INT { }; @@ -123,18 +123,18 @@ input.y:11.10-32: warning: unused value: $]1[ input.y:11.10-32: warning: unused value: $]3[ input.y:11.10-32: warning: unused value: $]5[ input.y:12.9: warning: empty rule for typed nonterminal, and no action -]]m4_ifval($2, [[[input.y:13.14-19: warning: unset value: $$ -input.y:13.25-39: warning: unset value: $$ -]]])[[input.y:13.10-59: warning: unset value: $]$[ -input.y:13.10-59: warning: unused value: $]3[ -input.y:13.10-59: warning: unused value: $]5[ +]]m4_ifval($2, [[[input.y:13.14-20: warning: unset value: $$ +input.y:13.26-41: warning: unset value: $$ +]]])[[input.y:13.10-62: warning: unset value: $]$[ +input.y:13.10-62: warning: unused value: $]3[ +input.y:13.10-62: warning: unused value: $]5[ ]]m4_ifval($2, [[[input.y:14.14-16: warning: unset value: $$ -]]])[[input.y:14.10-47: warning: unset value: $]$[ -input.y:14.10-47: warning: unused value: $]3[ -input.y:14.10-47: warning: unused value: $]5[ -input.y:15.10-36: warning: unset value: $]$[ -input.y:15.10-36: warning: unused value: $]3[ -input.y:15.10-36: warning: unused value: $]5[ +]]])[[input.y:14.10-49: warning: unset value: $]$[ +input.y:14.10-49: warning: unused value: $]3[ +input.y:14.10-49: warning: unused value: $]5[ +input.y:15.10-37: warning: unset value: $]$[ +input.y:15.10-37: warning: unused value: $]3[ +input.y:15.10-37: warning: unused value: $]5[ input.y:17.10-58: warning: unset value: $]$[ input.y:17.10-58: warning: unused value: $]1[ ]]m4_ifval($2, [[[input.y:17.10-58: warning: unused value: $]2[ diff --git a/tests/regression.at b/tests/regression.at index fa2278a8..32e676c6 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -1247,27 +1247,3 @@ AT_COMPILE([[input]]) AT_PARSER_CHECK([[./input]]) AT_CLEANUP - - - -## ----------------------------------------------- ## -## Fix user actions without a trailing semicolon. ## -## ----------------------------------------------- ## - -AT_SETUP([[Fix user actions without a trailing semicolon]]) - -# This feature is undocumented, but we accidentally broke it in 2.3a, and there -# was a complaint at: -# . - -AT_DATA([input.y], -[[%% -start: {asdffdsa} ; -]]) - -AT_BISON_CHECK([[-o input.c input.y]]) -AT_CHECK([[sed -n '/asdffdsa/s/^ *//p' input.c]], [[0]], -[[{asdffdsa;} -]]) - -AT_CLEANUP From c4fae1ef488f25c1f6bd104d2cba1bcb1cfe865a Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 8 Dec 2008 10:26:38 +0100 Subject: [PATCH 058/404] Fix portability issue in the test suite. * tests/local.at (AT_MATCHES_CHECK): New. Based on Perl instead of Sed. Sed has too many portability pitfalls, not ever Sed is GNU Sed. * tests/actions.at (Fix user actions without a trailing semicolon): Use it. (cherry picked from commit 6617622c9aaa6ec3a9de5b0867421e2849b68b2f) --- ChangeLog | 9 +++++++++ tests/actions.at | 21 ++++++--------------- tests/local.at | 16 ++++++++++++++++ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5104afbf..a7603bde 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-12-08 Akim Demaille + + Fix portability issue in the test suite. + * tests/local.at (AT_MATCHES_CHECK): New. + Based on Perl instead of Sed. Sed has too many portability + pitfalls, not ever Sed is GNU Sed. + * tests/actions.at (Fix user actions without a trailing semicolon): + Use it. + 2008-12-07 Di-an Jan Implement the FIXME that ends an user action with a semicolon diff --git a/tests/actions.at b/tests/actions.at index 32bfc34e..841ae392 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -1400,20 +1400,11 @@ input.y:35.1: warning: future versions of Bison will not add the `;' input.y:36.1: warning: a `;' might be needed at the end of action code input.y:36.1: warning: future versions of Bison will not add the `;' ]]) -AT_CHECK([[grep -c '/\* TEST:N:2 \*/ }$' input.c]], [0], [[3 -]]) -AT_CHECK([[grep -c '/\* TEST:Y:2 \*/ ;}$' input.c]], [0], [[6 -]]) -AT_CHECK([[sed -n '/TEST:N:1/{N -s/\n//gp}' input.c | grep -c '// TEST:N:1 [;{}]*}$']], [0], [[6 -]]) -AT_CHECK([[sed -n '/TEST:Y:1/{N -s/\n//gp}' input.c | grep -c '// TEST:Y:1 [;{}]*;}$']], [0], [[12 -]]) -AT_CHECK([[sed -n '/^#define TEST_MACRO_N/{N -N -s/\n//gp}' input.c | grep -F -xc '#define TEST_MACRO_N \[]"broken\" $ @ $$ @$ [];\string;"}']], - [0], [[2 -]]) + +AT_MATCHES_CHECK([input.c], [[/\* TEST:N:2 \*/ \}$]], [[3]]) +AT_MATCHES_CHECK([input.c], [[/\* TEST:Y:2 \*/ ;\}$]], [[6]]) +AT_MATCHES_CHECK([input.c], [[// TEST:N:1 [;{}]*\n\}$]], [[6]]) +AT_MATCHES_CHECK([input.c], [[// TEST:Y:1 [;{}]*\n;\}$]], [[12]]) +AT_MATCHES_CHECK([input.c], [[#define TEST_MACRO_N \\\n\[\]"broken\\" \$ \@ \$\$ \@\$ \[\];\\\nstring;"\}]], [[2]]) AT_CLEANUP diff --git a/tests/local.at b/tests/local.at index 01adaf5d..163de2ef 100644 --- a/tests/local.at +++ b/tests/local.at @@ -21,6 +21,22 @@ m4_version_prereq([2.58]) +## ------------- ## +## Basic tests. ## +## ------------- ## + +# AT_MATCHES_CHECK(FILE, PERL-REGEXP, COUNT) +# ------------------------------------------ +# Expect COUNT matches of the PERL-REGEXP in FILE. The file is +# taken in "slurp" mode, i.e., one can match end-of-lines. +m4_define([AT_MATCHES_CHECK], +[AT_CHECK([perl -0777 -ne ' +my $count = 0; +s{$2}{ ++$count; "" }gem; +printf "$count\n";' $1], [0], [$3 +])]) + + ## ------------------------------- ## ## Macros decoding Bison options. ## ## ------------------------------- ## From a2d0567444f8ab1fc079796169a9845fec62ed0f Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Sat, 4 Apr 2009 02:10:33 -0400 Subject: [PATCH 059/404] Document semicolon warnings. * NEWS (2.5): Here. --- ChangeLog | 5 +++++ NEWS | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/ChangeLog b/ChangeLog index a7603bde..347006ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-04-04 Joel E. Denny + + Document semicolon warnings. + * NEWS (2.5): Here. + 2008-12-08 Akim Demaille Fix portability issue in the test suite. diff --git a/NEWS b/NEWS index 1a98c191..f57b755d 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,27 @@ Bison News for any NAME and VALUE. Omitting `=VALUE' on the command line is equivalent to omitting `"VALUE"' in the declaration. +** Temporary hack for adding a semicolon to the user action. + + Previously, Bison appended a semicolon to every user action for + reductions when the output language defaulted to C (specifically, when + neither %yacc, %language, %skeleton, or equivalent command-line + options were specified). This allowed actions such as + + exp: exp "+" exp { $$ = $1 + $3 }; + + instead of + + exp: exp "+" exp { $$ = $1 + $3; }; + + As a first step in removing this misfeature, Bison now issues a + warning when it appends a semicolon. Moreover, in cases where Bison + cannot easily determine whether a semicolon is needed (for example, an + action ending with a cpp directive or a braced compound initializer), + it no longer appends one. Thus, the C compiler might now complain + about a missing semicolon where it did not before. Future releases of + Bison will cease to append semicolons entirely. + * Changes in version 2.4.2 (????-??-??): * Changes in version 2.4.1 (2008-12-11): From 426607361865b7071e9b393a33ec9744093ea4b0 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 17 Apr 2009 16:14:17 -0400 Subject: [PATCH 060/404] Pacify make maintainer-check-posix. * tests/input.at (%define, --define): Move bison command-line options before grammar file name. --- ChangeLog | 6 ++++++ tests/input.at | 16 ++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 347006ba..7df915f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-04-17 Joel E. Denny + + Pacify make maintainer-check-posix. + * tests/input.at (%define, --define): Move bison command-line + options before grammar file name. + 2009-04-04 Joel E. Denny Document semicolon warnings. diff --git a/tests/input.at b/tests/input.at index 57f3b641..4389e9d2 100644 --- a/tests/input.at +++ b/tests/input.at @@ -1,6 +1,6 @@ # Checking the Bison scanner. -*- Autotest -*- -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, -# Inc. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# 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 @@ -834,14 +834,14 @@ AT_DATA([input.y], start: ; ]]) -AT_BISON_CHECK([[input.y -DFOO -DFOO -Dvar=value]], [0], [], -[[:4: warning: %define variable `FOO' redefined -:3: warning: previous definition +AT_BISON_CHECK([[-DFOO -DFOO -Dvar=value input.y]], [0], [], +[[:3: warning: %define variable `FOO' redefined +:2: warning: previous definition input.y:1.9-11: warning: %define variable `var' redefined -:5: warning: previous definition +:4: warning: previous definition +:2: warning: %define variable `FOO' is not used :3: warning: %define variable `FOO' is not used -:4: warning: %define variable `FOO' is not used -:5: warning: %define variable `var' is not used +:4: warning: %define variable `var' is not used input.y:1.9-11: warning: %define variable `var' is not used ]]) From 44c124a3896b149561b3b9cee411b4a479ab04d7 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 20 Apr 2009 12:53:46 +0200 Subject: [PATCH 061/404] Consistently refer to Yacc, not YACC. * src/getargs.c (usage, warnings_args): s/YACC/Yacc/. --- ChangeLog | 5 +++++ src/getargs.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7df915f4..eb240df7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-04-20 Akim Demaille + + Consistently refer to Yacc, not YACC. + * src/getargs.c (usage, warnings_args): s/YACC/Yacc/. + 2009-04-17 Joel E. Denny Pacify make maintainer-check-posix. diff --git a/src/getargs.c b/src/getargs.c index aebc2401..bb060c55 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -216,7 +216,7 @@ static const char * const warnings_args[] = that argmatch_valid be more readable. */ "none - no warnings", "midrule-values - unset or unused midrule values", - "yacc - incompatibilities with POSIX YACC", + "yacc - incompatibilities with POSIX Yacc", "all - all of the above", "error - warnings are errors", 0 @@ -312,7 +312,7 @@ Output:\n\ fputs (_("\ Warning categories include:\n\ `midrule-values' unset or unused midrule values\n\ - `yacc' incompatibilities with POSIX YACC\n\ + `yacc' incompatibilities with POSIX Yacc\n\ `all' all the warnings\n\ `no-CATEGORY' turn off warnings in CATEGORY\n\ `none' turn off all the warnings\n\ From 03c07b039448552b5ac6c51076b88c2f15b0307f Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Mon, 20 Apr 2009 00:55:50 -0400 Subject: [PATCH 062/404] Implement %define lr.default_rules. Its value describes the states that are permitted to contain default rules: "all", "consistent", or "accepting". * src/reader.c (reader): Default lr.default_rules to "all". Check for a valid lr.default_rules value. * src/lalr.c (state_lookahead_tokens_count): If lr.default_rules is "accepting", then only mark the accepting state as consistent. (initialize_LA): Tell state_lookahead_tokens_count whether lr.default_rules is "accepting". * src/tables.c (action_row): If lr.default_rules is not "all", then disable default rules in inconsistent states. * src/print.c (print_reductions): Use this opportunity to perform some assertions about whether lr.default_rules was obeyed correctly. * tests/local.at (AT_TEST_TABLES_AND_PARSE): New macro that helps with checking the parser tables for a grammar. * tests/input.at (%define lr.default_rules invalid values): New test group. * tests/reduce.at (AT_TEST_LR_DEFAULT_RULES): New macro using AT_TEST_TABLES_AND_PARSE. (`no %define lr.default_rules'): New test group generated by AT_TEST_LR_DEFAULT_RULES. (`%define lr.default_rules "all"'): Likewise. (`%define lr.default_rules "consistent"'): Likewise. (`%define lr.default_rules "accepting"'): Likewise. --- ChangeLog | 29 +++++++++ src/lalr.c | 41 ++++++++---- src/print.c | 29 ++++++--- src/reader.c | 13 +++- src/tables.c | 13 +++- tests/input.at | 18 ++++++ tests/local.at | 163 +++++++++++++++++++++++++++++++++++++++++++++++- tests/reduce.at | 147 ++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 429 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index eb240df7..fdbbba9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2009-04-20 Joel E. Denny + + Implement %define lr.default_rules. + Its value describes the states that are permitted to contain + default rules: "all", "consistent", or "accepting". + * src/reader.c (reader): Default lr.default_rules to "all". + Check for a valid lr.default_rules value. + * src/lalr.c (state_lookahead_tokens_count): If lr.default_rules + is "accepting", then only mark the accepting state as + consistent. + (initialize_LA): Tell state_lookahead_tokens_count whether + lr.default_rules is "accepting". + * src/tables.c (action_row): If lr.default_rules is not "all", + then disable default rules in inconsistent states. + * src/print.c (print_reductions): Use this opportunity to + perform some assertions about whether lr.default_rules was + obeyed correctly. + * tests/local.at (AT_TEST_TABLES_AND_PARSE): New macro that + helps with checking the parser tables for a grammar. + * tests/input.at (%define lr.default_rules invalid values): New + test group. + * tests/reduce.at (AT_TEST_LR_DEFAULT_RULES): New macro using + AT_TEST_TABLES_AND_PARSE. + (`no %define lr.default_rules'): New test group generated by + AT_TEST_LR_DEFAULT_RULES. + (`%define lr.default_rules "all"'): Likewise. + (`%define lr.default_rules "consistent"'): Likewise. + (`%define lr.default_rules "accepting"'): Likewise. + 2009-04-20 Akim Demaille Consistently refer to Yacc, not YACC. diff --git a/src/lalr.c b/src/lalr.c index a214dc57..9f5d43f3 100644 --- a/src/lalr.c +++ b/src/lalr.c @@ -1,7 +1,7 @@ /* Compute lookahead criteria for Bison. Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005, - 2006, 2007 Free Software Foundation, Inc. + 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -36,6 +36,7 @@ #include "getargs.h" #include "gram.h" #include "lalr.h" +#include "muscle_tab.h" #include "nullable.h" #include "reader.h" #include "relation.h" @@ -336,22 +337,30 @@ compute_lookahead_tokens (void) `----------------------------------------------------*/ static int -state_lookahead_tokens_count (state *s) +state_lookahead_tokens_count (state *s, bool default_rule_only_for_accept) { int n_lookahead_tokens = 0; reductions *rp = s->reductions; transitions *sp = s->transitions; - /* We need a lookahead either to distinguish different - reductions (i.e., there are two or more), or to distinguish a - reduction from a shift. Otherwise, it is straightforward, - and the state is `consistent'. There is no need to check that - transition 0 hasn't been disabled before checking if it is a - shift since transitions are only disabled during conflict - resolution, and that hasn't happened yet. */ + /* Transitions are only disabled during conflict resolution, and that + hasn't happened yet, so there should be no need to check that + transition 0 hasn't been disabled before checking if it is a shift. + However, this check was performed at one time, so we leave it as an + aver. */ aver (sp->num == 0 || !TRANSITION_IS_DISABLED (sp, 0)); + + /* We need a lookahead either to distinguish different reductions + (i.e., there are two or more), or to distinguish a reduction from a + shift. Otherwise, it is straightforward, and the state is + `consistent'. However, for states that have any rules, treat only + the accepting state as consistent (since there is never a lookahead + token that makes sense there, and so no lookahead token should be + read) if the user has otherwise disabled default rules. */ if (rp->num > 1 - || (rp->num == 1 && sp->num && TRANSITION_IS_SHIFT (sp, 0))) + || (rp->num == 1 && sp->num && TRANSITION_IS_SHIFT (sp, 0)) + || (rp->num == 1 && rp->rules[0]->number != 0 + && default_rule_only_for_accept)) n_lookahead_tokens += rp->num; else s->consistent = 1; @@ -369,11 +378,18 @@ initialize_LA (void) { state_number i; bitsetv pLA; + bool default_rule_only_for_accept; + { + char *default_rules = muscle_percent_define_get ("lr.default_rules"); + default_rule_only_for_accept = 0 == strcmp (default_rules, "accepting"); + free (default_rules); + } /* Compute the total number of reductions requiring a lookahead. */ nLA = 0; for (i = 0; i < nstates; i++) - nLA += state_lookahead_tokens_count (states[i]); + nLA += + state_lookahead_tokens_count (states[i], default_rule_only_for_accept); /* Avoid having to special case 0. */ if (!nLA) nLA = 1; @@ -385,7 +401,8 @@ initialize_LA (void) require lookahead tokens. */ for (i = 0; i < nstates; i++) { - int count = state_lookahead_tokens_count (states[i]); + int count = + state_lookahead_tokens_count (states[i], default_rule_only_for_accept); if (count) { states[i]->reductions->lookahead_tokens = pLA; diff --git a/src/print.c b/src/print.c index ddd76a60..413896c2 100644 --- a/src/print.c +++ b/src/print.c @@ -1,7 +1,7 @@ /* Print information on generated parser, for bison, - Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005, 2007 - Free Software Foundation, Inc. + Copyright (C) 1984, 1986, 1989, 2000, 2001, 2002, 2003, 2004, 2005, + 2007, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -31,6 +31,7 @@ #include "getargs.h" #include "gram.h" #include "lalr.h" +#include "muscle_tab.h" #include "print.h" #include "reader.h" #include "reduce.h" @@ -244,6 +245,7 @@ print_reductions (FILE *out, state *s) rule *default_rule = NULL; size_t width = 0; int i, j; + bool non_default_action = false; if (reds->num == 0) return; @@ -296,6 +298,8 @@ print_reductions (FILE *out, state *s) { bool defaulted = false; bool count = bitset_test (no_reduce_set, i); + if (count) + non_default_action = true; for (j = 0; j < reds->num; ++j) if (bitset_test (reds->lookahead_tokens[j], i)) @@ -303,15 +307,19 @@ print_reductions (FILE *out, state *s) if (! count) { if (reds->rules[j] != default_rule) - print_reduction (out, width, - symbols[i]->tag, - reds->rules[j], true); + { + non_default_action = true; + print_reduction (out, width, + symbols[i]->tag, + reds->rules[j], true); + } else defaulted = true; count = true; } else { + non_default_action = true; if (defaulted) print_reduction (out, width, symbols[i]->tag, @@ -325,8 +333,15 @@ print_reductions (FILE *out, state *s) } if (default_rule) - print_reduction (out, width, - _("$default"), default_rule, true); + { + char *default_rules = muscle_percent_define_get ("lr.default_rules"); + print_reduction (out, width, _("$default"), default_rule, true); + aver (0 == strcmp (default_rules, "all") + || (0 == strcmp (default_rules, "consistent") + && !non_default_action) + || (reds->num == 1 && reds->rules[0]->number == 0)); + free (default_rules); + } } diff --git a/src/reader.c b/src/reader.c index 7758c772..68e8b44e 100644 --- a/src/reader.c +++ b/src/reader.c @@ -1,7 +1,7 @@ /* Input parser for Bison Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000, 2001, 2002, 2003, - 2005, 2006, 2007 Free Software Foundation, Inc. + 2005, 2006, 2007, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -555,6 +555,17 @@ reader (void) gram_scanner_initialize (); gram_parse (); + muscle_percent_define_default ("lr.default_rules", "all"); + + /* Check front-end %define variable values. */ + { + static char const * const values[] = { + "lr.default_rules", "all", "consistent", "accepting", NULL, + NULL + }; + muscle_percent_define_check_values (values); + } + if (! complaint_issued) check_and_convert_grammar (); diff --git a/src/tables.c b/src/tables.c index e22b0892..958e77b1 100644 --- a/src/tables.c +++ b/src/tables.c @@ -1,7 +1,7 @@ /* Output the generated parsing program for Bison. Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, - 2005, 2006 Free Software Foundation, Inc. + 2005, 2006, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -30,6 +30,7 @@ #include "getargs.h" #include "gram.h" #include "lalr.h" +#include "muscle_tab.h" #include "reader.h" #include "symtab.h" #include "tables.h" @@ -303,6 +304,16 @@ action_row (state *s) actrow[sym->number] = ACTION_NUMBER_MINIMUM; } + /* Turn off default rules where requested by the user. See + state_lookahead_tokens_count in lalr.c to understand when states are + labeled as consistent. */ + { + char *default_rules = muscle_percent_define_get ("lr.default_rules"); + if (0 != strcmp (default_rules, "all") && !s->consistent) + nodefault = true; + free (default_rules); + } + /* Now find the most common reduction and make it the default action for this state. */ diff --git a/tests/input.at b/tests/input.at index 4389e9d2..9edf6132 100644 --- a/tests/input.at +++ b/tests/input.at @@ -867,6 +867,24 @@ AT_BISON_CHECK([[Input.y]], [1], [], AT_CLEANUP +## ----------------------------------------- ## +## %define lr.default_rules invalid values. ## +## ----------------------------------------- ## + +AT_SETUP([[%define lr.default_rules invalid values]]) + +AT_DATA([[input.y]], +[[%define lr.default_rules "bogus" +%% +start: ; +]]) + +AT_BISON_CHECK([[input.y]], [[1]], [[]], +[[input.y:1.9-24: invalid value for %define variable `lr.default_rules': `bogus' +]]) + +AT_CLEANUP + ## ------------------------ ## ## %define enum variables. ## ## ------------------------ ## diff --git a/tests/local.at b/tests/local.at index 163de2ef..91e0f20e 100644 --- a/tests/local.at +++ b/tests/local.at @@ -1,8 +1,8 @@ # Process this -*- Autotest -*- file with autom4te. # Macros for the GNU Bison Test suite. -# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, -# Inc. +# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 @@ -329,6 +329,165 @@ m4_define([AT_FULL_COMPILE], m4_define([AT_PARSER_CHECK], [AT_CHECK([$5 $PREPARSER $1], [$2], [$3], [$4])]) +# AT_TEST_TABLES_AND_PARSE(TITLE, COND-VALUE, TEST-SPEC, +# DECLS, GRAMMAR, INPUT, +# BISON-STDERR, TABLES-OR-LAST-STATE, +# [OTHER-CHECKS], +# [PARSER-EXIT-VALUE], +# [PARSER-STDOUT], [PARSER-STDERR]) +# ------------------------------------------------------------- +# Using TITLE as the test group title, check the generated parser tables +# and parser for a specified grammar file under a condition labeled by +# COND-VALUE. +# +# TEST-SPEC is a comma-delimited list of attributes of this test. Each +# recognized attribute is described below where it is relevant. +# +# Insert DECLS and GRAMMAR into the declarations and grammar section of +# the grammar file. Insert basic yyerror, yylex, and main function +# definitions as well. Hardcode yylex to return the (possibly empty) +# comma-delimited series of tokens in INPUT followed by token 0. +# +# If TEST-SPEC contains the attribute no-xml, then invoke bison using +# AT_BISON_CHECK_NO_XML. Otherwise, invoke bison using AT_BISON_CHECK. +# On the bison command-line, specify `--report=all --defines'. Check +# that Bison exits with value 0, has no stdout, and has stderr +# BISON-STDERR. +# +# If TEST-SPEC contains the attribute `last-state', check that the value +# of TABLES-OR-LAST-STATE is the index of the last state generated for +# the grammar; in other words, check the number of states (minus one). +# Otherwise, check that everything in the `.output' file starting with +# the definition of state 0 is the same as the entire value of +# TABLES-OR-LAST-STATE. +# +# Expand the M4 in OTHER-CHECKS to perform additional checks of the +# `.output' file, which is named `input.output', and/or grammar file, +# which is named `input.y'. +# +# Finally, compile the generated parser and then run it using +# AT_PARSER_CHECK with PARSER-EXIT-VALUE, PARSER-STDOUT, and +# PARSER-STDERR as the 2nd-4th arguments. +# +# As a precondition, you must properly double-quote all arguments that +# are to be interpreted as strings. +# +# AT_COND_CASE (when appearing in single-quoted segments of arguments) +# invokes m4_case with its own arguments but COND-VALUE inserted as the +# first argument. This is useful, for example, when wrapping multiple +# AT_TEST_TABLES_AND_PARSE invocations, each representing a different +# condition, in another macro. +# +# For example: +# +# # AT_TEST_SYNTAX_ERROR(DESCRIPTION, DECLS, GRAMMAR, INPUT, LAST-STATE, +# # PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR) +# # --------------------------------------------------------------------- +# m4_define([AT_TEST_SYNTAX_ERROR], +# [ +# AT_TEST_TABLES_AND_PARSE([$1[ with %error-verbose]], [[verbose]], +# [[last-state]], +# [[%error-verbose ]$2], [$3], [$4], +# [[]], [$5], [], [$6], [$7], [$8]) +# AT_TEST_TABLES_AND_PARSE([$1[ with no %error-verbose]], [[no verbose]], +# [[last-state]], +# [$2], [$3], [$4], +# [[]], [$5], [], [$6], [$7], [$8]) +# ]) +# +# AT_TEST_SYNTAX_ERROR([[Single Char Grammar]], +# [[%token 'b']], [[start: 'a' ;]], [['a', 'b']], +# [[3]], +# [[1]], [[]], +# [AT_COND_CASE([[no verbose]], +# [[syntax error +# ]], +# [[syntax error, unexpected 'b', expecting $end +# ]])]) +m4_define([AT_TEST_TABLES_AND_PARSE], +[_AT_TEST_TABLES_AND_PARSE($[1], $[@], $@)]) + +m4_define([_AT_TEST_TABLES_AND_PARSE], +[m4_pushdef([AT_COND_CASE], [m4_case([$4], $][@)]) + +AT_SETUP([$3]) + +AT_DATA_GRAMMAR([[input.y]], +[[%code { + #include + static void yyerror (char const *msg); + static int yylex (void); +} + +]$6[ + +%% + +]$7[ + +%% + +static void +yyerror (char const *msg) +{ + fprintf (stderr, "%s\n", msg); +} + +static int +yylex (void) +{ + static int const input[] = { + ]m4_if([$8], [], [], [$8], [[]], [], [$8[, ]])[0 + }; + static int const *inputp = input; + return *inputp++; +} + +int +main (void) +{ + return yyparse (); +} +]]) + +# AT_CHECK invokes AS_ESCAPE before expanding macros, so it corrupts some +# special characters in the macros. To avoid this, expand now and pass it +# the result with proper string quotation. Assume args 9 thru 14 expand to +# properly quoted strings. + +# Pass plenty of options, to exercise plenty of code, even if we +# don't actually check the output. But SEGV is watching us, and +# so might do dmalloc. +m4_if(m4_index(m4_quote($5), [no-xml]), -1, + [AT_BISON_CHECK], + [AT_BISON_CHECK_NO_XML])([[--report=all --defines -o input.c input.y]], + [0], [], m4_dquote($9)) + +# Sigh. Some M4's can't reference arg 10 directly. +m4_pushdef([arg10], m4_car(m4_shiftn(9, $@))) +m4_if(m4_index(m4_quote($5), [last-state]), -1, + [AT_CHECK([[sed -n '/^state 0$/,$p' input.output]], [[0]], + m4_dquote(arg10))], + [AT_CHECK([[sed -n 's/^state //p' input.output | tail -1]], [[0]], + m4_dquote(arg10)[[ +]])]) +m4_popdef([arg10]) + +m4_if($#, 10, [], m4_car(m4_shiftn(10, $@))) + +AT_COMPILE([[input]]) + +m4_pushdef([AT_EXPAND_ARGS], [$][*]) +m4_pushdef([AT_DQUOTE_EACH], [[[$1]]m4_if($][#, 1, [], [, AT_DQUOTE_EACH(m4_shift($2))])]) + +AT_PARSER_CHECK([[./input]]m4_if($#, 10, [], $#, 11, [], [, AT_DQUOTE_EACH(AT_EXPAND_ARGS(m4_shiftn(11, $@)))])) + +m4_popdef([AT_DQUOTE_EACH]) +m4_popdef([AT_EXPAND_ARGS]) + +AT_CLEANUP + +m4_popdef([AT_COND_CASE])]) diff --git a/tests/reduce.at b/tests/reduce.at index 5fe650a8..058d7c0d 100644 --- a/tests/reduce.at +++ b/tests/reduce.at @@ -1,5 +1,6 @@ # Exercising Bison Grammar Reduction. -*- Autotest -*- -# Copyright (C) 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2001, 2002, 2007, 2008, 2009 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 @@ -355,3 +356,147 @@ input.y:3.1-3: fatal error: start symbol exp does not derive any sentence ]]) AT_CLEANUP + + + +## -------------------------- ## +## %define lr.default_rules. ## +## -------------------------- ## + +# AT_TEST_LR_DEFAULT_RULES(GRAMMAR, INPUT, TABLES) +# ------------------------------------------------ +m4_define([AT_TEST_LR_DEFAULT_RULES], +[ +AT_TEST_TABLES_AND_PARSE([[no %define lr.default_rules]], + [[all]], [[]], + [[]], + [$1], [$2], [[]], [$3]) +AT_TEST_TABLES_AND_PARSE([[%define lr.default_rules "all"]], + [[all]], [[]], + [[%define lr.default_rules "all"]], + [$1], [$2], [[]], [$3]) +AT_TEST_TABLES_AND_PARSE([[%define lr.default_rules "consistent"]], + [[consistent]], [[]], + [[%define lr.default_rules "consistent"]], + [$1], [$2], [[]], [$3]) +AT_TEST_TABLES_AND_PARSE([[%define lr.default_rules "accepting"]], + [[accepting]], [[]], + [[%define lr.default_rules "accepting"]], + [$1], [$2], [[]], [$3]) +]) + +AT_TEST_LR_DEFAULT_RULES([[ +/* The start state is consistent and has a shift on 'a' and no reductions. + After pushing the b below, enter an inconsistent state that has a shift and + one reduction with one lookahead. */ +start: + a b + | a b 'a' + | a c 'b' + ; + +/* After shifting this 'a', enter a consistent state that has no shift and 1 + reduction with multiple lookaheads. */ +a: 'a' ; + +/* After the previous reduction, enter an inconsistent state that has no shift + and multiple reductions. The first reduction has more lookaheads than the + second, so the first should always be preferred as the default rule if + enabled. The second reduction has one lookahead. */ +b: ; +c: ; +]], +dnl Visit each state mentioned above. +[['a', 'a']], +[[state 0 + + 0 $accept: . start $end + 1 start: . a b + 2 | . a b 'a' + 3 | . a c 'b' + 4 a: . 'a' + + 'a' shift, and go to state 1 + + start go to state 2 + a go to state 3 + + +state 1 + + 4 a: 'a' .]AT_COND_CASE([[accepting]], [[ [$end, 'a', 'b'] + + $end reduce using rule 4 (a) + 'a' reduce using rule 4 (a) + 'b' reduce using rule 4 (a)]], [[ + + $default reduce using rule 4 (a)]])[ + + +state 2 + + 0 $accept: start . $end + + $end shift, and go to state 4 + + +state 3 + + 1 start: a . b + 2 | a . b 'a' + 3 | a . c 'b' + 5 b: . [$end, 'a'] + 6 c: . ['b']]AT_COND_CASE([[all]], [[ + + 'b' reduce using rule 6 (c) + $default reduce using rule 5 (b)]], [[ + + $end reduce using rule 5 (b) + 'a' reduce using rule 5 (b) + 'b' reduce using rule 6 (c)]])[ + + b go to state 5 + c go to state 6 + + +state 4 + + 0 $accept: start $end . + + $default accept + + +state 5 + + 1 start: a b . [$end] + 2 | a b . 'a' + + 'a' shift, and go to state 7 + + ]AT_COND_CASE([[all]], [[$default]], [[$end]])[ reduce using rule 1 (start) + + +state 6 + + 3 start: a c . 'b' + + 'b' shift, and go to state 8 + + +state 7 + + 2 start: a b 'a' .]AT_COND_CASE([[accepting]], [[ [$end] + + $end reduce using rule 2 (start)]], [[ + + $default reduce using rule 2 (start)]])[ + + +state 8 + + 3 start: a c 'b' .]AT_COND_CASE([[accepting]], [[ [$end] + + $end reduce using rule 3 (start)]], [[ + + $default reduce using rule 3 (start)]])[ +]]) From 166366b28f579dfb991f8f6fca323847bcc1eb65 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Tue, 21 Apr 2009 02:10:57 -0400 Subject: [PATCH 063/404] Add new files for IELR and canonical LR implementation. * src/AnnotationList.c: New. * src/AnnotationList.h: New. * src/InadequacyList.c: New. * src/InadequacyList.h: New. * src/Sbitset.c: New. * src/Sbitset.h: New. * src/ielr.c: New. * src/ielr.h: New. --- ChangeLog | 12 + src/AnnotationList.c | 811 ++++++++++++++++++++++++++++ src/AnnotationList.h | 177 +++++++ src/InadequacyList.c | 76 +++ src/InadequacyList.h | 135 +++++ src/Sbitset.c | 78 +++ src/Sbitset.h | 87 +++ src/ielr.c | 1200 ++++++++++++++++++++++++++++++++++++++++++ src/ielr.h | 46 ++ 9 files changed, 2622 insertions(+) create mode 100644 src/AnnotationList.c create mode 100644 src/AnnotationList.h create mode 100644 src/InadequacyList.c create mode 100644 src/InadequacyList.h create mode 100644 src/Sbitset.c create mode 100644 src/Sbitset.h create mode 100644 src/ielr.c create mode 100644 src/ielr.h diff --git a/ChangeLog b/ChangeLog index fdbbba9c..962f5342 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2009-04-21 Joel E. Denny + + Add new files for IELR and canonical LR implementation. + * src/AnnotationList.c: New. + * src/AnnotationList.h: New. + * src/InadequacyList.c: New. + * src/InadequacyList.h: New. + * src/Sbitset.c: New. + * src/Sbitset.h: New. + * src/ielr.c: New. + * src/ielr.h: New. + 2009-04-20 Joel E. Denny Implement %define lr.default_rules. diff --git a/src/AnnotationList.c b/src/AnnotationList.c new file mode 100644 index 00000000..a603102a --- /dev/null +++ b/src/AnnotationList.c @@ -0,0 +1,811 @@ +/* IELR's inadequacy annotation list. + + Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of Bison, the GNU Compiler Compiler. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include "system.h" + +#include "AnnotationList.h" +#include "lalr.h" +#include "ielr.h" + +/** + * \pre + * - annotations_obstackp != NULL. + * \post + * - \c result is a new \c AnnotationList with one node whose: + * - \c inadequacyNode member is \c NULL. + * - \c contributions member is allocated with \c contribution_count + * uninitialized elements. + * - All memory was allocated on \c annotations_obstackp. + */ +static AnnotationList* +AnnotationList__alloc_on_obstack (ContributionIndex contribution_count, + struct obstack *annotations_obstackp) +{ + AnnotationList *result; + size_t contributions_size = + contribution_count * sizeof result->contributions[0]; + result = obstack_alloc (annotations_obstackp, + offsetof (AnnotationList, contributions) + + contributions_size); + result->next = NULL; + result->inadequacyNode = NULL; + return result; +} + +/** + * \pre + * - self != NULL. + * - 0 <= ci < self->inadequacyNode->contributionCount. + * \post + * - \c result = true iff contribution \c ci in \c self represents an + * "always" contribution. + */ +static bool +AnnotationList__isContributionAlways (AnnotationList const *self, + ContributionIndex ci) +{ + aver (0 <= ci && ci < self->inadequacyNode->contributionCount); + return self->contributions[ci] == NULL; +} + +/** + * \pre + * - \c self is a single node. + * - \c self annotates the same state as every other node in \c list, and + * that state has \c nitems kernel items. + * \post + * - If the list \c list already contains an identical annotation to \c self, + * \c self was discarded, \c result is false, and the caller is responsible + * for the memory of \c self. + * - Otherwise, \c list now contains the node \c self, \c result is true, and + * \c list assumes responsibility for the memory of \c self. + * - The sort in \c list is: + * - Sort in reverse order on memory address of the associated inadequacy + * node. Because memory is usually allocated in ascending order (FIXME: + * Is this true enough? Should we keep some sort of global index to + * guarantee it?), this should mean that the insertion position within an + * annotation list is usually near the beginning with other annotations + * associated with the same inadequacy. + * - Next, sort on the first contribution that is different as follows: + * - Sort an always-contribution before a never-contribution before a + * potential-contribution. + * - Two always-contributions are identical. + * - Two never-contributions are identical. + * - For two potential-contributions, sort on the contributions' kernel + * item bitsets interpreted as binary numbers. + * - The sorting has a few effects: + * - It accelerates elimination of identical annotations during insertion. + * - It determines how the output of \c AnnotationList__debug is sorted. + * - Other than that, it's probably not important. + */ +static bool +AnnotationList__insertInto (AnnotationList *self, AnnotationList **list, + size_t nitems) +{ + AnnotationList **node; + for (node = list; *node; node = &(*node)->next) + { + int cmp = 0; + ContributionIndex ci; + if (self->inadequacyNode < (*node)->inadequacyNode) + cmp = 1; + else if ((*node)->inadequacyNode < self->inadequacyNode) + cmp = -1; + else + for (ci = 0; + cmp == 0 && ci < self->inadequacyNode->contributionCount; + ++ci) + { + if (AnnotationList__isContributionAlways (self, ci)) + { + if (!AnnotationList__isContributionAlways (*node, ci)) + cmp = -1; + } + else if (AnnotationList__isContributionAlways (*node, ci)) + cmp = 1; + else + { + size_t item; + for (item = 0; cmp == 0 && item < nitems; ++item) + { + if (!Sbitset__test (self->contributions[ci], item)) + { + if (Sbitset__test ((*node)->contributions[ci], item)) + cmp = -1; + } + else if (!Sbitset__test ((*node)->contributions[ci], item)) + cmp = 1; + } + } + } + if (cmp < 0) + { + self->next = *node; + *node = self; + break; + } + else if (cmp == 0) + { + self = NULL; + break; + } + } + if (!*node) + *node = self; + return self != NULL; +} + +static bitset +AnnotationList__compute_shift_tokens (transitions *trans) +{ + bitset shift_tokens = bitset_create (ntokens, BITSET_FIXED); + int i; + FOR_EACH_SHIFT (trans, i) + bitset_set (shift_tokens, TRANSITION_SYMBOL (trans, i)); + return shift_tokens; +} + +static bitset +AnnotationList__compute_conflicted_tokens (bitset shift_tokens, + reductions *reds) +{ + bitset conflicted_tokens = bitset_create (ntokens, BITSET_FIXED); + bitset conflicted_tokens_rule = bitset_create (ntokens, BITSET_FIXED); + bitset tokens = bitset_create (ntokens, BITSET_FIXED); + int i; + + bitset_copy (tokens, shift_tokens); + for (i = 0; i < reds->num; ++i) + { + bitset_and (conflicted_tokens_rule, tokens, reds->lookahead_tokens[i]); + bitset_or (conflicted_tokens, + conflicted_tokens, conflicted_tokens_rule); + bitset_or (tokens, tokens, reds->lookahead_tokens[i]); + /* Check that rules are sorted on rule number or the next step in + AnnotationList__compute_from_inadequacies will misbehave. */ + aver (i == 0 || reds->rules[i-1] < reds->rules[i]); + } + + bitset_free (tokens); + bitset_free (conflicted_tokens_rule); + + return conflicted_tokens; +} + +static bool +AnnotationList__compute_lhs_contributions (state *s, rule *the_rule, + symbol_number conflicted_token, + bitsetv follow_kernel_items, + bitsetv always_follows, + state ***predecessors, + bitset **item_lookahead_sets, + Sbitset *items, + struct obstack + *annotations_obstackp) +{ + goto_number lhs_goto = map_goto (s->number, the_rule->lhs->number); + if (bitset_test (always_follows[lhs_goto], conflicted_token)) + return true; + *items = Sbitset__new_on_obstack (s->nitems, annotations_obstackp); + { + bitset_iterator biter_item; + bitset_bindex item; + BITSET_FOR_EACH (biter_item, follow_kernel_items[lhs_goto], item, 0) + if (ielr_item_has_lookahead (s, 0, item, conflicted_token, + predecessors, item_lookahead_sets)) + Sbitset__set (*items, item); + } + return false; +} + +static void +AnnotationList__computePredecessorAnnotations (AnnotationList *self, state *s, + bitsetv follow_kernel_items, + bitsetv always_follows, + state ***predecessors, + bitset **item_lookahead_sets, + AnnotationList + **annotation_lists, + AnnotationIndex + *annotation_counts, + struct obstack + *annotations_obstackp) +{ + state **predecessor; + for (predecessor = predecessors[s->number]; *predecessor; ++predecessor) + { + AnnotationList *annotation_node = + AnnotationList__alloc_on_obstack ( + self->inadequacyNode->contributionCount, annotations_obstackp); + annotation_node->inadequacyNode = self->inadequacyNode; + bool potential_contribution = false; + bitset *lookaheads = NULL; + { + ContributionIndex ci; + for (ci = 0; ci < self->inadequacyNode->contributionCount; ++ci) + { + symbol_number contribution_token = + InadequacyList__getContributionToken (self->inadequacyNode, ci) + ->number; + if (AnnotationList__isContributionAlways (self, ci)) + { + annotation_node->contributions[ci] = NULL; + continue; + } + annotation_node->contributions[ci] = + Sbitset__new_on_obstack ((*predecessor)->nitems, + annotations_obstackp); + { + size_t predecessor_item = 0; + Sbitset sbiter_item; + Sbitset__Index self_item; + SBITSET__FOR_EACH (self->contributions[ci], s->nitems, + sbiter_item, self_item) + { + /* If this kernel item is the beginning of a RHS, it must be + the kernel item in the start state, and so it has an empty + lookahead set. Thus, it can't contribute to inadequacies, + and so it should never have been identified as a + contribution. If, instead, this kernel item is the + successor of the start state's kernel item, the lookahead + set is still empty, and so it also should never have been + identified as a contribution. This situation is fortunate + because we want to avoid the - 2 below in both cases. */ + aver (s->items[self_item] > 1); + /* If this kernel item is next to the beginning of the RHS, + then check all of the predecessor's goto follows for the + LHS. */ + if (item_number_is_rule_number (ritem[s->items[self_item] + - 2])) + { + Sbitset items; + unsigned int rulei; + for (rulei = s->items[self_item]; + !item_number_is_rule_number (ritem[rulei]); + ++rulei) + ; + if (AnnotationList__compute_lhs_contributions ( + *predecessor, + &rules[item_number_as_rule_number (ritem[rulei])], + contribution_token, + follow_kernel_items, always_follows, predecessors, + item_lookahead_sets, &items, annotations_obstackp)) + { + obstack_free (annotations_obstackp, + annotation_node->contributions[ci]); + annotation_node->contributions[ci] = NULL; + break; + } + else + { + Sbitset__or (annotation_node->contributions[ci], + annotation_node->contributions[ci], + items, (*predecessor)->nitems); + obstack_free (annotations_obstackp, items); + } + } + /* If this kernel item is later in the RHS, then check the + predecessor item's lookahead set. */ + else + { + /* We don't have to start the predecessor item search at + the beginning every time because items from both + states are sorted by their indices in ritem. */ + for (; + predecessor_item < (*predecessor)->nitems; + ++predecessor_item) + if ((*predecessor)->items[predecessor_item] + == s->items[self_item] - 1) + break; + aver (predecessor_item != (*predecessor)->nitems); + if (ielr_item_has_lookahead (*predecessor, 0, + predecessor_item, + contribution_token, + predecessors, + item_lookahead_sets)) + Sbitset__set (annotation_node->contributions[ci], + predecessor_item); + } + } + } + if (annotation_node->contributions[ci]) + { + Sbitset biter; + Sbitset__Index i; + SBITSET__FOR_EACH (annotation_node->contributions[ci], + (*predecessor)->nitems, biter, i) + { + potential_contribution = true; + if (!lookaheads) + { + size_t j; + lookaheads = xnmalloc ((*predecessor)->nitems, + sizeof *lookaheads); + for (j = 0; j < (*predecessor)->nitems; ++j) + lookaheads[j] = NULL; + } + if (!lookaheads[i]) + lookaheads[i] = bitset_create (ntokens, BITSET_FIXED); + bitset_set (lookaheads[i], contribution_token); + } + } + } + } + + /* If the predecessor has any contributions besides just "always" and + "never" contributions: + - If the dominant contribution is split-stable, the annotation could + not affect merging on this predecessor state or its eventual + predecessor states. Moreover, all contributions that affect + whether the dominant contribution remains dominant must be "always" + or "never" contributions in order for the dominant contribution to + be split-stable. Thus, the dominant contribution computation result + in eventual successor states will not be affected by lookaheads + tracked for this predecessor state. (Also, as in the isocore + compatibility test, we depend on the fact that isocores with equal + dominant contributions will have the same dominant contribution when + merged. Otherwise, we might have to worry that the presence of a + potential contribution might somehow be the culprit of that behavior + and thus need to be tracked regardless of the split stability of the + dominant contribution.) Thus, go ahead and discard the annotation + to save space now plus time during state splitting. + - Otherwise, record the annotation, and compute any resulting + annotations needed on predecessor states. */ + if (potential_contribution) + { + if (ContributionIndex__none + != AnnotationList__computeDominantContribution ( + annotation_node, (*predecessor)->nitems, lookaheads, true)) + { + obstack_free (annotations_obstackp, annotation_node); + annotation_node = NULL; + } + { + size_t i; + for (i = 0; i < (*predecessor)->nitems; ++i) + if (lookaheads[i]) + bitset_free (lookaheads[i]); + free (lookaheads); + } + if (annotation_node) + { + if (AnnotationList__insertInto (annotation_node, + &annotation_lists[(*predecessor) + ->number], + (*predecessor)->nitems)) + { + ++annotation_counts[(*predecessor)->number]; + AnnotationList__computePredecessorAnnotations ( + annotation_node, *predecessor, + follow_kernel_items, always_follows, predecessors, + item_lookahead_sets, annotation_lists, annotation_counts, + annotations_obstackp); + } + else + obstack_free (annotations_obstackp, annotation_node); + } + } + else + obstack_free (annotations_obstackp, annotation_node); + } +} + +void +AnnotationList__compute_from_inadequacies (state *s, + bitsetv follow_kernel_items, + bitsetv always_follows, + state ***predecessors, + bitset **item_lookahead_sets, + InadequacyList **inadequacy_lists, + AnnotationList **annotation_lists, + AnnotationIndex *annotation_counts, + ContributionIndex + *max_contributionsp, + struct obstack + *annotations_obstackp) +{ + bitsetv all_lookaheads; + bitset shift_tokens; + bitset conflicted_tokens; + bitset_iterator biter_conflict; + bitset_bindex conflicted_token; + + /* Return an empty list if s->lookahead_tokens = NULL. */ + if (s->consistent) + return; + + all_lookaheads = bitsetv_create (s->nitems, ntokens, BITSET_FIXED); + bitsetv_ones (all_lookaheads); + shift_tokens = AnnotationList__compute_shift_tokens (s->transitions); + conflicted_tokens = + AnnotationList__compute_conflicted_tokens (shift_tokens, s->reductions); + + /* Add an inadequacy annotation for each conflicted_token. */ + BITSET_FOR_EACH (biter_conflict, conflicted_tokens, conflicted_token, 0) + { + AnnotationList *annotation_node; + /* FIXME: Would a BITSET_FRUGAL or BITEST_SPARSE be more efficient? Now + or convert it inside InadequacyList__new_conflict? */ + bitset actions = bitset_create (s->reductions->num + 1, BITSET_FIXED); + ContributionIndex contribution_count = 0; + bool potential_contribution = false; + + /* Allocate the annotation node. */ + { + int rule_i; + for (rule_i = 0; rule_i < s->reductions->num; ++rule_i) + if (bitset_test (s->reductions->lookahead_tokens[rule_i], + conflicted_token)) + ++contribution_count; + if (bitset_test (shift_tokens, conflicted_token)) + ++contribution_count; + annotation_node = + AnnotationList__alloc_on_obstack (contribution_count, + annotations_obstackp); + } + + /* Add a contribution for each reduction that has conflicted_token as a + lookahead. */ + { + ContributionIndex ci = 0; + int item_i = 0; + int rule_i; + for (rule_i = 0; rule_i < s->reductions->num; ++rule_i) + { + rule *the_rule = s->reductions->rules[rule_i]; + if (bitset_test (s->reductions->lookahead_tokens[rule_i], + conflicted_token)) + { + bitset_set (actions, rule_i); + /* If this reduction is on a kernel item, just add it. */ + if (!item_number_is_rule_number (the_rule->rhs[0])) + { + annotation_node->contributions[ci] = + Sbitset__new_on_obstack (s->nitems, + annotations_obstackp); + /* Catch item_i up to rule_i. This works because both are + sorted on rule number. */ + while (!item_number_is_rule_number ( + ritem[s->items[item_i]]) + || item_number_as_rule_number ( + ritem[s->items[item_i]]) + != the_rule->number) + { + ++item_i; + aver (item_i < s->nitems); + } + Sbitset__set (annotation_node->contributions[ci], item_i); + } + /* Otherwise, add the kernel items whose lookahead sets + contribute the conflicted token to this reduction's + lookahead set. */ + else if (AnnotationList__compute_lhs_contributions ( + s, the_rule, conflicted_token, follow_kernel_items, + always_follows, predecessors, item_lookahead_sets, + &annotation_node->contributions[ci], + annotations_obstackp)) + { + annotation_node->contributions[ci++] = NULL; + continue; + } + /* The lookahead token has to come from somewhere. */ + aver (!Sbitset__isEmpty (annotation_node->contributions[ci], + s->nitems)); + ++ci; + potential_contribution = true; + } + } + } + + /* If there are any contributions besides just "always" contributions: + - If there's also a shift contribution, record it. + - If the dominant contribution is split-stable, then the annotation + could not affect merging, so go ahead and discard the annotation and + the inadequacy to save space now plus time during state splitting. + - Otherwise, record the annotation and the inadequacy, and compute any + resulting annotations needed on predecessor states. */ + if (potential_contribution) + { + if (bitset_test (shift_tokens, conflicted_token)) + { + bitset_set (actions, s->reductions->num); + annotation_node->contributions[contribution_count - 1] = NULL; + } + { + InadequacyList *conflict_node = + InadequacyList__new_conflict (s, symbols[conflicted_token], + actions); + actions = NULL; + annotation_node->inadequacyNode = conflict_node; + if (ContributionIndex__none + != AnnotationList__computeDominantContribution ( + annotation_node, s->nitems, all_lookaheads, true)) + { + obstack_free (annotations_obstackp, annotation_node); + InadequacyList__delete (conflict_node); + } + else + { + InadequacyList__prependTo (conflict_node, + &inadequacy_lists[s->number]); + aver (AnnotationList__insertInto ( + annotation_node, &annotation_lists[s->number], + s->nitems)); + /* This aver makes sure the + AnnotationList__computeDominantContribution check above + does discard annotations in the simplest case of a S/R + conflict with no token precedence. */ + aver (!bitset_test (shift_tokens, conflicted_token) + || symbols[conflicted_token]->prec); + ++annotation_counts[s->number]; + if (contribution_count > *max_contributionsp) + *max_contributionsp = contribution_count; + AnnotationList__computePredecessorAnnotations ( + annotation_node, s, + follow_kernel_items, always_follows, predecessors, + item_lookahead_sets, annotation_lists, annotation_counts, + annotations_obstackp); + } + } + } + else + { + bitset_free (actions); + obstack_free (annotations_obstackp, annotation_node); + } + } + + bitsetv_free (all_lookaheads); + bitset_free (shift_tokens); + bitset_free (conflicted_tokens); +} + +void +AnnotationList__debug (AnnotationList const *self, size_t nitems, int spaces) +{ + AnnotationList const *a; + AnnotationIndex ai; + for (a = self, ai = 0; a; a = a->next, ++ai) + { + { + int j; + for (j = 0; j < spaces; ++j) + putc (' ', stderr); + } + fprintf (stderr, "Annotation %d (manifesting state %d):\n", + ai, a->inadequacyNode->manifestingState->number); + { + ContributionIndex ci; + bitset_bindex rulei = 0; /* init suppresses compiler warning */ + rulei = bitset_first (a->inadequacyNode->inadequacy.conflict.actions); + for (ci = 0; ci < a->inadequacyNode->contributionCount; ++ci) + { + symbol_number token = + InadequacyList__getContributionToken (a->inadequacyNode, ci) + ->number; + { + int j; + for (j = 0; j < spaces+2; ++j) + putc (' ', stderr); + } + if (ci == InadequacyList__getShiftContributionIndex ( + a->inadequacyNode)) + fprintf (stderr, "Contributes shift of token %d.\n", token); + else + { + fprintf (stderr, "Contributes token %d", token); + aver (rulei != BITSET_BINDEX_MAX); + fprintf (stderr, " as lookahead, rule number %d", + a->inadequacyNode->manifestingState + ->reductions->rules[rulei]->number); + rulei = + bitset_next (a->inadequacyNode->inadequacy.conflict.actions, + rulei+1); + if (AnnotationList__isContributionAlways (a, ci)) + fprintf (stderr, " always."); + else + { + fprintf (stderr, ", items: "); + Sbitset__fprint (a->contributions[ci], nitems, stderr); + } + fprintf (stderr, "\n"); + } + } + } + } +} + +void +AnnotationList__computeLookaheadFilter (AnnotationList const *self, + size_t nitems, + bitsetv lookahead_filter) +{ + bitsetv_zero (lookahead_filter); + for (; self; self = self->next) + { + ContributionIndex ci; + for (ci = 0; ci < self->inadequacyNode->contributionCount; ++ci) + if (!AnnotationList__isContributionAlways (self, ci)) + { + Sbitset__Index item; + Sbitset biter; + symbol_number token = + InadequacyList__getContributionToken (self->inadequacyNode, ci) + ->number; + SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item) + bitset_set (lookahead_filter[item], token); + } + } +} + +/** + * \pre + * - self != NULL. + * - \c nitems is the number of kernel items in the LR(0) state that \c self + * annotates. + * - \c lookaheads describes the lookahead sets on the kernel items of some + * isocore of the LR(0) state that \c self annotates. Either: + * - lookaheads = NULL only if the lookahead set on every kernel + * item is empty. + * - For any 0 <= i < nitems, lookaheads[i] is either: + * - \c NULL only if the lookahead set on kernel item \c i is empty. + * - The (possibly empty) lookahead set on kernel item \c i. + * - 0 <= ci < self->inadequacyNode->contributionCount. + * \post + * - \c result = true iff contribution \c ci in \c self is made by the state + * described by \c lookaheads. + */ +static bool +AnnotationList__stateMakesContribution (AnnotationList const *self, + size_t nitems, ContributionIndex ci, + bitset *lookaheads) +{ + if (AnnotationList__isContributionAlways (self, ci)) + return true; + if (!lookaheads) + return false; + { + symbol_number token = + InadequacyList__getContributionToken (self->inadequacyNode, ci)->number; + Sbitset__Index item; + Sbitset biter; + SBITSET__FOR_EACH (self->contributions[ci], nitems, biter, item) + if (lookaheads[item] && bitset_test (lookaheads[item], token)) + return true; + } + return false; +} + +ContributionIndex +AnnotationList__computeDominantContribution (AnnotationList const *self, + size_t nitems, bitset *lookaheads, + bool require_split_stable) +{ + symbol *token; + ContributionIndex const ci_shift = + InadequacyList__getShiftContributionIndex (self->inadequacyNode); + + token = self->inadequacyNode->inadequacy.conflict.token; + + /* S/R conflict. */ + if (ci_shift != ContributionIndex__none) + { + bool find_stable_domination_over_shift = false; + bool find_stable_error_action_domination = false; + { + ContributionIndex ci; + int actioni; + ContributionIndex ci_rr_dominator = ContributionIndex__none; + int shift_precedence = token->prec; + + /* If the token has no precedence set, shift is always chosen. */ + if (!shift_precedence) + return ci_shift; + + /* Figure out which reductions contribute, which of those would + dominate in a R/R comparison, and whether any reduction dominates + the shift so that the R/R comparison is actually needed. */ + for (ci = 0, actioni = bitset_first (self->inadequacyNode->inadequacy + .conflict.actions); + ci < self->inadequacyNode->contributionCount; + ++ci, actioni = bitset_next (self->inadequacyNode->inadequacy + .conflict.actions, actioni+1)) + { + int reduce_precedence = 0; + if (ci == ci_shift) + continue; + { + rule *r = self->inadequacyNode->manifestingState + ->reductions->rules[actioni]; + if (r->prec) + reduce_precedence = r->prec->prec; + } + /* If there's no need to check whether this reduction actually + contributes because the shift eliminates it from the R/R + comparison anyway, continue to the next reduction. */ + if (reduce_precedence + && (reduce_precedence < shift_precedence + || (reduce_precedence == shift_precedence + && token->assoc == right_assoc))) + continue; + if (!AnnotationList__stateMakesContribution (self, nitems, ci, + lookaheads)) + continue; + /* This uneliminated reduction contributes, so see if it can cause + an error action. */ + if (reduce_precedence == shift_precedence + && token->assoc == non_assoc) + { + /* It's not possible to find split-stable domination over + shift after a potential %nonassoc. */ + if (find_stable_domination_over_shift) + return ContributionIndex__none; + if (!require_split_stable + || AnnotationList__isContributionAlways (self, ci)) + return ContributionIndex__error_action; + find_stable_error_action_domination = true; + } + /* Consider this uneliminated contributing reduction in the R/R + comparison. */ + if (ci_rr_dominator == ContributionIndex__none) + ci_rr_dominator = ci; + /* If precedence is set for this uneliminated contributing + reduction, it dominates the shift, so try to figure out which + reduction dominates the R/R comparison. */ + if (reduce_precedence) + { + /* It's not possible to find split-stable error action + domination after a potential reduction. */ + if (find_stable_error_action_domination) + return ContributionIndex__none; + if (!require_split_stable) + return ci_rr_dominator; + if (!AnnotationList__isContributionAlways (self, + ci_rr_dominator)) + return ContributionIndex__none; + if (AnnotationList__isContributionAlways (self, ci)) + return ci_rr_dominator; + find_stable_domination_over_shift = true; + } + } + } + if (find_stable_domination_over_shift + || find_stable_error_action_domination) + return ContributionIndex__none; + /* No reduce or error action domination found, so shift dominates. */ + return ci_shift; + } + + /* R/R conflict, so the reduction with the lowest rule number dominates. + Fortunately, contributions are sorted by rule number. */ + { + ContributionIndex ci; + for (ci = 0; ci < self->inadequacyNode->contributionCount; ++ci) + if (AnnotationList__stateMakesContribution (self, nitems, ci, + lookaheads)) + { + if (require_split_stable + && !AnnotationList__isContributionAlways (self, ci)) + return ContributionIndex__none; + return ci; + } + } + return ContributionIndex__none; +} diff --git a/src/AnnotationList.h b/src/AnnotationList.h new file mode 100644 index 00000000..02d4a2be --- /dev/null +++ b/src/AnnotationList.h @@ -0,0 +1,177 @@ +/* IELR's inadequacy annotation list. + + Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of Bison, the GNU Compiler Compiler. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef ANNOTATION_LIST_H_ +# define ANNOTATION_LIST_H_ + +#include +#include "Sbitset.h" +#include "InadequacyList.h" +#include "state.h" + +typedef unsigned int AnnotationIndex; + +/** + * A node in a list of annotations on a particular LR(0) state. Each + * annotation records how isocores of that LR(0) state might contribute to an + * individual inadequacy, which might manifest in a different state. Don't + * break encapsulation by modifying the fields directly. Use the provided + * interface functions. + */ +typedef struct AnnotationList +{ + /** The next node in the list or \c NULL if none. */ + struct AnnotationList *next; + /** The \c InadequacyList node describing how this inadequacy manifests. */ + InadequacyList *inadequacyNode; + /** + * List of how the "always", "never", and potential contributions of the + * inadequacy might be made by isocores of the annotated LR(0) state: + * - The number of rows is the number of contributions. That is, + * AnnotationList::inadequacyNode->contributionCount. + * - The token associated with contribution \c i is + * InadequacyList__getContributionToken (AnnotationList::inadequacyNode, i). + * - Iff AnnotationList::contributions[i] = NULL, contribution + * \c i is an "always" contribution. That is, for every isocore of the + * annotated LR(0) state, its core or the core of one its eventual + * successors will definitely make this contribution to the inadequacy. + * It may contribute by either: + * - Creating a shift of contribution i's token in the state + * that can manifest the inadequacy. + * - Propagating that token to the lookahead set of contribution + * i's reduction in the state that can manifest the + * inadequacy. + * - Otherwise: + * - The number of columns in AnnotationList::contributions[i] + * is the number of kernel items in any isocore of the annotated LR(0) + * state. + * - Iff AnnotationList::contributions[i] is empty, contribution + * \c i is a "never" contribution. That is, no isocore of the + * annotated LR(0) state can make this contribution to the inadequacy. + * - Otherwise, for each bit \c j that is set in + * AnnotationList::contributions[i], if the token associated + * with contribution \c i is present in the lookahead set of kernel + * item \c j of an isocore of the annotated LR(0) state, that isocore + * will make contribution \c i to the inadequacy by propagating the + * contribution's token to the lookahead set of the contribution's + * reduction in the state that can manifest the inadequacy. + */ + Sbitset contributions[1]; +} AnnotationList; + +/** + * \pre + * - s != NULL. + * - \c follow_kernel_items, \c always_follows, and \c predecessors were + * computed by \c ielr_compute_auxiliary_tables. + * - The size of each of \c annotation_lists and \c annotation_counts is + * \c ::nstates. + * \post + * - inadequacy_lists[s->number] now describes all inadequacies that + * manifest in \c s. + * - For every state states[i], annotation_lists[i] now + * contains all annotations associated with all inadequacies that manifest + * in \c s. + * - annotation_counts[i] was incremented by the number of new + * annotations added to states[i]. + * - *max_contributionsp is the higher of: + * - The maximum number of contributions computed per annotation. + * - *max_contributionsp \@pre. + * - All memory for all new annotations was allocated on + * \c annotations_obstackp. + */ +void +AnnotationList__compute_from_inadequacies (state *s, + bitsetv follow_kernel_items, + bitsetv always_follows, + state ***predecessors, + bitset **item_lookahead_sets, + InadequacyList **inadequacy_lists, + AnnotationList **annotation_lists, + AnnotationIndex *annotation_counts, + ContributionIndex + *max_contributionsp, + struct obstack + *annotations_obstackp); + +/** + * \pre + * - self != NULL. + * - \c nitems is the number of kernel items in the LR(0) state that every + * node in the list \c self annotates. + * \post + * - A textual representation of all nodes in the list \c self was printed to + * stderr. \c spaces spaces were printed before each line of the text. + */ +void AnnotationList__debug (AnnotationList const *self, size_t nitems, + int spaces); + +/** + * \pre + * - self != NULL. + * - \c nitems is the number of kernel items in the LR(0) state that \c self + * annotates. + * - The number of rows in \c lookahead_filter is at least \c nitems, and the + * number of columns is \c ::ntokens. + * \post + * - lookahead_filter[i][j] is set iff some annotation in the list + * \c self lists token \c j in kernel item \c i as a contributor. + */ +void AnnotationList__computeLookaheadFilter (AnnotationList const *self, + size_t nitems, + bitsetv lookahead_filter); + +/** + * \pre + * - self != NULL. + * - \c nitems is the number of kernel items in the LR(0) state that \c self + * annotates. + * - \c lookaheads describes the lookahead sets on the kernel items of some + * isocore of the LR(0) state that \c self annotates. Either: + * - lookaheads = NULL only if the lookahead set on every kernel + * item is empty. + * - For any 0 <= i < nitems, lookaheads[i] is either: + * - \c NULL only if the lookahead set on kernel item \c i is empty. + * - The (possibly empty) lookahead set on kernel item \c i. + * \post + * - If require_split_stable = false, \c result = either: + * - \c ContributionIndex__none iff the state described by \c lookaheads + * makes none of the contributions in \c self. + * - The index of the dominating contribution in \c self that is made by + * that state. + * - \c ContributionIndex__error_action to indicate that the inadequacy + * manifests as a conflict and that a syntax error action (because of a + * %nonassoc) dominates instead. + * - Otherwise, \c result is the same as if require_split_stable = + * false except that it is also \c ContributionIndex__none if there + * are contributions made by the state but the dominating contribution is + * not split-stable. By split-stable, we mean that the dominating + * contribution cannot change due to loss of one or more potential + * contributions due to loss of lookaheads due to splitting of the state. + * - After determining which contributions are actually made by the state, + * the algorithm for determining which contribution dominates in the + * conflict is intended to choose exactly the same action as conflicts.c + * would choose... no matter how crazy conflicts.c's choice is. + */ +ContributionIndex +AnnotationList__computeDominantContribution (AnnotationList const *self, + size_t nitems, bitset *lookaheads, + bool require_split_stable); + +#endif /* !ANNOTATION_LIST_H_ */ diff --git a/src/InadequacyList.c b/src/InadequacyList.c new file mode 100644 index 00000000..edf3a0f5 --- /dev/null +++ b/src/InadequacyList.c @@ -0,0 +1,76 @@ +/* IELR's inadequacy list. + + Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of Bison, the GNU Compiler Compiler. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include "system.h" + +#include "InadequacyList.h" + +ContributionIndex const ContributionIndex__none = -1; +ContributionIndex const ContributionIndex__error_action = -2; + +InadequacyList * +InadequacyList__new_conflict (state *manifesting_state, symbol *token, + bitset actions) +{ + InadequacyList *result = xmalloc (sizeof *result); + result->next = NULL; + result->manifestingState = manifesting_state; + result->contributionCount = bitset_count (actions); + result->inadequacy.conflict.token = token; + result->inadequacy.conflict.actions = actions; + return result; +} + +void +InadequacyList__delete (InadequacyList *self) +{ + while (self) + { + InadequacyList *node = self; + self = self->next; + bitset_free (node->inadequacy.conflict.actions); + free (node); + } +} + +ContributionIndex +InadequacyList__getShiftContributionIndex (InadequacyList const *self) +{ + if (!bitset_test (self->inadequacy.conflict.actions, + self->manifestingState->reductions->num)) + return ContributionIndex__none; + return self->contributionCount - 1; +} + +symbol * +InadequacyList__getContributionToken (InadequacyList const *self, + ContributionIndex i) +{ + aver (0 <= i && i < self->contributionCount); + return self->inadequacy.conflict.token; +} + +void +InadequacyList__prependTo (InadequacyList *self, InadequacyList **list) +{ + InadequacyList *head_old = *list; + *list = self; + self->next = head_old; +} diff --git a/src/InadequacyList.h b/src/InadequacyList.h new file mode 100644 index 00000000..5770f994 --- /dev/null +++ b/src/InadequacyList.h @@ -0,0 +1,135 @@ +/* IELR's inadequacy list. + + Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of Bison, the GNU Compiler Compiler. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef INADEQUACY_LIST_H_ +# define INADEQUACY_LIST_H_ + +#include +#include "gram.h" +#include "state.h" +#include "symtab.h" + +/** + * For a conflict, each rule in the grammar can have at most one contributing + * reduction except that rule 0 cannot have any because the reduction on rule 0 + * cannot have lookaheads. For a conflict, exactly one shift can contribute. + * Thus the number of rules in the grammar is an upper bound on the number of + * possible contributions to any conflict. The maximum number of possible + * items in a state is also an upper bound, but the \c nitems member of \c + * state is currently a \c size_t and thus, if changed, risks becoming out of + * sync with this type. Whatever the type, it must support negatives for sake + * of the special values below. + */ +typedef rule_number ContributionIndex; + +/* Special \c ContributionIndex used to indicate null result when looking for a + contribution. */ +extern ContributionIndex const ContributionIndex__none; + +/* Special \c ContributionIndex used by + \c AnnotationList__computeDominantContribution to signal when the action + chosen in a conflict is a syntax error because of a %nonassoc. */ +extern ContributionIndex const ContributionIndex__error_action; + +/** + * The description of a conflict. Don't break encapsulation by modifying the + * fields directly. Use the provided interface functions for + * \c InadequacyList. + */ +typedef struct { + /** The \c token passed to \c InadequacyList__new_conflict. */ + symbol *token; + /** The \c actions passed to \c InadequacyList__new_conflict. */ + bitset actions; +} Conflict; + +/** + * A node in a list that describes all the inadequacies that manifest in a + * particular state. Don't break encapsulation by modifying the fields + * directly. Use the provided interface functions. + */ +typedef struct InadequacyList { + struct InadequacyList *next; + state *manifestingState; + ContributionIndex contributionCount; + union { + Conflict conflict; + } inadequacy; +} InadequacyList; + +/** + * \pre + * - manifesting_state != NULL. + * - \c token is a token. + * - The size of \c actions is + * manifesting_state->reductions->num + 1. + * \post + * - \c result is a new \c InadequacyList with one node indicating that, in + * \c manifesting_state, the following actions are in conflict on \c token: + * - Shift iff + * bitset_test (actions, manifesting_state->reductions->num). + * - For any \c i such that + * 0 <= i < manifesting_state->reductions->num, the reduction + * for the rule manifesting_state->reductions->rules[i] iff + * actions[i] is set. + * - \c result assumes responsibility for the memory of \c actions. + */ +InadequacyList *InadequacyList__new_conflict (state *manifesting_state, + symbol *token, bitset actions); + +/** + * \post + * - All memory associated with all nodes in the list \c self was freed. + */ +void InadequacyList__delete (InadequacyList *self); + +/** + * \pre + * - self != NULL. + * \post + * - \c result = either: + * - \c ContributionIndex__none iff there is no shift contribution in + * \c self (perhaps because \c self isn't a conflict). + * - The index of the shift contribution, otherwise. + */ +ContributionIndex +InadequacyList__getShiftContributionIndex (InadequacyList const *self); + +/** + * \pre + * - self != NULL. + * - 0 <= i < self->contributionCount. + * \post + * - \c result = the token associated with contribution \c i in the + * inadequacy described by the node \c self. + */ +symbol *InadequacyList__getContributionToken (InadequacyList const *self, + ContributionIndex i); + +/** + * \pre + * - \c self is a single node. + * - list != NULL. + * \post + * - \c list now contains \c self as its first node. + * - \c list assumes responsibility for the memory of \c self. + */ +void InadequacyList__prependTo (InadequacyList *self, InadequacyList **list); + +#endif /* !INADEQUACY_LIST_H_ */ diff --git a/src/Sbitset.c b/src/Sbitset.c new file mode 100644 index 00000000..0c1fedfc --- /dev/null +++ b/src/Sbitset.c @@ -0,0 +1,78 @@ +/* A simple, memory-efficient bitset implementation. + + Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of Bison, the GNU Compiler Compiler. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include "system.h" + +#include "Sbitset.h" + +Sbitset +Sbitset__new (Sbitset__Index nbits) +{ + /* Some functions, like Sbitset__last_byte_mask, will fail if nbits = 0. */ + aver (nbits); + return xcalloc (1, Sbitset__nbytes (nbits)); +} + +Sbitset +Sbitset__new_on_obstack (Sbitset__Index nbits, struct obstack *obstackp) +{ + char *result; + char *ptr; + char *end; + aver (nbits); + result = obstack_alloc (obstackp, Sbitset__nbytes (nbits)); + for (ptr = result, end = result + Sbitset__nbytes (nbits); ptr < end; ++ptr) + *ptr = 0; + return result; +} + +void +Sbitset__delete (Sbitset self) +{ + free (self); +} + +bool +Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits) +{ + char *last = self + Sbitset__nbytes (nbits) - 1; + for (; self < last; ++self) + if (*self != 0) + return false; + return ((*last) & Sbitset__last_byte_mask (nbits)) == 0; +} + +void +Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file) +{ + Sbitset__Index i; + Sbitset itr; + bool first = true; + fprintf (file, "nbits = %d, set = {", nbits); + SBITSET__FOR_EACH (self, nbits, itr, i) + { + if (first) + first = false; + else + fprintf (file, ","); + fprintf (file, " %d", i); + } + fprintf (file, " }"); +} diff --git a/src/Sbitset.h b/src/Sbitset.h new file mode 100644 index 00000000..4b4b7508 --- /dev/null +++ b/src/Sbitset.h @@ -0,0 +1,87 @@ +/* A simple, memory-efficient bitset implementation. + + Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of Bison, the GNU Compiler Compiler. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef SBITSET_H_ +# define SBITSET_H_ + +typedef char *Sbitset; +typedef size_t Sbitset__Index; + +#define Sbitset__nbytes(NBITS) (((NBITS)+7)/8) +#define Sbitset__byteAddress(SELF, INDEX) (((SELF) + (INDEX)/8)) +#define Sbitset__bit_mask(INDEX) (0x1 << (7 - (INDEX)%8)) +#define Sbitset__last_byte_mask(NBITS) (0xff << (7 - ((NBITS)-1)%8)) + +/* nbits must not be 0. */ +Sbitset Sbitset__new (Sbitset__Index nbits); +Sbitset Sbitset__new_on_obstack (Sbitset__Index nbits, + struct obstack *obstackp); +void Sbitset__delete (Sbitset self); + +#define Sbitset__test(SELF, INDEX) \ + ((*Sbitset__byteAddress ((SELF), (INDEX)) & Sbitset__bit_mask (INDEX)) != 0) + +bool Sbitset__isEmpty (Sbitset self, Sbitset__Index nbits); + +void Sbitset__fprint(Sbitset self, Sbitset__Index nbits, FILE *file); + +#define Sbitset__set(SELF, INDEX) \ +do { \ + *Sbitset__byteAddress ((SELF), (INDEX)) = \ + *Sbitset__byteAddress ((SELF), (INDEX)) | Sbitset__bit_mask (INDEX); \ +} while(0) + +#define Sbitset__reset(SELF, INDEX) \ +do { \ + *Sbitset__byteAddress ((SELF), (INDEX)) = \ + *Sbitset__byteAddress ((SELF), (INDEX)) & ~Sbitset__bit_mask (INDEX); \ +} while(0) + +/* NBITS is the size of the bitset. More than NBITS bits might be reset. */ +#define Sbitset__zero(SELF, NBITS) \ +do { \ + memset (SELF, 0, Sbitset__nbytes (NBITS)); \ +} while(0) + +/* NBITS is the size of the bitset. More than NBITS bits might be set. */ +#define Sbitset__ones(SELF, NBITS) \ +do { \ + memset (SELF, 0xff, Sbitset__nbytes (NBITS)); \ +} while(0) + +/* NBITS is the size of every bitset. More than NBITS bits might be set. */ +#define Sbitset__or(SELF, OTHER1, OTHER2, NBITS) \ +do { \ + char *ptr_self = (SELF); \ + char *ptr_other1 = (OTHER1); \ + char *ptr_other2 = (OTHER2); \ + char *end_self = ptr_self + Sbitset__nbytes (NBITS); \ + for (; ptr_self < end_self; ++ptr_self, ++ptr_other1, ++ptr_other2) \ + *ptr_self = *ptr_other1 | *ptr_other2; \ +} while(0) + +#define SBITSET__FOR_EACH(SELF, NBITS, ITER, INDEX) \ + for ((ITER) = (SELF); (ITER) < (SELF) + Sbitset__nbytes (NBITS); ++(ITER)) \ + if (*(ITER) != 0) \ + for ((INDEX) = ((ITER)-(SELF))*8; \ + (INDEX) < (NBITS) && (SELF)+(INDEX)/8 < (ITER)+1; \ + ++(INDEX)) \ + if (((*ITER) & Sbitset__bit_mask (INDEX)) != 0) + +#endif /* !SBITSET_H_ */ diff --git a/src/ielr.c b/src/ielr.c new file mode 100644 index 00000000..2c89a5b1 --- /dev/null +++ b/src/ielr.c @@ -0,0 +1,1200 @@ +/* IELR main implementation. + + Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of Bison, the GNU Compiler Compiler. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include +#include "system.h" + +#include "ielr.h" + +#include +#include + +#include "AnnotationList.h" +#include "derives.h" +#include "getargs.h" +#include "lalr.h" +#include "muscle_tab.h" +#include "nullable.h" +#include "relation.h" +#include "state.h" +#include "symtab.h" + +/** Records the value of the \%define variable "lr.type". */ +typedef enum { LR_TYPE__LALR, LR_TYPE__IELR, LR_TYPE__CANONICAL_LR } LrType; + +/** + * \post: + * - \c result = a new \c bitset of size \c ::nritems such that any bit \c i + * is set iff ritem[i] is a nonterminal after which all ritems in + * the same RHS are nullable nonterminals. In other words, the follows of + * a goto on ritem[i] include the lookahead set of the item. + */ +static bitset +ielr_compute_ritem_sees_lookahead_set (void) +{ + bitset result = bitset_create (nritems, BITSET_FIXED); + unsigned int i = nritems-1; + while (i>0) + { + --i; + while (!item_number_is_rule_number (ritem[i]) + && ISVAR (ritem[i]) + && nullable [item_number_as_symbol_number (ritem[i]) - ntokens]) + bitset_set (result, i--); + if (!item_number_is_rule_number (ritem[i]) && ISVAR (ritem[i])) + bitset_set (result, i--); + while (!item_number_is_rule_number (ritem[i]) && i>0) + --i; + } + if (trace_flag & trace_ielr) + { + fprintf (stderr, "ritem_sees_lookahead_set:\n"); + debug_bitset (result); + fprintf (stderr, "\n"); + } + return result; +} + +/** + * \pre: + * - \c ritem_sees_lookahead_set was computed by + * \c ielr_compute_ritem_sees_lookahead_set. + * \post: + * - Each of \c *edgesp and \c *edge_countsp is a new array of size + * \c ::ngotos. + * - (*edgesp)[i] points to a \c goto_number array of size + * (*edge_countsp)[i]+1. + * - In such a \c goto_number array, the last element is \c ::END_NODE. + * - All remaining elements are the indices of the gotos to which there is an + * internal follow edge from goto \c i. + * - There is an internal follow edge from goto \c i to goto \c j iff both: + * - The from states of gotos \c i and \c j are the same. + * - The transition nonterminal for goto \c i appears as the first RHS + * symbol of at least one production for which both: + * - The LHS is the transition symbol of goto \c j. + * - All other RHS symbols are nullable nonterminals. + * - In other words, the follows of goto \c i include the follows of + * goto \c j and it's an internal edge because the from states are the + * same. + */ +static void +ielr_compute_internal_follow_edges (bitset ritem_sees_lookahead_set, + goto_number ***edgesp, int **edge_countsp) +{ + *edgesp = xnmalloc (ngotos, sizeof **edgesp); + *edge_countsp = xnmalloc (ngotos, sizeof **edge_countsp); + { + bitset sources = bitset_create (ngotos, BITSET_FIXED); + goto_number i; + for (i = 0; i < ngotos; ++i) + (*edge_countsp)[i] = 0; + for (i = 0; i < ngotos; ++i) + { + int nsources = 0; + { + rule **rulep; + for (rulep = derives[states[to_state[i]]->accessing_symbol + - ntokens]; + *rulep; + ++rulep) + { + /* If there is at least one RHS symbol, if the first RHS symbol + is a nonterminal, and if all remaining RHS symbols (if any) + are nullable nonterminals, create an edge from the LHS + symbol's goto to the first RHS symbol's goto such that the RHS + symbol's goto will be the source of the edge after the + eventual relation_transpose below. + + Unlike in ielr_compute_always_follows, I use a bitset for + edges rather than an array because it is possible that + multiple RHS's with the same first symbol could fit and thus + that we could end up with redundant edges. With the + possibility of redundant edges, it's hard to know ahead of + time how large to make such an array. Another possible + redundancy is that source and destination might be the same + goto. Eliminating all these possible redundancies now might + possibly help performance a little. I have not proven any of + this, but I'm guessing the bitset shouldn't entail much of a + performance penalty, if any. */ + if (bitset_test (ritem_sees_lookahead_set, + (*rulep)->rhs - ritem)) + { + goto_number source = + map_goto (from_state[i], + item_number_as_symbol_number (*(*rulep)->rhs)); + if (i != source && !bitset_test (sources, source)) + { + bitset_set (sources, source); + ++nsources; + ++(*edge_countsp)[source]; + } + } + } + } + if (nsources == 0) + (*edgesp)[i] = NULL; + else + { + (*edgesp)[i] = xnmalloc (nsources + 1, sizeof *(*edgesp)[i]); + { + bitset_iterator biter_source; + bitset_bindex source; + int j = 0; + BITSET_FOR_EACH (biter_source, sources, source, 0) + (*edgesp)[i][j++] = source; + } + (*edgesp)[i][nsources] = END_NODE; + } + bitset_zero (sources); + } + bitset_free (sources); + } + + relation_transpose (edgesp, ngotos); + + if (trace_flag & trace_ielr) + { + fprintf (stderr, "internal_follow_edges:\n"); + relation_print (*edgesp, ngotos, stderr); + } +} + +/** + * \pre: + * - \c ritem_sees_lookahead_set was computed by + * \c ielr_compute_ritem_sees_lookahead_set. + * - \c internal_follow_edges was computed by + * \c ielr_compute_internal_follow_edges. + * \post: + * - \c *follow_kernel_itemsp is a new \c bitsetv in which the number of rows + * is \c ngotos and the number of columns is maximum number of kernel items + * in any state. + * - (*follow_kernel_itemsp)[i][j] is set iff the follows of goto + * \c i include the lookahead set of item \c j in the from state of goto + * \c i. + * - Thus, (*follow_kernel_itemsp)[i][j] is always unset if there is + * no item \c j in the from state of goto \c i. + */ +static void +ielr_compute_follow_kernel_items (bitset ritem_sees_lookahead_set, + goto_number **internal_follow_edges, + bitsetv *follow_kernel_itemsp) +{ + { + size_t max_nitems = 0; + state_number i; + for (i = 0; i < nstates; ++i) + if (states[i]->nitems > max_nitems) + max_nitems = states[i]->nitems; + *follow_kernel_itemsp = bitsetv_create (ngotos, max_nitems, BITSET_FIXED); + } + { + goto_number i; + for (i = 0; i < ngotos; ++i) + { + size_t nitems = states[from_state[i]]->nitems; + item_number *items = states[from_state[i]]->items; + size_t j; + for (j = 0; j < nitems; ++j) + /* If this item has this goto and if all subsequent symbols in this + RHS (if any) are nullable nonterminals, then record this item as + one whose lookahead set is included in this goto's follows. */ + if (item_number_is_symbol_number (ritem[items[j]]) + && item_number_as_symbol_number (ritem[items[j]]) + == states[to_state[i]]->accessing_symbol + && bitset_test (ritem_sees_lookahead_set, items[j])) + bitset_set ((*follow_kernel_itemsp)[i], j); + } + } + relation_digraph (internal_follow_edges, ngotos, follow_kernel_itemsp); + + if (trace_flag & trace_ielr) + { + fprintf (stderr, "follow_kernel_items:\n"); + debug_bitsetv (*follow_kernel_itemsp); + } +} + +/** + * \pre + * - \c *edgesp and \c edge_counts were computed by + * \c ielr_compute_internal_follow_edges. + * \post + * - \c *always_followsp is a new \c bitsetv with \c ngotos rows and + * \c ntokens columns. + * - (*always_followsp)[i][j] is set iff token \c j is an always + * follow (that is, it's computed by internal and successor edges) of goto + * \c i. + * - Rows of \c *edgesp have been realloc'ed and extended to include + * successor follow edges. \c edge_counts has not been updated. + */ +static void +ielr_compute_always_follows (goto_number ***edgesp, + int const edge_counts[], + bitsetv *always_followsp) +{ + *always_followsp = bitsetv_create (ngotos, ntokens, BITSET_FIXED); + { + goto_number *edge_array = xnmalloc (ngotos, sizeof *edge_array); + goto_number i; + for (i = 0; i < ngotos; ++i) + { + goto_number nedges = edge_counts[i]; + { + int j; + transitions *trans = states[to_state[i]]->transitions; + FOR_EACH_SHIFT (trans, j) + bitset_set ((*always_followsp)[i], TRANSITION_SYMBOL (trans, j)); + for (; j < trans->num; ++j) + { + symbol_number sym = TRANSITION_SYMBOL (trans, j); + if (nullable[sym - ntokens]) + edge_array[nedges++] = map_goto (to_state[i], sym); + } + } + if (nedges - edge_counts[i]) + { + (*edgesp)[i] = + xnrealloc ((*edgesp)[i], nedges + 1, sizeof *(*edgesp)[i]); + memcpy ((*edgesp)[i] + edge_counts[i], edge_array + edge_counts[i], + (nedges - edge_counts[i]) * sizeof *(*edgesp)[i]); + (*edgesp)[i][nedges] = END_NODE; + } + } + free (edge_array); + } + relation_digraph (*edgesp, ngotos, always_followsp); + + if (trace_flag & trace_ielr) + { + fprintf (stderr, "always follow edges:\n"); + relation_print (*edgesp, ngotos, stderr); + fprintf (stderr, "always_follows:\n"); + debug_bitsetv (*always_followsp); + } +} + +/** + * \post + * - \c result is a new array of size \c ::nstates. + * - result[i] is an array of pointers to the predecessor + * state's of state \c i. + * - The last element of such an array is \c NULL. + */ +static state *** +ielr_compute_predecessors (void) +{ + state_number i; + int *predecessor_counts = xnmalloc (nstates, sizeof *predecessor_counts); + state ***result = xnmalloc (nstates, sizeof *result); + for (i = 0; i < nstates; ++i) + predecessor_counts[i] = 0; + for (i = 0; i < nstates; ++i) + { + int j; + for (j = 0; j < states[i]->transitions->num; ++j) + ++predecessor_counts[states[i]->transitions->states[j]->number]; + } + for (i = 0; i < nstates; ++i) + { + result[i] = xnmalloc (predecessor_counts[i]+1, sizeof *result[i]); + result[i][predecessor_counts[i]] = NULL; + predecessor_counts[i] = 0; + } + for (i = 0; i < nstates; ++i) + { + int j; + for (j = 0; j < states[i]->transitions->num; ++j) + { + state_number k = states[i]->transitions->states[j]->number; + result[k][predecessor_counts[k]++] = states[i]; + } + } + free (predecessor_counts); + return result; +} + +/** + * \post + * - \c *follow_kernel_itemsp and \c *always_followsp were computed by + * \c ielr_compute_follow_kernel_items and + * \c ielr_compute_always_follows. + * - Iff predecessorsp != NULL, then \c *predecessorsp was computed + * by \c ielr_compute_predecessors. + */ +static void +ielr_compute_auxiliary_tables (bitsetv *follow_kernel_itemsp, + bitsetv *always_followsp, + state ****predecessorsp) +{ + goto_number **edges; + int *edge_counts; + { + bitset ritem_sees_lookahead_set = ielr_compute_ritem_sees_lookahead_set (); + ielr_compute_internal_follow_edges (ritem_sees_lookahead_set, + &edges, &edge_counts); + ielr_compute_follow_kernel_items (ritem_sees_lookahead_set, edges, + follow_kernel_itemsp); + bitset_free (ritem_sees_lookahead_set); + } + ielr_compute_always_follows (&edges, edge_counts, always_followsp); + { + int i; + for (i = 0; i < ngotos; ++i) + free (edges[i]); + } + free (edges); + free (edge_counts); + if (predecessorsp) + *predecessorsp = ielr_compute_predecessors (); +} + +/** + * \note + * - FIXME: It might be an interesting experiment to compare the space and + * time efficiency of computing \c item_lookahead_sets either: + * - Fully up front. + * - Just-in-time, as implemented below. + * - Not at all. That is, just let annotations continue even when + * unnecessary. + */ +bool +ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item, + symbol_number lookahead, state ***predecessors, + bitset **item_lookahead_sets) +{ + if (!item_lookahead_sets[s->number]) + { + size_t i; + item_lookahead_sets[s->number] = + xnmalloc (s->nitems, sizeof item_lookahead_sets[s->number][0]); + for (i = 0; i < s->nitems; ++i) + item_lookahead_sets[s->number][i] = NULL; + } + if (!item_lookahead_sets[s->number][item]) + { + item_lookahead_sets[s->number][item] = + bitset_create (ntokens, BITSET_FIXED); + /* If this kernel item is the beginning of a RHS, it must be the kernel + item in the start state, and so its LHS has no follows and no goto to + check. If, instead, this kernel item is the successor of the start + state's kernel item, there are still no follows and no goto. This + situation is fortunate because we want to avoid the - 2 below in both + cases. + + Actually, IELR(1) should never invoke this function for either of + those cases because (1) follow_kernel_items will never reference a + kernel item for this RHS because the end token blocks sight of the + lookahead set from the RHS's only nonterminal, and (2) no reduction + has a lookback dependency on this lookahead set. Nevertheless, I + didn't change this test to an aver just in case the usage of this + function evolves to need those two cases. In both cases, the current + implementation returns the right result. */ + if (s->items[item] > 1) + { + /* If the LHS symbol of this item isn't known (because this is a + top-level invocation), go get it. */ + if (!lhs) + { + unsigned int i; + for (i = s->items[item]; + !item_number_is_rule_number (ritem[i]); + ++i) + ; + lhs = rules[item_number_as_rule_number (ritem[i])].lhs->number; + } + /* If this kernel item is next to the beginning of the RHS, then + check all predecessors' goto follows for the LHS. */ + if (item_number_is_rule_number (ritem[s->items[item] - 2])) + { + state **predecessor; + aver (lhs != accept->number); + for (predecessor = predecessors[s->number]; + *predecessor; + ++predecessor) + bitset_or (item_lookahead_sets[s->number][item], + item_lookahead_sets[s->number][item], + goto_follows[map_goto ((*predecessor)->number, + lhs)]); + } + /* If this kernel item is later in the RHS, then check all + predecessor items' lookahead sets. */ + else + { + state **predecessor; + for (predecessor = predecessors[s->number]; + *predecessor; + ++predecessor) + { + size_t predecessor_item; + for (predecessor_item = 0; + predecessor_item < (*predecessor)->nitems; + ++predecessor_item) + if ((*predecessor)->items[predecessor_item] + == s->items[item] - 1) + break; + aver (predecessor_item != (*predecessor)->nitems); + ielr_item_has_lookahead (*predecessor, lhs, + predecessor_item, 0 /*irrelevant*/, + predecessors, item_lookahead_sets); + bitset_or (item_lookahead_sets[s->number][item], + item_lookahead_sets[s->number][item], + item_lookahead_sets[(*predecessor)->number] + [predecessor_item]); + } + } + } + } + return bitset_test (item_lookahead_sets[s->number][item], lookahead); +} + +/** + * \pre + * - \c follow_kernel_items, \c always_follows, and \c predecessors + * were computed by \c ielr_compute_auxiliary_tables. + * \post + * - Each of *inadequacy_listsp and *annotation_listsp + * points to a new array of size \c ::nstates. + * - For 0 <= i < ::nstates: + * - (*inadequacy_listsp)[i] contains the \c InadequacyList head + * node for states[i]. + * - (*annotation_listsp)[i] contains the \c AnnotationList head + * node for states[i]. + * - *max_annotationsp is the maximum number of annotations per + * state. + */ +static void +ielr_compute_annotation_lists (bitsetv follow_kernel_items, + bitsetv always_follows, state ***predecessors, + AnnotationIndex *max_annotationsp, + InadequacyList ***inadequacy_listsp, + AnnotationList ***annotation_listsp, + struct obstack *annotations_obstackp) +{ + bitset **item_lookahead_sets = + xnmalloc (nstates, sizeof *item_lookahead_sets); + AnnotationIndex *annotation_counts = + xnmalloc (nstates, sizeof *annotation_counts); + ContributionIndex max_contributions = 0; + unsigned int total_annotations = 0; + state_number i; + + *inadequacy_listsp = xnmalloc (nstates, sizeof **inadequacy_listsp); + *annotation_listsp = xnmalloc (nstates, sizeof **annotation_listsp); + for (i = 0; i < nstates; ++i) + { + item_lookahead_sets[i] = NULL; + (*inadequacy_listsp)[i] = NULL; + (*annotation_listsp)[i] = NULL; + annotation_counts[i] = 0; + } + for (i = 0; i < nstates; ++i) + AnnotationList__compute_from_inadequacies (states[i], follow_kernel_items, + always_follows, predecessors, + item_lookahead_sets, + *inadequacy_listsp, + *annotation_listsp, + annotation_counts, + &max_contributions, + annotations_obstackp); + *max_annotationsp = 0; + for (i = 0; i < nstates; ++i) + { + if (annotation_counts[i] > *max_annotationsp) + *max_annotationsp = annotation_counts[i]; + total_annotations += annotation_counts[i]; + } + if (trace_flag & trace_ielr) + { + for (i = 0; i < nstates; ++i) + { + fprintf (stderr, "Inadequacy annotations for state %d:\n", i); + AnnotationList__debug ((*annotation_listsp)[i], + states[i]->nitems, 2); + } + fprintf (stderr, "Number of LR(0)/LALR(1) states: %d\n", nstates); + fprintf (stderr, "Average number of annotations per state: %f\n", + (float)total_annotations/nstates); + fprintf (stderr, "Max number of annotations per state: %d\n", + *max_annotationsp); + fprintf (stderr, "Max number of contributions per annotation: %d\n", + max_contributions); + } + for (i = 0; i < nstates; ++i) + if (item_lookahead_sets[i]) + { + size_t j; + for (j = 0; j < states[i]->nitems; ++j) + if (item_lookahead_sets[i][j]) + bitset_free (item_lookahead_sets[i][j]); + free (item_lookahead_sets[i]); + } + free (item_lookahead_sets); + free (annotation_counts); +} + +typedef struct state_list { + struct state_list *next; + state *state; + /** Has this state been recomputed as a successor of another state? */ + bool recomputedAsSuccessor; + /** + * \c NULL iff all lookahead sets are empty. lookaheads[i] = NULL + * iff the lookahead set on item \c i is empty. + */ + bitset *lookaheads; + /** + * nextIsocore is the next state in a circularly linked-list of all states + * with the same core. The one originally computed by generate_states in + * LR0.c is lr0Isocore. + */ + struct state_list *lr0Isocore; + struct state_list *nextIsocore; +} state_list; + +/** + * \pre + * - \c follow_kernel_items and \c always_follows were computed by + * \c ielr_compute_auxiliary_tables. + * - n->class = nterm_sym. + * \post + * - \c follow_set contains the follow set for the goto on nonterminal \c n + * in state \c s based on the lookaheads stored in s->lookaheads. + */ +static void +ielr_compute_goto_follow_set (bitsetv follow_kernel_items, + bitsetv always_follows, state_list *s, + symbol *n, bitset follow_set) +{ + goto_number n_goto = map_goto (s->lr0Isocore->state->number, n->number); + bitset_copy (follow_set, always_follows[n_goto]); + if (s->lookaheads) + { + bitset_iterator biter_item; + bitset_bindex item; + BITSET_FOR_EACH (biter_item, follow_kernel_items[n_goto], item, 0) + if (s->lookaheads[item]) + bitset_or (follow_set, follow_set, s->lookaheads[item]); + } +} + +/** + * \pre + * - \c follow_kernel_items and \c always_follows were computed by + * \c ielr_compute_auxiliary_tables. + * - \c lookahead_filter was computed by + * \c AnnotationList__computeLookaheadFilter for the original LR(0) isocore + * of \c t. + * - The number of rows in \c lookaheads is at least the number of items in + * \c t, and the number of columns is \c ::ntokens. + * \post + * - lookaheads[i][j] is set iff both: + * - lookahead_filter[i][j] is set. + * - The isocore of \c t that will be the transition successor of \c s will + * inherit from \c s token \c j into the lookahead set of item \c i. + */ +static void +ielr_compute_lookaheads (bitsetv follow_kernel_items, bitsetv always_follows, + state_list *s, state *t, bitsetv lookahead_filter, + bitsetv lookaheads) +{ + size_t s_item = 0; + size_t t_item; + bitsetv_zero (lookaheads); + for (t_item = 0; t_item < t->nitems; ++t_item) + { + /* If this kernel item is the beginning of a RHS, it must be the + kernel item in the start state, but t is supposed to be a successor + state. If, instead, this kernel item is the successor of the start + state's kernel item, the lookahead set is empty. This second case is + a special case to avoid the - 2 below, but the next successor can be + handled fine without special casing it. */ + aver (t->items[t_item] != 0); + if (t->items[t_item] > 1 + && !bitset_empty_p (lookahead_filter[t_item])) + { + if (item_number_is_rule_number (ritem[t->items[t_item] - 2])) + { + unsigned int rule_item; + for (rule_item = t->items[t_item]; + !item_number_is_rule_number (ritem[rule_item]); + ++rule_item) + ; + ielr_compute_goto_follow_set ( + follow_kernel_items, always_follows, s, + rules[item_number_as_rule_number (ritem[rule_item])].lhs, + lookaheads[t_item]); + } + else if (s->lookaheads) + { + /* We don't have to start the s item search at the beginning + every time because items from both states are sorted by their + indices in ritem. */ + for (; s_item < s->state->nitems; ++s_item) + if (s->state->items[s_item] == t->items[t_item] - 1) + break; + aver (s_item != s->state->nitems); + if (s->lookaheads[s_item]) + bitset_copy (lookaheads[t_item], s->lookaheads[s_item]); + } + bitset_and (lookaheads[t_item], + lookaheads[t_item], lookahead_filter[t_item]); + } + } +} + +/** + * \pre + * - \c follow_kernel_items and \c always_follows were computed by + * \c ielr_compute_auxiliary_tables. + * - Either: + * - annotation_lists = NULL and all bits in work2 are set. + * - \c annotation_lists was computed by \c ielr_compute_annotation_lists. + * - The number of rows in each of \c lookaheads and \c work2 is the maximum + * number of items in any state. The number of columns in each is + * \c ::ntokens. + * - \c lookaheads was computed by \c ielr_compute_lookaheads for \c t. + * - \c ::nstates is the total number of states, some not yet fully computed, + * in the list ending at \c *last_statep. It is at least the number of + * original LR(0) states. + * - The size of \c work1 is at least the number of annotations for the LR(0) + * isocore of \c t. + * \post + * - Either: + * - In the case that annotation_lists != NULL, + * lookaheads \@pre was merged with some isocore of \c t if + * permitted by the annotations for the original LR(0) isocore of \c t. + * If this changed the lookaheads in that isocore, those changes were + * propagated to all already computed transition successors recursively + * possibly resulting in the splitting of some of those successors. + * - In the case that annotation_lists = NULL, + * lookaheads \@pre was merged with some isocore of \c t if the + * isocore's lookahead sets were identical to those specified by + * lookaheads \@pre. + * - If no such merge was permitted, a new isocore of \c t containing + * lookaheads \@pre was appended to the state list whose + * previous tail was *last_statep \@pre and \c ::nstates was + * incremented. It was also appended to \c t's isocore list. + * - *tp = the isocore of \c t into which + * lookaheads \@pre was placed/merged. + * - \c lookaheads, \c work1, and \c work2 may have been altered. + */ +static void +ielr_compute_state (bitsetv follow_kernel_items, bitsetv always_follows, + AnnotationList **annotation_lists, state *t, + bitsetv lookaheads, state_list **last_statep, + ContributionIndex work1[], bitsetv work2, state **tp) +{ + state_list *lr0_isocore = t->state_list->lr0Isocore; + state_list **this_isocorep; + bool has_lookaheads; + + /* Determine whether there's an isocore of t with which these lookaheads can + be merged. */ + { + AnnotationIndex ai; + AnnotationList *a; + if (annotation_lists) + for (ai = 0, a = annotation_lists[lr0_isocore->state->number]; + a; + ++ai, a = a->next) + work1[ai] = + AnnotationList__computeDominantContribution ( + a, lr0_isocore->state->nitems, lookaheads, false); + for (this_isocorep = &t->state_list; + this_isocorep == &t->state_list || *this_isocorep != t->state_list; + this_isocorep = &(*this_isocorep)->nextIsocore) + { + if (!(*this_isocorep)->recomputedAsSuccessor) + break; + if (annotation_lists) + { + for (ai = 0, a = annotation_lists[lr0_isocore->state->number]; + a; + ++ai, a = a->next) + { + if (work1[ai] != ContributionIndex__none) + { + /* This isocore compatibility test depends on the fact + that, if the dominant contributions are the same for the + two isocores, then merging their lookahead sets will not + produce a state with a different dominant contribution. + */ + ContributionIndex ci = + AnnotationList__computeDominantContribution ( + a, lr0_isocore->state->nitems, + (*this_isocorep)->lookaheads, false); + if (ci != ContributionIndex__none && work1[ai] != ci) + break; + } + } + if (!a) + break; + } + else + { + size_t i; + for (i = 0; i < t->nitems; ++i) + { + if (!(*this_isocorep)->lookaheads + || !(*this_isocorep)->lookaheads[i]) + { + if (!bitset_empty_p (lookaheads[i])) + break; + } + // bitset_equal_p uses the size of the first argument, so + // lookaheads[i] must be the second argument. + else if (!bitset_equal_p ((*this_isocorep)->lookaheads[i], + lookaheads[i])) + break; + } + if (i == t->nitems) + break; + } + } + } + + has_lookaheads = false; + { + size_t i; + for (i = 0; i < lr0_isocore->state->nitems; ++i) + if (!bitset_empty_p (lookaheads[i])) + { + has_lookaheads = true; + break; + } + } + + /* Merge with an existing isocore. */ + if (this_isocorep == &t->state_list || *this_isocorep != t->state_list) + { + bool new_lookaheads = false; + *tp = (*this_isocorep)->state; + + /* Merge lookaheads into the state and record whether any of them are + actually new. */ + if (has_lookaheads) + { + size_t i; + if (!(*this_isocorep)->lookaheads) + { + (*this_isocorep)->lookaheads = + xnmalloc (t->nitems, sizeof (*this_isocorep)->lookaheads); + for (i = 0; i < t->nitems; ++i) + (*this_isocorep)->lookaheads[i] = NULL; + } + for (i = 0; i < t->nitems; ++i) + if (!bitset_empty_p (lookaheads[i])) + { + if (!(*this_isocorep)->lookaheads[i]) + (*this_isocorep)->lookaheads[i] = + bitset_create (ntokens, BITSET_FIXED); + bitset_andn (lookaheads[i], + lookaheads[i], (*this_isocorep)->lookaheads[i]); + bitset_or ((*this_isocorep)->lookaheads[i], + lookaheads[i], (*this_isocorep)->lookaheads[i]); + if (!bitset_empty_p (lookaheads[i])) + new_lookaheads = true; + } + } + + /* If new lookaheads were merged, propagate those lookaheads to the + successors, possibly splitting them. If *tp is being recomputed for + the first time, this isn't necessary because the main + ielr_split_states loop will handle the successors later. */ + if (!(*this_isocorep)->recomputedAsSuccessor) + (*this_isocorep)->recomputedAsSuccessor = true; + else if (new_lookaheads) + { + int i; + /* When merging demands identical lookahead sets, it is impossible to + merge new lookaheads. */ + aver (annotation_lists); + for (i = 0; i < (*tp)->transitions->num; ++i) + { + state *t2 = (*tp)->transitions->states[i]; + /* At any time, there's at most one state for which we have so + far initially recomputed only some of its successors in the + main ielr_split_states loop. Because we recompute successors + in order, we can just stop at the first such successor. Of + course, *tp might be a state some of whose successors have + been recomputed as successors of other states rather than as + successors of *tp. It's fine if we go ahead and propagate to + some of those. We'll propagate to them again (but stop when + we see nothing changes) and to the others when we reach *tp in + the main ielr_split_states loop later. */ + if (!t2->state_list->recomputedAsSuccessor) + break; + AnnotationList__computeLookaheadFilter ( + annotation_lists[t2->state_list->lr0Isocore->state->number], + t2->nitems, work2); + ielr_compute_lookaheads (follow_kernel_items, always_follows, + (*this_isocorep), t2, work2, + lookaheads); + /* FIXME: If splitting t2 here, it's possible that lookaheads + that had already propagated from *tp to t2 will be left in t2 + after *tp has been removed as t2's predecessor: + - We're going to recompute all lookaheads in phase 4, so these + extra lookaheads won't appear in the final parser table. + - If t2 has just one annotation, then these extra lookaheads + cannot alter the dominating contribution to the associated + inadequacy and thus cannot needlessly prevent a future merge + of some new state with t2. We can be sure of this because: + - The fact that we're splitting t2 now means that some + predecessors (at least one) other than *tp must be + propagating contributions to t2. + - The fact that t2 was merged in the first place means that, + if *tp propagated any contributions, the dominating + contribution must be the same as that from those other + predecessors. + - Thus, if some new state to be merged with t2 in the future + proves to be compatible with the contributions propagated + by the other predecessors, it will also be compatible with + the contributions made by the extra lookaheads left behind + by *tp. + - However, if t2 has more than one annotation and these extra + lookaheads contribute to one of their inadequacies, it's + possible these extra lookaheads may needlessly prevent a + future merge with t2. For example: + - Let's say there's an inadequacy A that makes the split + necessary as follows: + - There's currently just one other predecessor and it + propagates to t2 some contributions to inadequacy A. + - The new lookaheads that we were attempting to propagate + from *tp to t2 made contributions to inadequacy A with a + different dominating contribution than those from that + other predecessor. + - The extra lookaheads either make no contribution to + inadequacy A or have the same dominating contribution as + the contributions from the other predecessor. Either + way, as explained above, they can't prevent a future + merge. + - Let's say there's an inadequacy B that causes the trouble + with future merges as follows: + - The extra lookaheads make contributions to inadequacy B. + - Those extra contributions did not prevent the original + merge to create t2 because the other predecessor + propagates to t2 no contributions to inadequacy B. + - Thus, those extra contributions may prevent a future + merge with t2 even though the merge would be fine if *tp + had not left them behind. + - Is the latter case common enough to worry about? + - Perhaps we should track all predecessors and iterate them + now to recreate t2 without those extra lookaheads. */ + ielr_compute_state (follow_kernel_items, always_follows, + annotation_lists, t2, lookaheads, + last_statep, work1, work2, + &(*tp)->transitions->states[i]); + } + } + } + + /* Create a new isocore. */ + else + { + state_list *old_isocore = *this_isocorep; + (*last_statep)->next = *this_isocorep = xmalloc (sizeof **last_statep); + *last_statep = *this_isocorep; + (*last_statep)->state = *tp = state_new_isocore (t); + (*tp)->state_list = *last_statep; + (*last_statep)->recomputedAsSuccessor = true; + (*last_statep)->next = NULL; + (*last_statep)->lookaheads = NULL; + if (has_lookaheads) + { + size_t i; + (*last_statep)->lookaheads = + xnmalloc (t->nitems, sizeof (*last_statep)->lookaheads); + for (i = 0; i < t->nitems; ++i) + { + if (bitset_empty_p (lookaheads[i])) + (*last_statep)->lookaheads[i] = NULL; + else + { + (*last_statep)->lookaheads[i] = + bitset_create (ntokens, BITSET_FIXED); + bitset_copy ((*last_statep)->lookaheads[i], lookaheads[i]); + } + } + } + (*last_statep)->lr0Isocore = lr0_isocore; + (*last_statep)->nextIsocore = old_isocore; + } +} + +/** + * \pre + * - \c follow_kernel_items and \c always_follows were computed by + * \c ielr_compute_auxiliary_tables. + * - Either: + * - annotation_lists = NULL and max_annotations=0. + * - \c annotation_lists and \c max_annotations were computed by + * \c ielr_compute_annotation_lists. + * \post + * - \c ::states is of size \c ::nstates (which might be greater than + * ::nstates \@pre) and no longer contains any LR(1)-relative + * inadequacy. \c annotation_lists was used to determine state + * compatibility or, if annotation_lists = NULL, the canonical + * LR(1) state compatibility test was used. + * - If annotation_lists = NULL, reduction lookahead sets were + * computed in all states. TV_IELR_PHASE4 was pushed while they were + * computed from item lookahead sets. + */ +static void +ielr_split_states (bitsetv follow_kernel_items, bitsetv always_follows, + AnnotationList **annotation_lists, + AnnotationIndex max_annotations) +{ + state_list *first_state; + state_list *last_state; + bitsetv lookahead_filter = NULL; + bitsetv lookaheads; + + /* Set up state list and some reusable bitsets. */ + { + size_t max_nitems = 0; + state_number i; + state_list **nodep = &first_state; + for (i = 0; i < nstates; ++i) + { + *nodep = states[i]->state_list = last_state = xmalloc (sizeof **nodep); + (*nodep)->state = states[i]; + (*nodep)->recomputedAsSuccessor = false; + (*nodep)->lookaheads = NULL; + (*nodep)->lr0Isocore = *nodep; + (*nodep)->nextIsocore = *nodep; + nodep = &(*nodep)->next; + if (states[i]->nitems > max_nitems) + max_nitems = states[i]->nitems; + } + *nodep = NULL; + lookahead_filter = bitsetv_create (max_nitems, ntokens, BITSET_FIXED); + if (!annotation_lists) + bitsetv_ones (lookahead_filter); + lookaheads = bitsetv_create (max_nitems, ntokens, BITSET_FIXED); + } + + /* Recompute states. */ + { + ContributionIndex *work = xnmalloc (max_annotations, sizeof *work); + state_list *this_state; + for (this_state = first_state; this_state; this_state = this_state->next) + { + state *s = this_state->state; + int i; + for (i = 0; i < s->transitions->num; ++i) + { + state *t = s->transitions->states[i]; + if (annotation_lists) + AnnotationList__computeLookaheadFilter ( + annotation_lists[t->state_list->lr0Isocore->state->number], + t->nitems, lookahead_filter); + ielr_compute_lookaheads (follow_kernel_items, always_follows, + this_state, t, lookahead_filter, + lookaheads); + ielr_compute_state (follow_kernel_items, always_follows, + annotation_lists, t, lookaheads, &last_state, + work, lookahead_filter, + &s->transitions->states[i]); + } + } + free (work); + } + + bitsetv_free (lookahead_filter); + bitsetv_free (lookaheads); + + /* Store states back in the states array. */ + states = xnrealloc (states, nstates, sizeof *states); + { + state_list *node; + for (node = first_state; node; node = node->next) + states[node->state->number] = node->state; + } + + /* In the case of canonical LR(1), copy item lookahead sets to reduction + lookahead sets. */ + if (!annotation_lists) + { + timevar_push (TV_IELR_PHASE4); + initialize_LA (); + state_list *node; + for (node = first_state; node; node = node->next) + if (!node->state->consistent) + { + size_t i = 0; + item_number *itemset = node->state->items; + size_t r; + for (r = 0; r < node->state->reductions->num; ++r) + { + rule *this_rule = node->state->reductions->rules[r]; + bitset lookahead_set = + node->state->reductions->lookahead_tokens[r]; + if (item_number_is_rule_number (*this_rule->rhs)) + ielr_compute_goto_follow_set (follow_kernel_items, + always_follows, node, + this_rule->lhs, lookahead_set); + else if (node->lookaheads) + { + /* We don't need to start the kernel item search back at + i=0 because both items and reductions are sorted on rule + number. */ + while (!item_number_is_rule_number (ritem[itemset[i]]) + || item_number_as_rule_number (ritem[itemset[i]]) + != this_rule->number) + { + ++i; + aver (i < node->state->nitems); + } + if (node->lookaheads[i]) + bitset_copy (lookahead_set, node->lookaheads[i]); + } + } + } + timevar_pop (TV_IELR_PHASE4); + } + + /* Free state list. */ + while (first_state) + { + state_list *node = first_state; + if (node->lookaheads) + { + size_t i; + for (i = 0; i < node->state->nitems; ++i) + if (node->lookaheads[i]) + bitset_free (node->lookaheads[i]); + free (node->lookaheads); + } + first_state = node->next; + free (node); + } +} + +void +ielr (void) +{ + LrType lr_type; + + /* Examine user options. */ + { + char *type = muscle_percent_define_get ("lr.type"); + if (0 == strcmp (type, "LALR")) + lr_type = LR_TYPE__LALR; + else if (0 == strcmp (type, "IELR")) + lr_type = LR_TYPE__IELR; + else if (0 == strcmp (type, "canonical LR")) + lr_type = LR_TYPE__CANONICAL_LR; + else + aver (false); + free (type); + } + + /* Phase 0: LALR(1). */ + timevar_push (TV_LALR); + if (lr_type == LR_TYPE__CANONICAL_LR) + set_goto_map (); + else + lalr (); + if (lr_type == LR_TYPE__LALR) + { + bitsetv_free (goto_follows); + timevar_pop (TV_LALR); + return; + } + timevar_pop (TV_LALR); + + { + bitsetv follow_kernel_items; + bitsetv always_follows; + InadequacyList **inadequacy_lists = NULL; + AnnotationList **annotation_lists = NULL; + struct obstack annotations_obstack; + AnnotationIndex max_annotations = 0; + + { + /* Phase 1: Compute Auxiliary Tables. */ + state ***predecessors; + timevar_push (TV_IELR_PHASE1); + ielr_compute_auxiliary_tables ( + &follow_kernel_items, &always_follows, + lr_type == LR_TYPE__CANONICAL_LR ? NULL : &predecessors); + timevar_pop (TV_IELR_PHASE1); + + /* Phase 2: Compute Annotations. */ + timevar_push (TV_IELR_PHASE2); + if (lr_type != LR_TYPE__CANONICAL_LR) + { + obstack_init (&annotations_obstack); + ielr_compute_annotation_lists (follow_kernel_items, always_follows, + predecessors, &max_annotations, + &inadequacy_lists, &annotation_lists, + &annotations_obstack); + { + state_number i; + for (i = 0; i < nstates; ++i) + free (predecessors[i]); + } + free (predecessors); + bitsetv_free (goto_follows); + lalr_free (); + } + timevar_pop (TV_IELR_PHASE2); + } + + /* Phase 3: Split States. */ + timevar_push (TV_IELR_PHASE3); + { + state_number nstates_lr0 = nstates; + ielr_split_states (follow_kernel_items, always_follows, + annotation_lists, max_annotations); + if (inadequacy_lists) + { + state_number i; + for (i = 0; i < nstates_lr0; ++i) + InadequacyList__delete (inadequacy_lists[i]); + } + } + free (inadequacy_lists); + if (annotation_lists) + obstack_free (&annotations_obstack, NULL); + free (annotation_lists); + bitsetv_free (follow_kernel_items); + bitsetv_free (always_follows); + timevar_pop (TV_IELR_PHASE3); + } + + /* Phase 4: Compute Reduction Lookaheads. */ + timevar_push (TV_IELR_PHASE4); + free (goto_map); + free (from_state); + free (to_state); + if (lr_type == LR_TYPE__CANONICAL_LR) + { + // Reduction lookaheads are computed in ielr_split_states above but are + // timed as part of phase 4. + set_goto_map (); + } + else + { + lalr (); + bitsetv_free (goto_follows); + } + timevar_pop (TV_IELR_PHASE4); +} diff --git a/src/ielr.h b/src/ielr.h new file mode 100644 index 00000000..27b3a445 --- /dev/null +++ b/src/ielr.h @@ -0,0 +1,46 @@ +/* IELR main implementation. + + Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of Bison, the GNU Compiler Compiler. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef IELR_H_ +# define IELR_H_ + +#include + +#include "state.h" + +/** + * \pre + * - \c ::states is of size \c ::nstates and defines an LALR(1) parser for + * the users's grammar. + * - \c ::ntokens is the number of tokens in the grammar. + * \post + * - \c ::states is of size \c ::nstates (which might be greater than + * ::nstates \@pre) and defines the type of parser specified by + * the value of the \c \%define variable \c lr.type. Its value can be: + * - \c "LALR". + * - \c "IELR". + * - \c "canonical LR". + */ +void ielr (void); + +bool ielr_item_has_lookahead (state *s, symbol_number lhs, size_t item, + symbol_number lookahead, state ***predecessors, + bitset **item_lookahead_sets); + +#endif /* !IELR_H_ */ From f805dfcb3fc6517dd0a49939fd6610999afcca00 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Tue, 21 Apr 2009 03:40:16 -0400 Subject: [PATCH 064/404] Finish implementing %define lr.type. Its value can be "LALR", "IELR", or "canonical LR". * lib/timevar.def (TV_IELR_PHASE1): New var. (TV_IELR_PHASE2): New var. (TV_IELR_PHASE3): New var. (TV_IELR_PHASE4): New var. * src/Makefile.am (bison_SOURCES): Add AnnotationList.c, AnnotationList.h, InadequacyList.c, InadequacyList.h, Sbitset.c, Sbitset.h, ielr.h, and ielr.c. * src/getargs.h, src/getargs.c (enum trace, trace_args, trace_types): Add trace_ielr. * src/lalr.h, src/lalr.c (ngotos): Export it. (F): Rename to... (goto_follows): ... this, update all uses, and export it. (set_goto_map): Export it. (map_goto): Export it. (compute_lookahead_tokens): Don't free goto_follows yet. Now handled in ielr. (initialize_LA): Export it. Move lookback allocation to... (lalr): ... here because, for canonical LR, initialize_LA must be invoked but lookback and much of the rest of LALR isn't needed. * main.c (main): Instead of lalr, invoke ielr, which invokes lalr. * src/reader.c (reader): Default lr.type to "LALR". Default lr.default_rules to "accepting" if lr.type is "canonical LR". Leave the default as "all" otherwise. Check for a valid lr.type value. * src/state.h, src/state.c (struct state_list): Add state_list member. (state_new): Initialize state_list member to NULL. (state_new_isocore): New function, exported. * tests/existing.at (AT_TEST_EXISTING_GRAMMAR): New macro that exercises all values of lr.type. (GNU AWK Grammar): Rename test group to... (GNU AWK 3.1.0 Grammar): ... this, and extend to use AT_TEST_EXISTING_GRAMMAR. (GNU Cim Grammar): Extend to use AT_TEST_EXISTING_GRAMMAR. (GNU pic Grammar): Rename test group to... (GNU pic (Groff 1.18.1) Grammar): ... this, and extend to use AT_TEST_EXISTING_GRAMMAR. * tests/reduce.at (AT_TEST_LR_TYPE): New macro that exercises all values of lr.type. (Single State Split): New test groups using AT_TEST_LR_TYPE. (Lane Split): Likewise. (Complex Lane Split): Likewise. (Split During Added Lookahead Propagation): Likewise. --- ChangeLog | 50 ++ lib/timevar.def | 6 +- src/Makefile.am | 8 +- src/getargs.c | 4 +- src/getargs.h | 3 +- src/lalr.c | 33 +- src/lalr.h | 40 +- src/main.c | 11 +- src/reader.c | 13 +- src/state.c | 31 +- src/state.h | 12 +- tests/existing.at | 1709 +++++++++++++++++++++++++++++++++++++++++++-- tests/reduce.at | 1083 ++++++++++++++++++++++++++++ 13 files changed, 2904 insertions(+), 99 deletions(-) diff --git a/ChangeLog b/ChangeLog index 962f5342..d7e97f34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,53 @@ +2009-04-21 Joel E. Denny + + Finish implementing %define lr.type. + Its value can be "LALR", "IELR", or "canonical LR". + * lib/timevar.def (TV_IELR_PHASE1): New var. + (TV_IELR_PHASE2): New var. + (TV_IELR_PHASE3): New var. + (TV_IELR_PHASE4): New var. + * src/Makefile.am (bison_SOURCES): Add AnnotationList.c, + AnnotationList.h, InadequacyList.c, InadequacyList.h, Sbitset.c, + Sbitset.h, ielr.h, and ielr.c. + * src/getargs.h, src/getargs.c (enum trace, trace_args, + trace_types): Add trace_ielr. + * src/lalr.h, src/lalr.c (ngotos): Export it. + (F): Rename to... + (goto_follows): ... this, update all uses, and export it. + (set_goto_map): Export it. + (map_goto): Export it. + (compute_lookahead_tokens): Don't free goto_follows yet. Now + handled in ielr. + (initialize_LA): Export it. Move lookback allocation to... + (lalr): ... here because, for canonical LR, initialize_LA must + be invoked but lookback and much of the rest of LALR isn't + needed. + * main.c (main): Instead of lalr, invoke ielr, which invokes + lalr. + * src/reader.c (reader): Default lr.type to "LALR". + Default lr.default_rules to "accepting" if lr.type is "canonical + LR". Leave the default as "all" otherwise. + Check for a valid lr.type value. + * src/state.h, src/state.c (struct state_list): Add state_list + member. + (state_new): Initialize state_list member to NULL. + (state_new_isocore): New function, exported. + * tests/existing.at (AT_TEST_EXISTING_GRAMMAR): New macro that + exercises all values of lr.type. + (GNU AWK Grammar): Rename test group to... + (GNU AWK 3.1.0 Grammar): ... this, and extend to use + AT_TEST_EXISTING_GRAMMAR. + (GNU Cim Grammar): Extend to use AT_TEST_EXISTING_GRAMMAR. + (GNU pic Grammar): Rename test group to... + (GNU pic (Groff 1.18.1) Grammar): ... this, and extend to use + AT_TEST_EXISTING_GRAMMAR. + * tests/reduce.at (AT_TEST_LR_TYPE): New macro that exercises + all values of lr.type. + (Single State Split): New test groups using AT_TEST_LR_TYPE. + (Lane Split): Likewise. + (Complex Lane Split): Likewise. + (Split During Added Lookahead Propagation): Likewise. + 2009-04-21 Joel E. Denny Add new files for IELR and canonical LR implementation. diff --git a/lib/timevar.def b/lib/timevar.def index 3a4128f2..5caf7c3d 100644 --- a/lib/timevar.def +++ b/lib/timevar.def @@ -1,6 +1,6 @@ /* This file contains the definitions for timing variables used to -*- C -*- measure run-time performance of the compiler. - Copyright (C) 2002, 2007 Free Software Foundation, Inc. + Copyright (C) 2002, 2007, 2009 Free Software Foundation, Inc. Contributed by Akim Demaille . This file is part of Bison, the GNU Compiler Compiler. @@ -41,6 +41,10 @@ DEFTIMEVAR (TV_REDUCE , "reducing the grammar") DEFTIMEVAR (TV_SETS , "computing the sets") DEFTIMEVAR (TV_LR0 , "LR(0)") DEFTIMEVAR (TV_LALR , "LALR(1)") +DEFTIMEVAR (TV_IELR_PHASE1 , "IELR(1) Phase 1") +DEFTIMEVAR (TV_IELR_PHASE2 , "IELR(1) Phase 2") +DEFTIMEVAR (TV_IELR_PHASE3 , "IELR(1) Phase 3") +DEFTIMEVAR (TV_IELR_PHASE4 , "IELR(1) Phase 4") DEFTIMEVAR (TV_CONFLICTS , "conflicts") /* Time spent outputing results. */ diff --git a/src/Makefile.am b/src/Makefile.am index a5cf94ee..825266a8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ # Make bison/src. -# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software -# Foundation, Inc. +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# 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 @@ -31,7 +31,10 @@ bin_SCRIPTS = $(YACC_SCRIPT) EXTRA_SCRIPTS = yacc bison_SOURCES = \ + AnnotationList.c AnnotationList.h \ + InadequacyList.c InadequacyList.h \ LR0.c LR0.h \ + Sbitset.c Sbitset.h \ assoc.c assoc.h \ closure.c closure.h \ complain.c complain.h \ @@ -42,6 +45,7 @@ bison_SOURCES = \ getargs.c getargs.h \ gram.c gram.h \ lalr.h lalr.c \ + ielr.h ielr.c \ location.c location.h \ main.c \ muscle_tab.c muscle_tab.h \ diff --git a/src/getargs.c b/src/getargs.c index bb060c55..4b35171e 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -1,7 +1,7 @@ /* Parse command line arguments for Bison. Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -181,6 +181,7 @@ static const char * const trace_args[] = "m4 - m4 traces", "skeleton - skeleton postprocessing", "time - time consumption", + "ielr - IELR conversion", "all - all of the above", 0 }; @@ -200,6 +201,7 @@ static const int trace_types[] = trace_m4, trace_skeleton, trace_time, + trace_ielr, trace_all }; diff --git a/src/getargs.h b/src/getargs.h index 11390674..d9d95202 100644 --- a/src/getargs.h +++ b/src/getargs.h @@ -1,7 +1,7 @@ /* Parse command line arguments for bison. Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -107,6 +107,7 @@ enum trace trace_skeleton = 1 << 9, /**< Skeleton postprocessing. */ trace_m4 = 1 << 10, /**< M4 traces. */ trace_muscles = 1 << 11, /**< M4 definitions of the muscles. */ + trace_ielr = 1 << 12, /**< IELR conversion. */ trace_all = ~0 /**< All of the above. */ }; /** What debug items bison displays during its run. */ diff --git a/src/lalr.c b/src/lalr.c index 9f5d43f3..01011498 100644 --- a/src/lalr.c +++ b/src/lalr.c @@ -43,9 +43,10 @@ #include "symtab.h" goto_number *goto_map; -static goto_number ngotos; +goto_number ngotos; state_number *from_state; state_number *to_state; +bitsetv goto_follows = NULL; /* Linked list of goto numbers. */ typedef struct goto_list @@ -64,17 +65,13 @@ static bitsetv LA = NULL; size_t nLA; -/* And for the famous F variable, which name is so descriptive that a - comment is hardly needed. . */ -static bitsetv F = NULL; - static goto_number **includes; static goto_list **lookback; -static void +void set_goto_map (void) { state_number s; @@ -134,12 +131,7 @@ set_goto_map (void) } - -/*----------------------------------------------------------. -| Map a state/symbol pair into its numeric representation. | -`----------------------------------------------------------*/ - -static goto_number +goto_number map_goto (state_number s0, symbol_number sym) { goto_number high; @@ -174,7 +166,7 @@ initialize_F (void) goto_number i; - F = bitsetv_create (ngotos, ntokens, BITSET_FIXED); + goto_follows = bitsetv_create (ngotos, ntokens, BITSET_FIXED); for (i = 0; i < ngotos; i++) { @@ -183,7 +175,7 @@ initialize_F (void) int j; FOR_EACH_SHIFT (sp, j) - bitset_set (F[i], TRANSITION_SYMBOL (sp, j)); + bitset_set (goto_follows[i], TRANSITION_SYMBOL (sp, j)); for (; j < sp->num; j++) { @@ -203,7 +195,7 @@ initialize_F (void) } } - relation_digraph (reads, ngotos, &F); + relation_digraph (reads, ngotos, &goto_follows); for (i = 0; i < ngotos; i++) free (reads[i]); @@ -264,7 +256,7 @@ build_relations (void) { done = true; /* Each rhs ends in a rule number, and there is a - sentinel before the first rhs, so it is safe to + sentinel (ritem[-1]=0) before the first rhs, so it is safe to decrement RP here. */ rp--; if (ISVAR (*rp)) @@ -303,7 +295,7 @@ compute_FOLLOWS (void) { goto_number i; - relation_digraph (includes, ngotos, &F); + relation_digraph (includes, ngotos, &goto_follows); for (i = 0; i < ngotos; i++) free (includes[i]); @@ -320,14 +312,13 @@ compute_lookahead_tokens (void) for (i = 0; i < nLA; i++) for (sp = lookback[i]; sp; sp = sp->next) - bitset_or (LA[i], LA[i], F[sp->value]); + bitset_or (LA[i], LA[i], goto_follows[sp->value]); /* Free LOOKBACK. */ for (i = 0; i < nLA; i++) LIST_FREE (goto_list, lookback[i]); free (lookback); - bitsetv_free (F); } @@ -373,7 +364,7 @@ state_lookahead_tokens_count (state *s, bool default_rule_only_for_accept) | Compute LA, NLA, and the lookahead_tokens members. | `----------------------------------------------------*/ -static void +void initialize_LA (void) { state_number i; @@ -395,7 +386,6 @@ initialize_LA (void) nLA = 1; pLA = LA = bitsetv_create (nLA, ntokens, BITSET_FIXED); - lookback = xcalloc (nLA, sizeof *lookback); /* Initialize the members LOOKAHEAD_TOKENS for each state whose reductions require lookahead tokens. */ @@ -454,6 +444,7 @@ lalr (void) initialize_LA (); set_goto_map (); initialize_F (); + lookback = xcalloc (nLA, sizeof *lookback); build_relations (); compute_FOLLOWS (); compute_lookahead_tokens (); diff --git a/src/lalr.h b/src/lalr.h index c65c9b48..103a4c86 100644 --- a/src/lalr.h +++ b/src/lalr.h @@ -1,7 +1,7 @@ /* Compute lookahead criteria for bison, - Copyright (C) 1984, 1986, 1989, 2000, 2002, 2004, 2006, 2007 Free Software - Foundation, Inc. + Copyright (C) 1984, 1986, 1989, 2000, 2002, 2004, 2006, 2007, 2009 + Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -37,13 +37,29 @@ which rules need lookahead in each state, and which lookahead tokens they accept. - Builds: - - #goto_map - - #from_state - - #to_state + Also builds: + - #goto_map + - #from_state + - #to_state + - #goto_follows */ void lalr (void); +/** + * Set #nLA and allocate all reduction lookahead sets. Normally invoked by + * #lalr. + */ +void initialize_LA (void); + +/** + * Build only: + * - #goto_map + * - #from_state + * - #to_state + * Normally invoked by #lalr. + */ +void set_goto_map (void); + /** * Update state numbers recorded in #goto_map, #from_state, and #to_state such * that: @@ -62,7 +78,6 @@ void lalr_update_state_numbers (state_number old_to_new[], Can be performed once the action tables are computed. */ void lalr_free (void); - typedef size_t goto_number; # define GOTO_NUMBER_MAXIMUM ((goto_number) -1) @@ -73,11 +88,20 @@ typedef size_t goto_number; TO_STATE of the first of them. */ extern goto_number *goto_map; -/** State number which a transition leads from. */ +/** The size of #from_state and #to_state. */ +extern goto_number ngotos; + +/** State number which a transition leads from. */ extern state_number *from_state; /** State number it leads to. */ extern state_number *to_state; +/** Map a state/symbol pair into its numeric representation. */ +goto_number map_goto (state_number s0, symbol_number sym); + +/* goto_follows[i] is the set of tokens following goto i. */ +extern bitsetv goto_follows; + #endif /* !LALR_H_ */ diff --git a/src/main.c b/src/main.c index b3ef70ac..6c93a4ef 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,7 @@ /* Top level entry point of Bison. Copyright (C) 1984, 1986, 1989, 1992, 1995, 2000, 2001, 2002, 2004, - 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -35,6 +35,7 @@ #include "getargs.h" #include "gram.h" #include "lalr.h" +#include "ielr.h" #include "muscle_tab.h" #include "nullable.h" #include "output.h" @@ -102,10 +103,10 @@ main (int argc, char *argv[]) generate_states (); timevar_pop (TV_LR0); - /* make it deterministic. In file lalr. */ - timevar_push (TV_LALR); - lalr (); - timevar_pop (TV_LALR); + /* Make it deterministic by computing lookahead sets. Except when LALR(1) is + requested, split states to eliminate LR(1)-relative inadequacies. In file + lalr and ielr. */ + ielr (); /* Find and record any conflicts: places where one token of lookahead is not enough to disambiguate the parsing. In file diff --git a/src/reader.c b/src/reader.c index 68e8b44e..b2fdc3b6 100644 --- a/src/reader.c +++ b/src/reader.c @@ -555,11 +555,22 @@ reader (void) gram_scanner_initialize (); gram_parse (); - muscle_percent_define_default ("lr.default_rules", "all"); + /* IELR would be a better default, but LALR is historically the default. */ + { + char *lr_type; + muscle_percent_define_default ("lr.type", "LALR"); + lr_type = muscle_percent_define_get ("lr.type"); + if (0 != strcmp (lr_type, "canonical LR")) + muscle_percent_define_default ("lr.default_rules", "all"); + else + muscle_percent_define_default ("lr.default_rules", "accepting"); + free (lr_type); + } /* Check front-end %define variable values. */ { static char const * const values[] = { + "lr.type", "LALR", "IELR", "canonical LR", NULL, "lr.default_rules", "all", "consistent", "accepting", NULL, NULL }; diff --git a/src/state.c b/src/state.c index d3460c15..a0f5cdb8 100644 --- a/src/state.c +++ b/src/state.c @@ -1,7 +1,7 @@ /* Type definitions for nondeterministic finite state machine for Bison. - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software - Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 Free + Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -142,6 +142,7 @@ state_new (symbol_number accessing_symbol, res->transitions = NULL; res->reductions = NULL; res->errs = NULL; + res->state_list = NULL; res->consistent = 0; res->solved_conflicts = NULL; res->solved_conflicts_xml = NULL; @@ -154,6 +155,32 @@ state_new (symbol_number accessing_symbol, return res; } +state * +state_new_isocore (state const *s) +{ + state *res; + size_t items_size = s->nitems * sizeof *s->items; + + aver (nstates < STATE_NUMBER_MAXIMUM); + + res = xmalloc (offsetof (state, items) + items_size); + res->number = nstates++; + res->accessing_symbol = s->accessing_symbol; + res->transitions = + transitions_new (s->transitions->num, s->transitions->states); + res->reductions = reductions_new (s->reductions->num, s->reductions->rules); + res->errs = NULL; + res->state_list = NULL; + res->consistent = s->consistent; + res->solved_conflicts = NULL; + res->solved_conflicts_xml = NULL; + + res->nitems = s->nitems; + memcpy (res->items, s->items, items_size); + + return res; +} + /*---------. | Free S. | diff --git a/src/state.h b/src/state.h index 4afc1f00..931b48f1 100644 --- a/src/state.h +++ b/src/state.h @@ -1,7 +1,7 @@ /* Type definitions for nondeterministic finite state machine for Bison. - Copyright (C) 1984, 1989, 2000, 2001, 2002, 2003, 2004, 2007 Free - Software Foundation, Inc. + Copyright (C) 1984, 1989, 2000, 2001, 2002, 2003, 2004, 2007, 2009 + Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -193,6 +193,8 @@ typedef struct | states. | `---------*/ +struct state_list; + struct state { state_number number; @@ -201,6 +203,11 @@ struct state reductions *reductions; errs *errs; + /* When an includer (such as ielr.c) needs to store states in a list, the + includer can define struct state_list as the list node structure and can + store in this member a reference to the node containing each state. */ + struct state_list *state_list; + /* If non-zero, then no lookahead sets on reduce actions are needed to decide what to do in state S. */ char consistent; @@ -222,6 +229,7 @@ extern state *final_state; /* Create a new state with ACCESSING_SYMBOL for those items. */ state *state_new (symbol_number accessing_symbol, size_t core_size, item_number *core); +state *state_new_isocore (state const *s); /* Set the transitions of STATE. */ void state_transitions_set (state *s, int num, state **trans); diff --git a/tests/existing.at b/tests/existing.at index ba2c40cb..b754f3c6 100644 --- a/tests/existing.at +++ b/tests/existing.at @@ -1,7 +1,7 @@ # Exercising Bison on actual grammars. -*- Autotest -*- -# Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004, 2005, -# 2007 Free Software Foundation, Inc. +# Copyright (C) 1989, 1990, 1991, 1992, 2000, 2001, 2002, 2003, 2004, +# 2005, 2007, 2009 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 @@ -17,21 +17,70 @@ # along with this program. If not, see . AT_BANNER([[Existing Grammars.]]) -## ----------------- ## -## GNU AWK Grammar. ## -## ----------------- ## -AT_SETUP([GNU AWK Grammar]) +# AT_TEST_EXISTING_GRAMMAR(DESCRIPTION, +# DECLS, GRAMMAR, INPUT, +# BISON-STDERR, LAST-STATE, LALR1-DIFF, +# [OTHER-CHECKS], +# [PARSER-EXIT-VALUE], +# [PARSER-STDOUT], [PARSER-STDERR]) +# -------------------------------------------------------------- +m4_define([AT_TEST_EXISTING_GRAMMAR], [_AT_TEST_EXISTING_GRAMMAR([$][1], $@)]) + +m4_define([_AT_TEST_EXISTING_GRAMMAR], +[ +dnl See how the parser tables have changed. As the .output format evolves, the +dnl diff comments with line numbers might be a pain to maintain. When that +dnl time comes, just use sed to drop the line numbers. For now, as LR(1) +dnl support is rapidly evolving, let's keep that information to be careful. +dnl However, we don't do diffs for canonical LR(1) because the diff is huge. +m4_pushdef([AT_LALR1_DIFF_CHECK], +[AT_CHECK([[sed 's/^%define lr.type .*$//' input.y > input-lalr.y]]) +AT_BISON_CHECK([[--report=all input-lalr.y]], [[0]], [ignore], [ignore]) +AT_CHECK([[diff -u input-lalr.output input.output \ + | sed -n '/^@@/,$p' | sed 's/^ $//']], + [[0]], [$1])]) + +AT_TEST_TABLES_AND_PARSE([$2[: LALR(1)]], [[LALR]], [[last-state]], + [[%define lr.type "LALR" +]$3], + [$4], [$5], [$6], [$7], + [AT_LALR1_DIFF_CHECK([$8])$9]m4_if($#, 8, [], + $#, 9, [], + [, m4_shiftn(9, + $@)])) +AT_TEST_TABLES_AND_PARSE([$2[: IELR(1)]], [[IELR]], [[last-state]], + [[%define lr.type "IELR" +]$3], + [$4], [$5], [$6], [$7], + [AT_LALR1_DIFF_CHECK([$8])$9]m4_if($#, 8, [], + $#, 9, [], + [, m4_shiftn(9, + $@)])) +AT_TEST_TABLES_AND_PARSE([$2[: Canonical LR(1)]], [[canonical LR]], + [[last-state,no-xml]], + [[%define lr.type "canonical LR" +]$3], + [$4], [$5], [$6], [$7], + [$9]m4_if($#, 8, [], $#, 9, [], [, m4_shiftn(9, $@)])) + +m4_popdef([AT_LALR1_DIFF_CHECK]) +]) + + + +## ----------------------- ## +## GNU AWK 3.1.0 Grammar. ## +## ----------------------- ## # We have been careful to strip all the actions excepts the -# mid-rule actions. We rely on %expect to check that there are -# indeed 65 SR conflicts. +# mid-rule actions. # -# Bison was once wrong, due to an incorrect computation of nullable. -# It reported 485 SR conflicts! +# There are 65 SR conflicts. Bison was once wrong, due to an incorrect +# computation of nullable. It reported 485 SR conflicts! -AT_DATA([[input.y]], -[[%expect 65 +AT_TEST_EXISTING_GRAMMAR([[GNU AWK 3.1.0 Grammar]], +[[%error-verbose %token FUNC_CALL NAME REGEXP %token ERROR @@ -66,8 +115,8 @@ AT_DATA([[input.y]], %left INCREMENT DECREMENT %left '$' %left '(' ')' -%% - +]], +[[ start : opt_nls program opt_nls ; @@ -344,29 +393,397 @@ semi comma : ',' opt_nls ; +]], -%% -]]) +dnl INPUT +dnl +dnl For example, in AWK: +dnl +dnl getline $!4*0; +dnl +dnl The grammar below (from GNU AWK 3.1.0) using canonical LR(1) or IELR(1) +dnl parses it as: +dnl +dnl getline $!(4*0); +dnl +dnl That is, they shift `*' immediately and make it part of the getline +dnl argument. +dnl +dnl The grammar below using LALR(1) parses it as a syntax error. So does +dnl GNU AWK 3.0.6, 3.1.0, and 3.1.1. They reduce the full getline expression +dnl before shifting `*' even though `*' is not a valid lookahead. +dnl +dnl GNU AWK 3.1.2, 3.1.3, 3.1.4, and 3.1.5 parse it as: +dnl +dnl (getline $!4)*0; +dnl +dnl That is, like the other versions of GNU AWK, they reduce the full getline +dnl expression before shifting `*'. However, because of a different LHS on the +dnl getline rule, `*' actually is a valid lookahead. Solaris /usr/xpg4/bin/awk +dnl and the Open Group awk specification seem to agree: +dnl +dnl http://www.opengroup.org/pubs/online/7908799/xcu/awk.html +dnl +dnl /bin/nawk and /bin/awk on Solaris 10 report it as a syntax error, but they +dnl don't like even `print $!4;'. +[[LEX_GETLINE, '$', '!', YNUMBER, '*', YNUMBER, ';']], -# Pass plenty of options, to exercise plenty of code, even if we -# don't actually check the output. But SEGV is watching us, and -# so might do dmalloc. -AT_BISON_CHECK([[--verbose --defines input.y]]) +dnl BISON-STDERR +[AT_COND_CASE([[canonical LR]], +[[input.y: conflicts: 265 shift/reduce]], +[[input.y: conflicts: 65 shift/reduce]])[ +]], -AT_CLEANUP +dnl LAST-STATE +[AT_COND_CASE([[LALR]], [[319]], [[canonical LR]], [[2358]], [[328]])], + +dnl LALR1-DIFF not used for canonical LR(1) because the diff is huge. +dnl Isocore map from LALR(1) state number to new state number plus descriptions +dnl of any change in the actions resulting in a change in accepted language: +dnl - 24 -> 320 +dnl - 16 -> 321 +dnl - 17 -> 322 +dnl - 20 -> 323 +dnl - 21 -> 324 +dnl - 54 -> 325 +dnl - 56 -> 326: reduce -> shift on '*', '/', and '%' +dnl - 58 -> 327: reduce -> shift on '*', '/', and '%' +dnl - 61 -> 328: reduce -> shift on '*', '/', and '%' +[AT_COND_CASE([[LALR]], [], +[[@@ -712,7 +712,7 @@ + 156 | . '$' non_post_simp_exp + + NAME shift, and go to state 9 +- '$' shift, and go to state 24 ++ '$' shift, and go to state 320 + + NAME [reduce using rule 152 (opt_variable)] + '$' [reduce using rule 152 (opt_variable)] +@@ -5379,7 +5379,7 @@ + 156 | . '$' non_post_simp_exp + + NAME shift, and go to state 9 +- '$' shift, and go to state 24 ++ '$' shift, and go to state 320 + + NAME [reduce using rule 152 (opt_variable)] + '$' [reduce using rule 152 (opt_variable)] +@@ -5399,7 +5399,7 @@ + 156 | . '$' non_post_simp_exp + + NAME shift, and go to state 9 +- '$' shift, and go to state 24 ++ '$' shift, and go to state 320 + + NAME [reduce using rule 152 (opt_variable)] + '$' [reduce using rule 152 (opt_variable)] +@@ -6214,7 +6214,7 @@ + 156 | . '$' non_post_simp_exp + + NAME shift, and go to state 9 +- '$' shift, and go to state 24 ++ '$' shift, and go to state 320 + + NAME [reduce using rule 152 (opt_variable)] + '$' [reduce using rule 152 (opt_variable)] +@@ -11099,3 +11099,274 @@ + 45 statement: LEX_FOR '(' opt_exp semi opt_nls exp semi opt_nls opt_exp r_paren opt_nls statement . + + $default reduce using rule 45 (statement) ++ ++ ++state 320 ++ ++ 139 non_post_simp_exp: . '!' simp_exp ++ 140 | . '(' exp r_paren ++ 141 | . LEX_BUILTIN '(' opt_expression_list r_paren ++ 142 | . LEX_LENGTH '(' opt_expression_list r_paren ++ 143 | . LEX_LENGTH ++ 144 | . FUNC_CALL '(' opt_expression_list r_paren ++ 145 | . variable ++ 146 | . INCREMENT variable ++ 147 | . DECREMENT variable ++ 148 | . YNUMBER ++ 149 | . YSTRING ++ 150 | . '-' simp_exp ++ 151 | . '+' simp_exp ++ 154 variable: . NAME ++ 155 | . NAME '[' expression_list ']' ++ 156 | . '$' non_post_simp_exp ++ 156 | '$' . non_post_simp_exp ++ ++ FUNC_CALL shift, and go to state 8 ++ NAME shift, and go to state 9 ++ YNUMBER shift, and go to state 10 ++ YSTRING shift, and go to state 11 ++ INCREMENT shift, and go to state 321 ++ DECREMENT shift, and go to state 322 ++ LEX_BUILTIN shift, and go to state 18 ++ LEX_LENGTH shift, and go to state 19 ++ '+' shift, and go to state 323 ++ '-' shift, and go to state 324 ++ '!' shift, and go to state 325 ++ '$' shift, and go to state 320 ++ '(' shift, and go to state 55 ++ ++ non_post_simp_exp go to state 62 ++ variable go to state 63 ++ ++ ++state 321 ++ ++ 146 non_post_simp_exp: INCREMENT . variable ++ 154 variable: . NAME ++ 155 | . NAME '[' expression_list ']' ++ 156 | . '$' non_post_simp_exp ++ ++ NAME shift, and go to state 9 ++ '$' shift, and go to state 320 ++ ++ variable go to state 50 ++ ++ ++state 322 ++ ++ 147 non_post_simp_exp: DECREMENT . variable ++ 154 variable: . NAME ++ 155 | . NAME '[' expression_list ']' ++ 156 | . '$' non_post_simp_exp ++ ++ NAME shift, and go to state 9 ++ '$' shift, and go to state 320 ++ ++ variable go to state 51 ++ ++ ++state 323 ++ ++ 130 simp_exp: . non_post_simp_exp ++ 131 | . simp_exp '^' simp_exp ++ 132 | . simp_exp '*' simp_exp ++ 133 | . simp_exp '/' simp_exp ++ 134 | . simp_exp '%' simp_exp ++ 135 | . simp_exp '+' simp_exp ++ 136 | . simp_exp '-' simp_exp ++ 137 | . variable INCREMENT ++ 138 | . variable DECREMENT ++ 139 non_post_simp_exp: . '!' simp_exp ++ 140 | . '(' exp r_paren ++ 141 | . LEX_BUILTIN '(' opt_expression_list r_paren ++ 142 | . LEX_LENGTH '(' opt_expression_list r_paren ++ 143 | . LEX_LENGTH ++ 144 | . FUNC_CALL '(' opt_expression_list r_paren ++ 145 | . variable ++ 146 | . INCREMENT variable ++ 147 | . DECREMENT variable ++ 148 | . YNUMBER ++ 149 | . YSTRING ++ 150 | . '-' simp_exp ++ 151 | . '+' simp_exp ++ 151 | '+' . simp_exp ++ 154 variable: . NAME ++ 155 | . NAME '[' expression_list ']' ++ 156 | . '$' non_post_simp_exp ++ ++ FUNC_CALL shift, and go to state 8 ++ NAME shift, and go to state 9 ++ YNUMBER shift, and go to state 10 ++ YSTRING shift, and go to state 11 ++ INCREMENT shift, and go to state 16 ++ DECREMENT shift, and go to state 17 ++ LEX_BUILTIN shift, and go to state 18 ++ LEX_LENGTH shift, and go to state 19 ++ '+' shift, and go to state 20 ++ '-' shift, and go to state 21 ++ '!' shift, and go to state 54 ++ '$' shift, and go to state 24 ++ '(' shift, and go to state 55 ++ ++ simp_exp go to state 326 ++ non_post_simp_exp go to state 35 ++ variable go to state 57 ++ ++ ++state 324 ++ ++ 130 simp_exp: . non_post_simp_exp ++ 131 | . simp_exp '^' simp_exp ++ 132 | . simp_exp '*' simp_exp ++ 133 | . simp_exp '/' simp_exp ++ 134 | . simp_exp '%' simp_exp ++ 135 | . simp_exp '+' simp_exp ++ 136 | . simp_exp '-' simp_exp ++ 137 | . variable INCREMENT ++ 138 | . variable DECREMENT ++ 139 non_post_simp_exp: . '!' simp_exp ++ 140 | . '(' exp r_paren ++ 141 | . LEX_BUILTIN '(' opt_expression_list r_paren ++ 142 | . LEX_LENGTH '(' opt_expression_list r_paren ++ 143 | . LEX_LENGTH ++ 144 | . FUNC_CALL '(' opt_expression_list r_paren ++ 145 | . variable ++ 146 | . INCREMENT variable ++ 147 | . DECREMENT variable ++ 148 | . YNUMBER ++ 149 | . YSTRING ++ 150 | . '-' simp_exp ++ 150 | '-' . simp_exp ++ 151 | . '+' simp_exp ++ 154 variable: . NAME ++ 155 | . NAME '[' expression_list ']' ++ 156 | . '$' non_post_simp_exp ++ ++ FUNC_CALL shift, and go to state 8 ++ NAME shift, and go to state 9 ++ YNUMBER shift, and go to state 10 ++ YSTRING shift, and go to state 11 ++ INCREMENT shift, and go to state 16 ++ DECREMENT shift, and go to state 17 ++ LEX_BUILTIN shift, and go to state 18 ++ LEX_LENGTH shift, and go to state 19 ++ '+' shift, and go to state 20 ++ '-' shift, and go to state 21 ++ '!' shift, and go to state 54 ++ '$' shift, and go to state 24 ++ '(' shift, and go to state 55 ++ ++ simp_exp go to state 327 ++ non_post_simp_exp go to state 35 ++ variable go to state 57 ++ ++ ++state 325 ++ ++ 130 simp_exp: . non_post_simp_exp ++ 131 | . simp_exp '^' simp_exp ++ 132 | . simp_exp '*' simp_exp ++ 133 | . simp_exp '/' simp_exp ++ 134 | . simp_exp '%' simp_exp ++ 135 | . simp_exp '+' simp_exp ++ 136 | . simp_exp '-' simp_exp ++ 137 | . variable INCREMENT ++ 138 | . variable DECREMENT ++ 139 non_post_simp_exp: . '!' simp_exp ++ 139 | '!' . simp_exp ++ 140 | . '(' exp r_paren ++ 141 | . LEX_BUILTIN '(' opt_expression_list r_paren ++ 142 | . LEX_LENGTH '(' opt_expression_list r_paren ++ 143 | . LEX_LENGTH ++ 144 | . FUNC_CALL '(' opt_expression_list r_paren ++ 145 | . variable ++ 146 | . INCREMENT variable ++ 147 | . DECREMENT variable ++ 148 | . YNUMBER ++ 149 | . YSTRING ++ 150 | . '-' simp_exp ++ 151 | . '+' simp_exp ++ 154 variable: . NAME ++ 155 | . NAME '[' expression_list ']' ++ 156 | . '$' non_post_simp_exp ++ ++ FUNC_CALL shift, and go to state 8 ++ NAME shift, and go to state 9 ++ YNUMBER shift, and go to state 10 ++ YSTRING shift, and go to state 11 ++ INCREMENT shift, and go to state 16 ++ DECREMENT shift, and go to state 17 ++ LEX_BUILTIN shift, and go to state 18 ++ LEX_LENGTH shift, and go to state 19 ++ '+' shift, and go to state 20 ++ '-' shift, and go to state 21 ++ '!' shift, and go to state 54 ++ '$' shift, and go to state 24 ++ '(' shift, and go to state 55 ++ ++ simp_exp go to state 328 ++ non_post_simp_exp go to state 35 ++ variable go to state 57 ++ ++ ++state 326 ++ ++ 131 simp_exp: simp_exp . '^' simp_exp ++ 132 | simp_exp . '*' simp_exp ++ 133 | simp_exp . '/' simp_exp ++ 134 | simp_exp . '%' simp_exp ++ 135 | simp_exp . '+' simp_exp ++ 136 | simp_exp . '-' simp_exp ++ 151 non_post_simp_exp: '+' simp_exp . [error, FUNC_CALL, NAME, YNUMBER, YSTRING, RELOP, APPEND_OP, MATCHOP, NEWLINE, LEX_IN, LEX_AND, LEX_OR, INCREMENT, DECREMENT, LEX_BUILTIN, LEX_LENGTH, '?', ':', ',', '<', '>', '|', TWOWAYIO, '+', '-', '!', '$', '(', ')', '@:>@', '{', ';'] ++ ++ '*' shift, and go to state 89 ++ '/' shift, and go to state 90 ++ '%' shift, and go to state 91 ++ '^' shift, and go to state 92 ++ ++ $default reduce using rule 151 (non_post_simp_exp) ++ ++ Conflict between rule 151 and token '+' resolved as reduce ('+' < UNARY). ++ Conflict between rule 151 and token '-' resolved as reduce ('-' < UNARY). ++ ++ ++state 327 ++ ++ 131 simp_exp: simp_exp . '^' simp_exp ++ 132 | simp_exp . '*' simp_exp ++ 133 | simp_exp . '/' simp_exp ++ 134 | simp_exp . '%' simp_exp ++ 135 | simp_exp . '+' simp_exp ++ 136 | simp_exp . '-' simp_exp ++ 150 non_post_simp_exp: '-' simp_exp . [error, FUNC_CALL, NAME, YNUMBER, YSTRING, RELOP, APPEND_OP, MATCHOP, NEWLINE, LEX_IN, LEX_AND, LEX_OR, INCREMENT, DECREMENT, LEX_BUILTIN, LEX_LENGTH, '?', ':', ',', '<', '>', '|', TWOWAYIO, '+', '-', '!', '$', '(', ')', '@:>@', '{', ';'] ++ ++ '*' shift, and go to state 89 ++ '/' shift, and go to state 90 ++ '%' shift, and go to state 91 ++ '^' shift, and go to state 92 ++ ++ $default reduce using rule 150 (non_post_simp_exp) ++ ++ Conflict between rule 150 and token '+' resolved as reduce ('+' < UNARY). ++ Conflict between rule 150 and token '-' resolved as reduce ('-' < UNARY). ++ ++ ++state 328 ++ ++ 131 simp_exp: simp_exp . '^' simp_exp ++ 132 | simp_exp . '*' simp_exp ++ 133 | simp_exp . '/' simp_exp ++ 134 | simp_exp . '%' simp_exp ++ 135 | simp_exp . '+' simp_exp ++ 136 | simp_exp . '-' simp_exp ++ 139 non_post_simp_exp: '!' simp_exp . [error, FUNC_CALL, NAME, YNUMBER, YSTRING, RELOP, APPEND_OP, MATCHOP, NEWLINE, LEX_IN, LEX_AND, LEX_OR, INCREMENT, DECREMENT, LEX_BUILTIN, LEX_LENGTH, '?', ':', ',', '<', '>', '|', TWOWAYIO, '+', '-', '!', '$', '(', ')', '@:>@', '{', ';'] ++ ++ '*' shift, and go to state 89 ++ '/' shift, and go to state 90 ++ '%' shift, and go to state 91 ++ '^' shift, and go to state 92 ++ ++ $default reduce using rule 139 (non_post_simp_exp) ++ ++ Conflict between rule 139 and token '+' resolved as reduce ('+' < UNARY). ++ Conflict between rule 139 and token '-' resolved as reduce ('-' < UNARY). +]])], + +dnl OTHER-CHECKS +[], + +dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR +dnl In the case of the syntax error, the parser recovers, so it returns 0. +[[0]], +[], +[AT_COND_CASE([[LALR]], +[[syntax error, unexpected '*', expecting NEWLINE or '{' or ';' +]])]) ## ----------------- ## ## GNU Cim Grammar. ## ## ----------------- ## -AT_SETUP([GNU Cim Grammar]) - # GNU Cim, the GNU Simula 87 Compiler. # Bison was once wrong, due to an incorrect computation of the RR conflicts. # It reported 80 SR && 99 RR conflicts instead of 78/10!!! -AT_DATA([[input.y]], +AT_TEST_EXISTING_GRAMMAR([[GNU Cim Grammar]], [[%union {} %token @@ -428,7 +845,8 @@ AT_DATA([[input.y]], %left HDOT %start MAIN_MODULE -%% +]], +[[ /* GRAMATIKK FOR PROGRAM MODULES */ MAIN_MODULE : {} MODULS @@ -947,17 +1365,26 @@ ARGUMENT_LIST : EXPRESSION HPAREXPSEPARATOR ARGUMENT_LIST ; -%% -]]) +]], -# Pass plenty of options, to exercise plenty of code, even if we -# don't actually check the output. But SEGV is watching us, and -# so might do dmalloc. -AT_BISON_CHECK([[--verbose --defines input.y]], 0, [], -[[input.y: conflicts: 78 shift/reduce, 10 reduce/reduce -]]) +dnl INPUT +[[]], -AT_CHECK([[grep '^State.*conflicts:' input.output]], 0, +dnl BISON-STDERR +[AT_COND_CASE([[canonical LR]], +[[input.y: conflicts: 1876 shift/reduce, 144 reduce/reduce]], +[[input.y: conflicts: 78 shift/reduce, 10 reduce/reduce]])[ +]], + +dnl LAST-STATE +[AT_COND_CASE([[canonical LR]], [[10425]], [[442]])], + +dnl LALR1-DIFF not used for canonical LR(1) because the diff is huge. +[], + +dnl OTHER-CHECKS +[AT_COND_CASE([[canonical LR]], [[]], +[AT_CHECK([[grep '^State.*conflicts:' input.output]], [[0]], [[State 64 conflicts: 14 shift/reduce State 164 conflicts: 1 shift/reduce State 201 conflicts: 33 shift/reduce, 4 reduce/reduce @@ -967,22 +1394,19 @@ State 335 conflicts: 9 shift/reduce, 2 reduce/reduce State 356 conflicts: 1 shift/reduce State 360 conflicts: 9 shift/reduce, 2 reduce/reduce State 427 conflicts: 9 shift/reduce, 2 reduce/reduce -]]) +]])])]) -AT_CLEANUP - -## ----------------- ## -## GNU pic Grammar. ## -## ----------------- ## - -AT_SETUP([GNU pic Grammar]) +## -------------------------------- ## +## GNU pic (Groff 1.18.1) Grammar. ## +## -------------------------------- ## # GNU pic, part of groff. # Bison once reported shift/reduce conflicts that it shouldn't have. -AT_DATA([[input.y]], -[[%union {} +AT_TEST_EXISTING_GRAMMAR([[GNU pic (Groff 1.18.1) Grammar]], +[[%error-verbose +%union {} %token LABEL %token VARIABLE @@ -1148,9 +1572,8 @@ works */ %left '*' '/' '%' %right '!' %right '^' - -%% - +]], +[[ top: optional_separator | element_list @@ -1513,13 +1936,1189 @@ expr: | expr OROR expr | '!' expr ; -]]) +]], -# Pass plenty of options, to exercise plenty of code, even if we -# don't actually check the output. But SEGV is watching us, and -# so might do dmalloc. -AT_BISON_CHECK([[--verbose --defines input.y]], 0, [], -[[input.y:453.11-48: warning: rule useless in parser due to conflicts: path: ORDINAL LAST object_type relative_path -]]) +dnl INPUT +dnl +dnl For example, in pic: +dnl +dnl .PS +dnl A: circle "A" +dnl B: A left +dnl circle "B" at B +dnl .PE +dnl +dnl Even using groff 1.19.2, the 3rd line above is a syntax error. Change +dnl "left" to "right", and it still is. However, add "upper" or "lower" before +dnl "left or "right" and it's accepted to mean ".nw", ".ne", ".sw", or ".se". +dnl (There seem to be no aliases for "north" and "south" that can stand alone +dnl without being followed by "of".) +[[VARIABLE, '=', LABEL, LEFT, DOT_X]], -AT_CLEANUP +dnl BISON-STDERR +[[input.y:471.11-48: warning: rule useless in parser due to conflicts: path: ORDINAL LAST object_type relative_path +]], + +dnl LAST-STATE +[AT_COND_CASE([[LALR]], [[422]], [[canonical LR]], [[4833]], [[427]])], + +dnl LALR1-DIFF not used for canonical LR(1) because the diff is huge. +dnl Isocore map from LALR(1) state number to new state number plus descriptions +dnl of any change in the actions resulting in a change in accepted language: +dnl - 102 -> 423: reduce -> shift on LEFT and RIGHT +dnl - 237 -> 425 +dnl - 266 -> 424 +dnl - 339 -> 426 +dnl - 383 -> 427 +[AT_COND_CASE([[LALR]], [], +[[@@ -1223,7 +1223,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -1377,7 +1377,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -1854,7 +1854,7 @@ + + text go to state 162 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -2047,7 +2047,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -2571,7 +2571,7 @@ + position_not_place go to state 99 + expr_pair go to state 191 + place go to state 101 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -2732,7 +2732,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -2875,7 +2875,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -3018,7 +3018,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -3256,7 +3256,7 @@ + + state 102 + +- 146 place: label . [$end, LABEL, VARIABLE, NUMBER, TEXT, ORDINAL, LEFT_ARROW_HEAD, RIGHT_ARROW_HEAD, DOUBLE_ARROW_HEAD, LAST, UP, DOWN, LEFT, RIGHT, HEIGHT, RADIUS, WIDTH, DIAMETER, FROM, TO, AT, WITH, BY, THEN, SOLID, DOTTED, DASHED, CHOP, SAME, INVISIBLE, LJUST, RJUST, ABOVE, BELOW, AND, HERE, DOT_X, DOT_Y, DOT_HT, DOT_WID, DOT_RAD, SIN, COS, ATAN2, LOG, EXP, SQRT, K_MAX, K_MIN, INT, RAND, SRAND, CW, CCW, THICKNESS, FILL, COLORED, OUTLINED, SHADED, ALIGNED, SPRINTF, '(', '`', ',', '>', '+', '-', '!', ';', '}', '@:>@', ')'] ++ 146 place: label . [$end, LABEL, VARIABLE, NUMBER, TEXT, ORDINAL, LEFT_ARROW_HEAD, RIGHT_ARROW_HEAD, DOUBLE_ARROW_HEAD, LAST, UP, DOWN, LEFT, RIGHT, HEIGHT, RADIUS, WIDTH, DIAMETER, FROM, TO, AT, WITH, BY, THEN, SOLID, DOTTED, DASHED, CHOP, SAME, INVISIBLE, LJUST, RJUST, ABOVE, BELOW, HERE, DOT_X, DOT_Y, DOT_HT, DOT_WID, DOT_RAD, SIN, COS, ATAN2, LOG, EXP, SQRT, K_MAX, K_MIN, INT, RAND, SRAND, CW, CCW, THICKNESS, FILL, COLORED, OUTLINED, SHADED, ALIGNED, SPRINTF, '(', '`', '+', '-', '!', ';', '}', '@:>@'] + 147 | label . corner + 153 label: label . '.' LABEL + 180 corner: . DOT_N +@@ -3645,7 +3645,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -3804,7 +3804,7 @@ + text_expr go to state 239 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -4481,7 +4481,7 @@ + $default reduce using rule 89 (object_spec) + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -4673,7 +4673,7 @@ + $default reduce using rule 91 (object_spec) + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -4867,7 +4867,7 @@ + $default reduce using rule 95 (object_spec) + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -5065,7 +5065,7 @@ + $default reduce using rule 93 (object_spec) + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -5260,7 +5260,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -5403,7 +5403,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -5546,7 +5546,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -5689,7 +5689,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -6475,7 +6475,7 @@ + + expr_pair go to state 280 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -6633,7 +6633,7 @@ + $default reduce using rule 105 (object_spec) + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -6825,7 +6825,7 @@ + $default reduce using rule 107 (object_spec) + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -7017,7 +7017,7 @@ + $default reduce using rule 114 (object_spec) + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -7264,7 +7264,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -7408,7 +7408,7 @@ + $default reduce using rule 109 (object_spec) + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -7819,12 +7819,12 @@ + position_not_place go to state 296 + expr_pair go to state 100 + place go to state 297 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 + corner go to state 106 +- expr go to state 266 ++ expr go to state 424 + + + state 165 +@@ -7987,7 +7987,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -8172,7 +8172,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -8333,7 +8333,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -8494,7 +8494,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -8655,7 +8655,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -8816,7 +8816,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -8977,7 +8977,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -9138,7 +9138,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -9299,7 +9299,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -9460,7 +9460,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -9623,7 +9623,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -9784,7 +9784,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -9921,7 +9921,7 @@ + + $default reduce using rule 47 (any_expr) + +- between go to state 237 ++ between go to state 425 + + + state 193 +@@ -10152,7 +10152,7 @@ + + expr_pair go to state 317 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -10298,7 +10298,7 @@ + + expr_pair go to state 318 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -10622,7 +10622,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -10765,7 +10765,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -10908,7 +10908,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -11051,7 +11051,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -11194,7 +11194,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -11337,7 +11337,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -11480,7 +11480,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -11637,7 +11637,7 @@ + position_not_place go to state 99 + expr_pair go to state 100 + place go to state 101 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -11780,7 +11780,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -11923,7 +11923,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -12066,7 +12066,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -12209,7 +12209,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -12352,7 +12352,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -12495,7 +12495,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -12638,7 +12638,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -12794,12 +12794,12 @@ + position_not_place go to state 99 + expr_pair go to state 100 + place go to state 101 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 + corner go to state 106 +- expr go to state 266 ++ expr go to state 424 + + + state 238 +@@ -12937,7 +12937,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -13160,7 +13160,7 @@ + text_expr go to state 342 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -13319,7 +13319,7 @@ + text_expr go to state 344 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -13502,7 +13502,7 @@ + text_expr go to state 348 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -13661,7 +13661,7 @@ + text_expr go to state 350 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -13804,7 +13804,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -14747,7 +14747,7 @@ + position_not_place go to state 99 + expr_pair go to state 191 + place go to state 101 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -15074,7 +15074,7 @@ + text go to state 113 + expr_pair go to state 365 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -15693,12 +15693,12 @@ + position_not_place go to state 99 + expr_pair go to state 100 + place go to state 101 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 + corner go to state 106 +- expr go to state 266 ++ expr go to state 424 + + + state 315 +@@ -16124,7 +16124,7 @@ + + $default reduce using rule 239 (expr) + +- between go to state 237 ++ between go to state 425 + + Conflict between rule 239 and token OF resolved as shift ('<' < OF). + Conflict between rule 239 and token BETWEEN resolved as shift ('<' < BETWEEN). +@@ -17234,7 +17234,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -17416,7 +17416,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -17577,7 +17577,7 @@ + text_expr go to state 112 + text go to state 113 + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -17772,12 +17772,12 @@ + position_not_place go to state 99 + expr_pair go to state 100 + place go to state 101 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 + corner go to state 106 +- expr go to state 266 ++ expr go to state 424 + + + state 383 +@@ -18071,7 +18071,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -18221,7 +18221,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -18830,7 +18830,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -18987,7 +18987,7 @@ + '!' shift, and go to state 94 + + place go to state 114 +- label go to state 102 ++ label go to state 423 + ordinal go to state 103 + optional_ordinal_last go to state 104 + nth_primitive go to state 105 +@@ -19089,3 +19089,440 @@ + 29 placeless_element: FOR VARIABLE '=' expr TO expr optional_by DO $@6 DELIMITED . + + $default reduce using rule 29 (placeless_element) ++ ++ ++state 423 ++ ++ 146 place: label . [$end, AND, DOT_X, DOT_Y, DOT_HT, DOT_WID, DOT_RAD, ',', '>', '+', '-', ';', '}', '@:>@', ')'] ++ 147 | label . corner ++ 153 label: label . '.' LABEL ++ 180 corner: . DOT_N ++ 181 | . DOT_E ++ 182 | . DOT_W ++ 183 | . DOT_S ++ 184 | . DOT_NE ++ 185 | . DOT_SE ++ 186 | . DOT_NW ++ 187 | . DOT_SW ++ 188 | . DOT_C ++ 189 | . DOT_START ++ 190 | . DOT_END ++ 191 | . TOP ++ 192 | . BOTTOM ++ 193 | . LEFT ++ 194 | . RIGHT ++ 195 | . UPPER LEFT ++ 196 | . LOWER LEFT ++ 197 | . UPPER RIGHT ++ 198 | . LOWER RIGHT ++ 199 | . LEFT_CORNER ++ 200 | . RIGHT_CORNER ++ 201 | . UPPER LEFT_CORNER ++ 202 | . LOWER LEFT_CORNER ++ 203 | . UPPER RIGHT_CORNER ++ 204 | . LOWER RIGHT_CORNER ++ 205 | . NORTH ++ 206 | . SOUTH ++ 207 | . EAST ++ 208 | . WEST ++ 209 | . CENTER ++ 210 | . START ++ 211 | . END ++ ++ LEFT shift, and go to state 53 ++ RIGHT shift, and go to state 54 ++ DOT_N shift, and go to state 56 ++ DOT_E shift, and go to state 57 ++ DOT_W shift, and go to state 58 ++ DOT_S shift, and go to state 59 ++ DOT_NE shift, and go to state 60 ++ DOT_SE shift, and go to state 61 ++ DOT_NW shift, and go to state 62 ++ DOT_SW shift, and go to state 63 ++ DOT_C shift, and go to state 64 ++ DOT_START shift, and go to state 65 ++ DOT_END shift, and go to state 66 ++ TOP shift, and go to state 78 ++ BOTTOM shift, and go to state 79 ++ UPPER shift, and go to state 80 ++ LOWER shift, and go to state 81 ++ LEFT_CORNER shift, and go to state 82 ++ RIGHT_CORNER shift, and go to state 83 ++ NORTH shift, and go to state 84 ++ SOUTH shift, and go to state 85 ++ EAST shift, and go to state 86 ++ WEST shift, and go to state 87 ++ CENTER shift, and go to state 88 ++ END shift, and go to state 89 ++ START shift, and go to state 90 ++ '.' shift, and go to state 204 ++ ++ $default reduce using rule 146 (place) ++ ++ corner go to state 205 ++ ++ ++state 424 ++ ++ 140 position_not_place: expr . between position AND position ++ 141 | expr . '<' position ',' position '>' ++ 142 between: . BETWEEN ++ 143 | . OF THE WAY BETWEEN ++ 144 expr_pair: expr . ',' expr ++ 219 expr: expr . '+' expr ++ 220 | expr . '-' expr ++ 221 | expr . '*' expr ++ 222 | expr . '/' expr ++ 223 | expr . '%' expr ++ 224 | expr . '^' expr ++ 239 | expr . '<' expr ++ 240 | expr . LESSEQUAL expr ++ 241 | expr . '>' expr ++ 242 | expr . GREATEREQUAL expr ++ 243 | expr . EQUALEQUAL expr ++ 244 | expr . NOTEQUAL expr ++ 245 | expr . ANDAND expr ++ 246 | expr . OROR expr ++ ++ OF shift, and go to state 220 ++ BETWEEN shift, and go to state 221 ++ ANDAND shift, and go to state 222 ++ OROR shift, and go to state 223 ++ NOTEQUAL shift, and go to state 224 ++ EQUALEQUAL shift, and go to state 225 ++ LESSEQUAL shift, and go to state 226 ++ GREATEREQUAL shift, and go to state 227 ++ ',' shift, and go to state 228 ++ '<' shift, and go to state 229 ++ '>' shift, and go to state 230 ++ '+' shift, and go to state 231 ++ '-' shift, and go to state 232 ++ '*' shift, and go to state 233 ++ '/' shift, and go to state 234 ++ '%' shift, and go to state 235 ++ '^' shift, and go to state 236 ++ ++ between go to state 425 ++ ++ ++state 425 ++ ++ 134 position: . position_not_place ++ 135 | . place ++ 136 position_not_place: . expr_pair ++ 137 | . position '+' expr_pair ++ 138 | . position '-' expr_pair ++ 139 | . '(' position ',' position ')' ++ 140 | . expr between position AND position ++ 140 | expr between . position AND position ++ 141 | . expr '<' position ',' position '>' ++ 144 expr_pair: . expr ',' expr ++ 145 | . '(' expr_pair ')' ++ 146 place: . label ++ 147 | . label corner ++ 148 | . corner label ++ 149 | . corner OF label ++ 150 | . HERE ++ 151 label: . LABEL ++ 152 | . nth_primitive ++ 153 | . label '.' LABEL ++ 154 ordinal: . ORDINAL ++ 155 | . '`' any_expr TH ++ 156 optional_ordinal_last: . LAST ++ 157 | . ordinal LAST ++ 158 nth_primitive: . ordinal object_type ++ 159 | . optional_ordinal_last object_type ++ 180 corner: . DOT_N ++ 181 | . DOT_E ++ 182 | . DOT_W ++ 183 | . DOT_S ++ 184 | . DOT_NE ++ 185 | . DOT_SE ++ 186 | . DOT_NW ++ 187 | . DOT_SW ++ 188 | . DOT_C ++ 189 | . DOT_START ++ 190 | . DOT_END ++ 191 | . TOP ++ 192 | . BOTTOM ++ 193 | . LEFT ++ 194 | . RIGHT ++ 195 | . UPPER LEFT ++ 196 | . LOWER LEFT ++ 197 | . UPPER RIGHT ++ 198 | . LOWER RIGHT ++ 199 | . LEFT_CORNER ++ 200 | . RIGHT_CORNER ++ 201 | . UPPER LEFT_CORNER ++ 202 | . LOWER LEFT_CORNER ++ 203 | . UPPER RIGHT_CORNER ++ 204 | . LOWER RIGHT_CORNER ++ 205 | . NORTH ++ 206 | . SOUTH ++ 207 | . EAST ++ 208 | . WEST ++ 209 | . CENTER ++ 210 | . START ++ 211 | . END ++ 212 expr: . VARIABLE ++ 213 | . NUMBER ++ 214 | . place DOT_X ++ 215 | . place DOT_Y ++ 216 | . place DOT_HT ++ 217 | . place DOT_WID ++ 218 | . place DOT_RAD ++ 219 | . expr '+' expr ++ 220 | . expr '-' expr ++ 221 | . expr '*' expr ++ 222 | . expr '/' expr ++ 223 | . expr '%' expr ++ 224 | . expr '^' expr ++ 225 | . '-' expr ++ 226 | . '(' any_expr ')' ++ 227 | . SIN '(' any_expr ')' ++ 228 | . COS '(' any_expr ')' ++ 229 | . ATAN2 '(' any_expr ',' any_expr ')' ++ 230 | . LOG '(' any_expr ')' ++ 231 | . EXP '(' any_expr ')' ++ 232 | . SQRT '(' any_expr ')' ++ 233 | . K_MAX '(' any_expr ',' any_expr ')' ++ 234 | . K_MIN '(' any_expr ',' any_expr ')' ++ 235 | . INT '(' any_expr ')' ++ 236 | . RAND '(' any_expr ')' ++ 237 | . RAND '(' ')' ++ 238 | . SRAND '(' any_expr ')' ++ 239 | . expr '<' expr ++ 240 | . expr LESSEQUAL expr ++ 241 | . expr '>' expr ++ 242 | . expr GREATEREQUAL expr ++ 243 | . expr EQUALEQUAL expr ++ 244 | . expr NOTEQUAL expr ++ 245 | . expr ANDAND expr ++ 246 | . expr OROR expr ++ 247 | . '!' expr ++ ++ LABEL shift, and go to state 48 ++ VARIABLE shift, and go to state 49 ++ NUMBER shift, and go to state 50 ++ ORDINAL shift, and go to state 51 ++ LAST shift, and go to state 52 ++ LEFT shift, and go to state 53 ++ RIGHT shift, and go to state 54 ++ HERE shift, and go to state 55 ++ DOT_N shift, and go to state 56 ++ DOT_E shift, and go to state 57 ++ DOT_W shift, and go to state 58 ++ DOT_S shift, and go to state 59 ++ DOT_NE shift, and go to state 60 ++ DOT_SE shift, and go to state 61 ++ DOT_NW shift, and go to state 62 ++ DOT_SW shift, and go to state 63 ++ DOT_C shift, and go to state 64 ++ DOT_START shift, and go to state 65 ++ DOT_END shift, and go to state 66 ++ SIN shift, and go to state 67 ++ COS shift, and go to state 68 ++ ATAN2 shift, and go to state 69 ++ LOG shift, and go to state 70 ++ EXP shift, and go to state 71 ++ SQRT shift, and go to state 72 ++ K_MAX shift, and go to state 73 ++ K_MIN shift, and go to state 74 ++ INT shift, and go to state 75 ++ RAND shift, and go to state 76 ++ SRAND shift, and go to state 77 ++ TOP shift, and go to state 78 ++ BOTTOM shift, and go to state 79 ++ UPPER shift, and go to state 80 ++ LOWER shift, and go to state 81 ++ LEFT_CORNER shift, and go to state 82 ++ RIGHT_CORNER shift, and go to state 83 ++ NORTH shift, and go to state 84 ++ SOUTH shift, and go to state 85 ++ EAST shift, and go to state 86 ++ WEST shift, and go to state 87 ++ CENTER shift, and go to state 88 ++ END shift, and go to state 89 ++ START shift, and go to state 90 ++ '(' shift, and go to state 91 ++ '`' shift, and go to state 92 ++ '-' shift, and go to state 93 ++ '!' shift, and go to state 94 ++ ++ position go to state 426 ++ position_not_place go to state 99 ++ expr_pair go to state 100 ++ place go to state 101 ++ label go to state 423 ++ ordinal go to state 103 ++ optional_ordinal_last go to state 104 ++ nth_primitive go to state 105 ++ corner go to state 106 ++ expr go to state 424 ++ ++ ++state 426 ++ ++ 137 position_not_place: position . '+' expr_pair ++ 138 | position . '-' expr_pair ++ 140 | expr between position . AND position ++ ++ AND shift, and go to state 427 ++ '+' shift, and go to state 197 ++ '-' shift, and go to state 198 ++ ++ ++state 427 ++ ++ 134 position: . position_not_place ++ 135 | . place ++ 136 position_not_place: . expr_pair ++ 137 | . position '+' expr_pair ++ 138 | . position '-' expr_pair ++ 139 | . '(' position ',' position ')' ++ 140 | . expr between position AND position ++ 140 | expr between position AND . position ++ 141 | . expr '<' position ',' position '>' ++ 144 expr_pair: . expr ',' expr ++ 145 | . '(' expr_pair ')' ++ 146 place: . label ++ 147 | . label corner ++ 148 | . corner label ++ 149 | . corner OF label ++ 150 | . HERE ++ 151 label: . LABEL ++ 152 | . nth_primitive ++ 153 | . label '.' LABEL ++ 154 ordinal: . ORDINAL ++ 155 | . '`' any_expr TH ++ 156 optional_ordinal_last: . LAST ++ 157 | . ordinal LAST ++ 158 nth_primitive: . ordinal object_type ++ 159 | . optional_ordinal_last object_type ++ 180 corner: . DOT_N ++ 181 | . DOT_E ++ 182 | . DOT_W ++ 183 | . DOT_S ++ 184 | . DOT_NE ++ 185 | . DOT_SE ++ 186 | . DOT_NW ++ 187 | . DOT_SW ++ 188 | . DOT_C ++ 189 | . DOT_START ++ 190 | . DOT_END ++ 191 | . TOP ++ 192 | . BOTTOM ++ 193 | . LEFT ++ 194 | . RIGHT ++ 195 | . UPPER LEFT ++ 196 | . LOWER LEFT ++ 197 | . UPPER RIGHT ++ 198 | . LOWER RIGHT ++ 199 | . LEFT_CORNER ++ 200 | . RIGHT_CORNER ++ 201 | . UPPER LEFT_CORNER ++ 202 | . LOWER LEFT_CORNER ++ 203 | . UPPER RIGHT_CORNER ++ 204 | . LOWER RIGHT_CORNER ++ 205 | . NORTH ++ 206 | . SOUTH ++ 207 | . EAST ++ 208 | . WEST ++ 209 | . CENTER ++ 210 | . START ++ 211 | . END ++ 212 expr: . VARIABLE ++ 213 | . NUMBER ++ 214 | . place DOT_X ++ 215 | . place DOT_Y ++ 216 | . place DOT_HT ++ 217 | . place DOT_WID ++ 218 | . place DOT_RAD ++ 219 | . expr '+' expr ++ 220 | . expr '-' expr ++ 221 | . expr '*' expr ++ 222 | . expr '/' expr ++ 223 | . expr '%' expr ++ 224 | . expr '^' expr ++ 225 | . '-' expr ++ 226 | . '(' any_expr ')' ++ 227 | . SIN '(' any_expr ')' ++ 228 | . COS '(' any_expr ')' ++ 229 | . ATAN2 '(' any_expr ',' any_expr ')' ++ 230 | . LOG '(' any_expr ')' ++ 231 | . EXP '(' any_expr ')' ++ 232 | . SQRT '(' any_expr ')' ++ 233 | . K_MAX '(' any_expr ',' any_expr ')' ++ 234 | . K_MIN '(' any_expr ',' any_expr ')' ++ 235 | . INT '(' any_expr ')' ++ 236 | . RAND '(' any_expr ')' ++ 237 | . RAND '(' ')' ++ 238 | . SRAND '(' any_expr ')' ++ 239 | . expr '<' expr ++ 240 | . expr LESSEQUAL expr ++ 241 | . expr '>' expr ++ 242 | . expr GREATEREQUAL expr ++ 243 | . expr EQUALEQUAL expr ++ 244 | . expr NOTEQUAL expr ++ 245 | . expr ANDAND expr ++ 246 | . expr OROR expr ++ 247 | . '!' expr ++ ++ LABEL shift, and go to state 48 ++ VARIABLE shift, and go to state 49 ++ NUMBER shift, and go to state 50 ++ ORDINAL shift, and go to state 51 ++ LAST shift, and go to state 52 ++ LEFT shift, and go to state 53 ++ RIGHT shift, and go to state 54 ++ HERE shift, and go to state 55 ++ DOT_N shift, and go to state 56 ++ DOT_E shift, and go to state 57 ++ DOT_W shift, and go to state 58 ++ DOT_S shift, and go to state 59 ++ DOT_NE shift, and go to state 60 ++ DOT_SE shift, and go to state 61 ++ DOT_NW shift, and go to state 62 ++ DOT_SW shift, and go to state 63 ++ DOT_C shift, and go to state 64 ++ DOT_START shift, and go to state 65 ++ DOT_END shift, and go to state 66 ++ SIN shift, and go to state 67 ++ COS shift, and go to state 68 ++ ATAN2 shift, and go to state 69 ++ LOG shift, and go to state 70 ++ EXP shift, and go to state 71 ++ SQRT shift, and go to state 72 ++ K_MAX shift, and go to state 73 ++ K_MIN shift, and go to state 74 ++ INT shift, and go to state 75 ++ RAND shift, and go to state 76 ++ SRAND shift, and go to state 77 ++ TOP shift, and go to state 78 ++ BOTTOM shift, and go to state 79 ++ UPPER shift, and go to state 80 ++ LOWER shift, and go to state 81 ++ LEFT_CORNER shift, and go to state 82 ++ RIGHT_CORNER shift, and go to state 83 ++ NORTH shift, and go to state 84 ++ SOUTH shift, and go to state 85 ++ EAST shift, and go to state 86 ++ WEST shift, and go to state 87 ++ CENTER shift, and go to state 88 ++ END shift, and go to state 89 ++ START shift, and go to state 90 ++ '(' shift, and go to state 91 ++ '`' shift, and go to state 92 ++ '-' shift, and go to state 93 ++ '!' shift, and go to state 94 ++ ++ position go to state 402 ++ position_not_place go to state 99 ++ expr_pair go to state 100 ++ place go to state 101 ++ label go to state 423 ++ ordinal go to state 103 ++ optional_ordinal_last go to state 104 ++ nth_primitive go to state 105 ++ corner go to state 106 ++ expr go to state 424 +]])], + +dnl OTHER-CHECKS +[], + +dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR +[AT_COND_CASE([[LALR]], [[1]], [[0]])], +[], +[AT_COND_CASE([[LALR]], +[[syntax error, unexpected LEFT +]])]) diff --git a/tests/reduce.at b/tests/reduce.at index 058d7c0d..6642f654 100644 --- a/tests/reduce.at +++ b/tests/reduce.at @@ -359,6 +359,1089 @@ AT_CLEANUP +## ----------------- ## +## %define lr.type. ## +## ----------------- ## + +# AT_TEST_LR_TYPE(DESCRIPTION, +# DECLS, GRAMMAR, INPUT, +# BISON-STDERR, TABLES, +# [OTHER-CHECKS], +# [PARSER-EXIT-VALUE], +# [PARSER-STDOUT], [PARSER-STDERR]) +# ------------------------------------------------- +m4_define([AT_TEST_LR_TYPE], +[ +AT_TEST_TABLES_AND_PARSE([[no %define lr.type: ]$1], + [[LALR]], [[]], + [$2], m4_shiftn(2, $@)) +AT_TEST_TABLES_AND_PARSE([[%define lr.type "LALR": ]$1], + [[LALR]], [[]], + [[%define lr.type "LALR" +]$2], + m4_shiftn(2, $@)) +AT_TEST_TABLES_AND_PARSE([[%define lr.type "IELR": ]$1], + [[IELR]], [[]], + [[%define lr.type "IELR" +]$2], + m4_shiftn(2, $@)) +AT_TEST_TABLES_AND_PARSE([[%define lr.type "canonical LR": ]$1], + [[canonical LR]], [[]], + [[%define lr.type "canonical LR" +]$2], + m4_shiftn(2, $@)) +]) + +AT_TEST_LR_TYPE([[Single State Split]], +[[%left 'a' +// Conflict resolution renders state 12 unreachable for canonical LR(1). We +// keep it so that the paser table diff is easier to code. +%define lr.keep_unreachable_states]], +[[ +S: 'a' A 'a' /* rule 1 */ + | 'b' A 'b' /* rule 2 */ + | 'c' c /* rule 3 */ + ; + +/* A conflict should appear after the first 'a' in rules 4 and 5 but only after + having shifted the first 'a' in rule 1. However, when LALR(1) merging is + chosen, the state containing that conflict is reused after having seen the + first 'b' in rule 2 and then the first 'a' in rules 4 and 5. In both cases, + because of the merged state, if the next token is an 'a', the %left forces a + reduction action with rule 5. In the latter case, only a shift is actually + grammatically correct. Thus, the parser would report a syntax error for the + grammatically correct sentence "baab" because it would encounter a syntax + error after that incorrect reduction. + + Despite not being LALR(1), Menhir version 20070322 suffers from this problem + as well. It uses David Pager's weak compatibility test for merging states. + Bison and Menhir accept non-LR(1) grammars with conflict resolution. Pager + designed his algorithm only for LR(1) grammars. */ +A: 'a' 'a' /* rule 4 */ + | 'a' /* rule 5 */ + ; + +/* Rule 3, rule 6, and rule 7 ensure that Bison does not report rule 4 as + useless after conflict resolution. This proves that, even though LALR(1) + generates incorrect parser tables sometimes, Bison will not necessarily + produce any warning to help the user realize it. */ +c: 'a' 'b' /* rule 6 */ + | A /* rule 7 */ + ; +]], + +dnl INPUT +[['b', 'a', 'a', 'b']], + +dnl BISON-STDERR +[], + +dnl TABLES +[[state 0 + + 0 $accept: . S $end + 1 S: . 'a' A 'a' + 2 | . 'b' A 'b' + 3 | . 'c' c + + 'a' shift, and go to state 1 + 'b' shift, and go to state 2 + 'c' shift, and go to state 3 + + S go to state 4 + + +state 1 + + 1 S: 'a' . A 'a' + 4 A: . 'a' 'a' + 5 | . 'a' + + 'a' shift, and go to state 5 + + A go to state 6 + + +state 2 + + 2 S: 'b' . A 'b' + 4 A: . 'a' 'a' + 5 | . 'a' + + 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[16]])[ + + A go to state 7 + + +state 3 + + 3 S: 'c' . c + 4 A: . 'a' 'a' + 5 | . 'a' + 6 c: . 'a' 'b' + 7 | . A + + 'a' shift, and go to state 8 + + A go to state 9 + c go to state 10 + + +state 4 + + 0 $accept: S . $end + + $end shift, and go to state 11 + + +state 5 + + 4 A: 'a' . 'a' + 5 | 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[ + + ]AT_COND_CASE([[canonical LR]], [['a']], + [[$default]])[ reduce using rule 5 (A) + + Conflict between rule 5 and token 'a' resolved as reduce (%left 'a'). + + +state 6 + + 1 S: 'a' A . 'a' + + 'a' shift, and go to state 13 + + +state 7 + + 2 S: 'b' A . 'b' + + 'b' shift, and go to state 14 + + +state 8 + + 4 A: 'a' . 'a' + 5 | 'a' . [$end] + 6 c: 'a' . 'b' + + 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[17]], + [[12]])[ + 'b' shift, and go to state 15 + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 5 (A) + + +state 9 + + 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 7 (c) + + +state 10 + + 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 3 (S) + + +state 11 + + 0 $accept: S $end . + + $default accept + + +state 12 + + 4 A: 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[ + + ]AT_COND_CASE([[canonical LR]], [['a']], + [[$default]])[ reduce using rule 4 (A) + + +state 13 + + 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 1 (S) + + +state 14 + + 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 2 (S) + + +state 15 + + 6 c: 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]], + [[]], [[ + + +state 16 + + 4 A: 'a' . 'a' + 5 | 'a' . ['b'] + + 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[18]], + [[12]])[ + + ]AT_COND_CASE([[canonical LR]], [['b']], + [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[ + + +state 17 + + 4 A: 'a' 'a' . [$end] + + $end reduce using rule 4 (A) + + +state 18 + + 4 A: 'a' 'a' . ['b'] + + 'b' reduce using rule 4 (A)]])])[ +]], + +dnl OTHER-CHECKS +[], + +dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR +[AT_COND_CASE([[LALR]], [[1]], [[0]])], +[], +[AT_COND_CASE([[LALR]], +[[syntax error +]])]) + +AT_TEST_LR_TYPE([[Lane Split]], +[[%left 'a' +// Conflict resolution renders state 16 unreachable for canonical LR(1). We +// keep it so that the paser table diff is easier to code. +%define lr.keep_unreachable_states]], +[[ +/* Similar to the last test case set but two states must be split. */ +S: 'a' A 'a' /* rule 1 */ + | 'b' A 'b' /* rule 2 */ + | 'c' c /* rule 3 */ + ; + +A: 'a' 'a' 'a' /* rule 4 */ + | 'a' 'a' /* rule 5 */ + ; + +c: 'a' 'a' 'b' /* rule 6 */ + | A /* rule 7 */ + ; +]], + +dnl INPUT +[['b', 'a', 'a', 'a', 'b']], + +dnl BISON-STDERR +[], + +dnl TABLES +[[state 0 + + 0 $accept: . S $end + 1 S: . 'a' A 'a' + 2 | . 'b' A 'b' + 3 | . 'c' c + + 'a' shift, and go to state 1 + 'b' shift, and go to state 2 + 'c' shift, and go to state 3 + + S go to state 4 + + +state 1 + + 1 S: 'a' . A 'a' + 4 A: . 'a' 'a' 'a' + 5 | . 'a' 'a' + + 'a' shift, and go to state 5 + + A go to state 6 + + +state 2 + + 2 S: 'b' . A 'b' + 4 A: . 'a' 'a' 'a' + 5 | . 'a' 'a' + + 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[18]])[ + + A go to state 7 + + +state 3 + + 3 S: 'c' . c + 4 A: . 'a' 'a' 'a' + 5 | . 'a' 'a' + 6 c: . 'a' 'a' 'b' + 7 | . A + + 'a' shift, and go to state 8 + + A go to state 9 + c go to state 10 + + +state 4 + + 0 $accept: S . $end + + $end shift, and go to state 11 + + +state 5 + + 4 A: 'a' . 'a' 'a' + 5 | 'a' . 'a' + + 'a' shift, and go to state 12 + + +state 6 + + 1 S: 'a' A . 'a' + + 'a' shift, and go to state 13 + + +state 7 + + 2 S: 'b' A . 'b' + + 'b' shift, and go to state 14 + + +state 8 + + 4 A: 'a' . 'a' 'a' + 5 | 'a' . 'a' + 6 c: 'a' . 'a' 'b' + + 'a' shift, and go to state 15 + + +state 9 + + 7 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 7 (c) + + +state 10 + + 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 3 (S) + + +state 11 + + 0 $accept: S $end . + + $default accept + + +state 12 + + 4 A: 'a' 'a' . 'a' + 5 | 'a' 'a' . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[ + + ]AT_COND_CASE([[canonical LR]], [['a']], + [[$default]])[ reduce using rule 5 (A) + + Conflict between rule 5 and token 'a' resolved as reduce (%left 'a'). + + +state 13 + + 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 1 (S) + + +state 14 + + 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 2 (S) + + +state 15 + + 4 A: 'a' 'a' . 'a' + 5 | 'a' 'a' . [$end] + 6 c: 'a' 'a' . 'b' + + 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[19]], + [[16]])[ + 'b' shift, and go to state 17 + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 5 (A) + + +state 16 + + 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[ + + ]AT_COND_CASE([[canonical LR]], [['a']], + [[$default]])[ reduce using rule 4 (A) + + +state 17 + + 6 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 6 (c)]AT_COND_CASE([[LALR]], + [[]], [[ + + +state 18 + + 4 A: 'a' . 'a' 'a' + 5 | 'a' . 'a' + + 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]], + [[19]])[ + + +state 19]AT_COND_CASE([[canonical LR]], [[ + + 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 4 (A) + + +state 20]])[ + + 4 A: 'a' 'a' . 'a' + 5 | 'a' 'a' . ['b'] + + 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]], + [[16]])[ + + ]AT_COND_CASE([[canonical LR]], [['b']], + [[$default]])[ reduce using rule 5 (A)]AT_COND_CASE([[canonical LR]], [[ + + +state 21 + + 4 A: 'a' 'a' 'a' .]AT_COND_CASE([[canonical LR]], [[ ['b']]])[ + + ]AT_COND_CASE([[canonical LR]], [['b']], + [[$default]])[ reduce using rule 4 (A)]])])[ +]], + +dnl OTHER-CHECKS +[], + +dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR +[AT_COND_CASE([[LALR]], [[1]], [[0]])], +[], +[AT_COND_CASE([[LALR]], +[[syntax error +]])]) + +AT_TEST_LR_TYPE([[Complex Lane Split]], +[[%left 'a' +// Conflict resolution renders state 16 unreachable for canonical LR(1). We +// keep it so that the paser table diff is easier to code. +%define lr.keep_unreachable_states]], +[[ +/* Similar to the last test case set but forseeing the S/R conflict from the + first state that must be split is becoming difficult. Imagine if B were + even more complex. Imagine if A had other RHS's ending in other + nonterminals. */ +S: 'a' A 'a' + | 'b' A 'b' + | 'c' c + ; +A: 'a' 'a' B + ; +B: 'a' + | %prec 'a' + ; +c: 'a' 'a' 'b' + | A + ; +]], + +dnl INPUT +[['b', 'a', 'a', 'a', 'b']], + +dnl BISON-STDERR +[], + +dnl TABLES +[[state 0 + + 0 $accept: . S $end + 1 S: . 'a' A 'a' + 2 | . 'b' A 'b' + 3 | . 'c' c + + 'a' shift, and go to state 1 + 'b' shift, and go to state 2 + 'c' shift, and go to state 3 + + S go to state 4 + + +state 1 + + 1 S: 'a' . A 'a' + 4 A: . 'a' 'a' B + + 'a' shift, and go to state 5 + + A go to state 6 + + +state 2 + + 2 S: 'b' . A 'b' + 4 A: . 'a' 'a' B + + 'a' shift, and go to state ]AT_COND_CASE([[LALR]], [[5]], [[19]])[ + + A go to state 7 + + +state 3 + + 3 S: 'c' . c + 4 A: . 'a' 'a' B + 7 c: . 'a' 'a' 'b' + 8 | . A + + 'a' shift, and go to state 8 + + A go to state 9 + c go to state 10 + + +state 4 + + 0 $accept: S . $end + + $end shift, and go to state 11 + + +state 5 + + 4 A: 'a' . 'a' B + + 'a' shift, and go to state 12 + + +state 6 + + 1 S: 'a' A . 'a' + + 'a' shift, and go to state 13 + + +state 7 + + 2 S: 'b' A . 'b' + + 'b' shift, and go to state 14 + + +state 8 + + 4 A: 'a' . 'a' B + 7 c: 'a' . 'a' 'b' + + 'a' shift, and go to state 15 + + +state 9 + + 8 c: A .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 8 (c) + + +state 10 + + 3 S: 'c' c .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 3 (S) + + +state 11 + + 0 $accept: S $end . + + $default accept + + +state 12 + + 4 A: 'a' 'a' . B + 5 B: . 'a' + 6 | . ]AT_COND_CASE([[LALR]], [[['a', 'b']]], [[['a']]])[ + + ]AT_COND_CASE([[canonical LR]], [['a']], + [[$default]])[ reduce using rule 6 (B) + + B go to state 17 + + Conflict between rule 6 and token 'a' resolved as reduce (%left 'a'). + + +state 13 + + 1 S: 'a' A 'a' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 1 (S) + + +state 14 + + 2 S: 'b' A 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 2 (S) + + +state 15 + + 4 A: 'a' 'a' . B + 5 B: . 'a' + 6 | . [$end] + 7 c: 'a' 'a' . 'b' + + 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]], + [[16]])[ + 'b' shift, and go to state 18 + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 6 (B) + + B go to state ]AT_COND_CASE([[canonical LR]], [[21]], [[17]])[ + + +state 16 + + 5 B: 'a' .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[ + + ]AT_COND_CASE([[canonical LR]], [['a']], + [[$default]])[ reduce using rule 5 (B) + + +state 17 + + 4 A: 'a' 'a' B .]AT_COND_CASE([[canonical LR]], [[ ['a']]])[ + + ]AT_COND_CASE([[canonical LR]], [['a']], + [[$default]])[ reduce using rule 4 (A) + + +state 18 + + 7 c: 'a' 'a' 'b' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 7 (c)]AT_COND_CASE([[LALR]], [], [[ + + +state 19 + + 4 A: 'a' . 'a' B + + 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[22]], + [[20]])[ + + +state 20]AT_COND_CASE([[canonical LR]], [[ + + 5 B: 'a' . [$end] + + $end reduce using rule 5 (B) + + +state 21 + + 4 A: 'a' 'a' B . [$end] + + $end reduce using rule 4 (A) + + +state 22]])[ + + 4 A: 'a' 'a' . B + 5 B: . 'a' + 6 | . ['b'] + + 'a' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[23]], + [[16]])[ + + ]AT_COND_CASE([[canonical LR]], [['b']], + [[$default]])[ reduce using rule 6 (B) + + B go to state ]AT_COND_CASE([[canonical LR]], [[24 + + +state 23 + + 5 B: 'a' . ['b'] + + 'b' reduce using rule 5 (B) + + +state 24 + + 4 A: 'a' 'a' B . ['b'] + + 'b' reduce using rule 4 (A)]], [[17]])])[ +]], + +dnl OTHER-CHECKS +[], + +dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR +[AT_COND_CASE([[LALR]], [[1]], [[0]])], +[], +[AT_COND_CASE([[LALR]], +[[syntax error +]])]) + +AT_TEST_LR_TYPE([[Split During Added Lookahead Propagation]], +[[%define lr.keep_unreachable_states]], +[[ +/* The partial state chart diagram below is for LALR(1). State 0 is the start + state. States are iterated for successor construction in numerical order. + Transitions are downwards. + + State 13 has a R/R conflict that cannot be predicted by Bison's LR(1) + algorithm using annotations alone. That is, when state 11's successor on + 'd' is merged with state 5 (which is originally just state 1's successor on + 'd'), state 5's successor on 'e' must then be changed because the resulting + lookaheads that propagate to it now make it incompatible with state 8's + successor on 'e'. In other words, state 13 must be split to avoid the + conflict. + + 0 + / | \ + a / c| \ b + 1 3 2 + | | | + d| |c | d + | 11 | + | | | + \ /d | + 5 8 + \ | + e \ / e + 13 + R/R + + This grammar is designed carefully to make sure that, despite Bison's LR(1) + algorithm's bread-first iteration of transitions to reconstruct states, + state 11's successors are constructed after state 5's and state 8's. + Otherwise (for example, if you remove the first 'c' in each of rules 6 and + 7), state 5's successor on 'e' would never be merged with state 8's, so the + split of the resulting state 13 would never need to be performed. */ +S: 'a' A 'f' + | 'a' B + | 'b' A 'f' + | 'b' B 'g' + | 'b' 'd' + | 'c' 'c' A 'g' + | 'c' 'c' B + ; +A: 'd' 'e' ; +B: 'd' 'e' ; +]], + +dnl INPUT +[['b', 'd', 'e', 'g']], + +dnl BISON-STDERR +[AT_COND_CASE([[LALR]], +[[input.y: conflicts: 1 reduce/reduce +]], [])], + +dnl TABLES +[[state 0 + + 0 $accept: . S $end + 1 S: . 'a' A 'f' + 2 | . 'a' B + 3 | . 'b' A 'f' + 4 | . 'b' B 'g' + 5 | . 'b' 'd' + 6 | . 'c' 'c' A 'g' + 7 | . 'c' 'c' B + + 'a' shift, and go to state 1 + 'b' shift, and go to state 2 + 'c' shift, and go to state 3 + + S go to state 4 + + +state 1 + + 1 S: 'a' . A 'f' + 2 | 'a' . B + 8 A: . 'd' 'e' + 9 B: . 'd' 'e' + + 'd' shift, and go to state 5 + + A go to state 6 + B go to state 7 + + +state 2 + + 3 S: 'b' . A 'f' + 4 | 'b' . B 'g' + 5 | 'b' . 'd' + 8 A: . 'd' 'e' + 9 B: . 'd' 'e' + + 'd' shift, and go to state 8 + + A go to state 9 + B go to state 10 + + +state 3 + + 6 S: 'c' . 'c' A 'g' + 7 | 'c' . 'c' B + + 'c' shift, and go to state 11 + + +state 4 + + 0 $accept: S . $end + + $end shift, and go to state 12 + + +state 5 + + 8 A: 'd' . 'e' + 9 B: 'd' . 'e' + + 'e' shift, and go to state ]AT_COND_CASE([[LALR]], [[13]], + [[canonical LR]], [[13]], + [[20]])[ + + +state 6 + + 1 S: 'a' A . 'f' + + 'f' shift, and go to state 14 + + +state 7 + + 2 S: 'a' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 2 (S) + + +state 8 + + 5 S: 'b' 'd' . [$end] + 8 A: 'd' . 'e' + 9 B: 'd' . 'e' + + 'e' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[20]], + [[13]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 5 (S) + + +state 9 + + 3 S: 'b' A . 'f' + + 'f' shift, and go to state 15 + + +state 10 + + 4 S: 'b' B . 'g' + + 'g' shift, and go to state 16 + + +state 11 + + 6 S: 'c' 'c' . A 'g' + 7 | 'c' 'c' . B + 8 A: . 'd' 'e' + 9 B: . 'd' 'e' + + 'd' shift, and go to state ]AT_COND_CASE([[canonical LR]], [[21]], + [[5]])[ + + A go to state 17 + B go to state 18 + + +state 12 + + 0 $accept: S $end . + + $default accept]AT_COND_CASE([[LALR]], [[ + + +state 13 + + 8 A: 'd' 'e' . ['f', 'g'] + 9 B: 'd' 'e' . [$end, 'g'] + + $end reduce using rule 9 (B) + 'g' reduce using rule 8 (A) + 'g' [reduce using rule 9 (B)] + $default reduce using rule 8 (A)]], [[ + + +state 13 + + 8 A: 'd' 'e' . ['f'] + 9 B: 'd' 'e' . ]AT_COND_CASE([[canonical LR]], [[[$end]]], [[['g']]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [['g' ]])[ reduce using rule 9 (B) + ]AT_COND_CASE([[canonical LR]], [['f' ]], + [[$default]])[ reduce using rule 8 (A)]])[ + + +state 14 + + 1 S: 'a' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 1 (S) + + +state 15 + + 3 S: 'b' A 'f' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 3 (S) + + +state 16 + + 4 S: 'b' B 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 4 (S) + + +state 17 + + 6 S: 'c' 'c' A . 'g' + + 'g' shift, and go to state 19 + + +state 18 + + 7 S: 'c' 'c' B .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 7 (S) + + +state 19 + + 6 S: 'c' 'c' A 'g' .]AT_COND_CASE([[canonical LR]], [[ [$end]]])[ + + ]AT_COND_CASE([[canonical LR]], [[$end]], + [[$default]])[ reduce using rule 6 (S)]AT_COND_CASE([[LALR]], + [[]], [[ + + +state 20]AT_COND_CASE([[canonical LR]], [[ + + 8 A: 'd' 'e' . ['f'] + 9 B: 'd' 'e' . ['g'] + + 'f' reduce using rule 8 (A) + 'g' reduce using rule 9 (B) + + +state 21 + + 8 A: 'd' . 'e' + 9 B: 'd' . 'e' + + 'e' shift, and go to state 22 + + +state 22 + + 8 A: 'd' 'e' . ['g'] + 9 B: 'd' 'e' . [$end] + + $end reduce using rule 9 (B) + 'g' reduce using rule 8 (A)]], [[ + + 8 A: 'd' 'e' . ['f', 'g'] + 9 B: 'd' 'e' . [$end] + + $end reduce using rule 9 (B) + $default reduce using rule 8 (A)]])])[ +]], + +dnl OTHER-CHECKS +[], + +dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR +[AT_COND_CASE([[LALR]], [[1]], [[0]])], +[], +[AT_COND_CASE([[LALR]], +[[syntax error +]])]) + + + ## -------------------------- ## ## %define lr.default_rules. ## ## -------------------------- ## From 34a6c2d19b85d4650b2d90f60b76d44071d167d1 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Tue, 21 Apr 2009 05:12:01 -0400 Subject: [PATCH 065/404] Document %define lr.type and lr.default_rules. * NEWS (2.5): Add an entry. * src/getargs.c (usage): Mention IELR(1) and canonical LR(1) besides just LALR(1) and GLR(1). * doc/bison.texinfo (Introduction): Likewise. (Language and Grammar): Bison is no longer limited to LALR(1) restrictions. (GLR parsing): Say deterministic or LR(1) rather than LALR(1) when trying to distinguish from GLR. Talk about LR(1) grammars rather than LALR(1) grammars. (Decl Summary): In %define api.push_pull entry, say it applies to deterministic parsers in C rather than LALR(1) parsers in C. Add lr.default_rules entry. Add lr.type entry. (Mystery Conflicts): Bison is no longer limited to LALR(1) restrictions. (Generalized LR Parsing): Same changes as for the previous GLR section. (Memory Management): Say deterministic rather than LALR(1). (Understanding): Correct some bison output. Index discussion of "accepting state". Say deterministic rather than LALR(1). (Bison Options): In --yacc entry, say deterministic rather than LALR(1). In --report, --graph, and --xml entries, just don't mention LALR(1). (C++ Parsers): Say deterministic rather than LALR(1). (Table of Symbols): Likewise in YYSTACK_USE_ALLOCA entry. (Glossary): Add Accepting State, Consistent State, Default Rule, and IELR(1) definitions. In Generalized LR (GLR) definition, make same changes as in previous GLR sections. In LALR(1) definition, say Bison uses LALR(1) by default rather than implying Bison is limited to LALR(1). (LocalWords): Add IELR. --- ChangeLog | 38 ++++++ NEWS | 29 ++++ doc/bison.texinfo | 335 +++++++++++++++++++++++++++++++++++----------- src/getargs.c | 3 +- 4 files changed, 327 insertions(+), 78 deletions(-) diff --git a/ChangeLog b/ChangeLog index d7e97f34..013cba07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,41 @@ +2009-04-21 Joel E. Denny + + Document %define lr.type and lr.default_rules. + * NEWS (2.5): Add an entry. + * src/getargs.c (usage): Mention IELR(1) and canonical LR(1) + besides just LALR(1) and GLR(1). + * doc/bison.texinfo (Introduction): Likewise. + (Language and Grammar): Bison is no longer limited to LALR(1) + restrictions. + (GLR parsing): Say deterministic or LR(1) rather than LALR(1) + when trying to distinguish from GLR. Talk about LR(1) grammars + rather than LALR(1) grammars. + (Decl Summary): In %define api.push_pull entry, say it applies + to deterministic parsers in C rather than LALR(1) parsers in C. + Add lr.default_rules entry. + Add lr.type entry. + (Mystery Conflicts): Bison is no longer limited to LALR(1) + restrictions. + (Generalized LR Parsing): Same changes as for the previous GLR + section. + (Memory Management): Say deterministic rather than LALR(1). + (Understanding): Correct some bison output. + Index discussion of "accepting state". + Say deterministic rather than LALR(1). + (Bison Options): In --yacc entry, say deterministic rather than + LALR(1). + In --report, --graph, and --xml entries, just don't mention + LALR(1). + (C++ Parsers): Say deterministic rather than LALR(1). + (Table of Symbols): Likewise in YYSTACK_USE_ALLOCA entry. + (Glossary): Add Accepting State, Consistent State, Default Rule, + and IELR(1) definitions. + In Generalized LR (GLR) definition, make same changes as in + previous GLR sections. + In LALR(1) definition, say Bison uses LALR(1) by default rather + than implying Bison is limited to LALR(1). + (LocalWords): Add IELR. + 2009-04-21 Joel E. Denny Finish implementing %define lr.type. diff --git a/NEWS b/NEWS index f57b755d..91bde870 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,35 @@ Bison News * Changes in version 2.5 (????-??-??): +** IELR(1) and Canonical LR(1) Support + + IELR(1) is a minimal LR(1) parser table generation algorithm. That + is, given any context-free grammar, IELR(1) generates parser tables + with the full language recognition power of canonical LR(1) but with + nearly the same number of parser states as LALR(1). This reduction in + parser states is often an order of magnitude. More importantly, + because canonical LR(1)'s extra parser states may contain duplicate + conflicts in the case of non-LR(1) grammars, the number of conflicts + for IELR(1) is often an order of magnitude less as well. This can + significantly reduce the complexity of developing of a grammar. + + Bison can now generate IELR(1) and canonical LR(1) parser tables in + place of its traditional LALR(1) parser tables, which remain the + default. You can specify the type of parser tables in the grammar + file with these directives: + + %define lr.type "LALR" + %define lr.type "IELR" + %define lr.type "canonical LR" + + The default rules optimization in the parser tables can also be + adjusted using `%define lr.default_rules'. See the documentation for + `%define lr.type' and `%define lr.default_rules' in the section `Bison + Declaration Summary' in the Bison manual for the details. + + These features are experimental. More user feedback will help to + stabilize them. + ** %define can now be invoked via the command line. Each of these bison command-line options diff --git a/doc/bison.texinfo b/doc/bison.texinfo index c8fa086d..ed092e2d 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -351,10 +351,12 @@ Copying This Manual @cindex introduction @dfn{Bison} is a general-purpose parser generator that converts an -annotated context-free grammar into an @acronym{LALR}(1) or -@acronym{GLR} parser for that grammar. Once you are proficient with -Bison, you can use it to develop a wide range of language parsers, from those -used in simple desk calculators to complex programming languages. +annotated context-free grammar into a deterministic or @acronym{GLR} +parser employing @acronym{LALR}(1), @acronym{IELR}(1), or canonical +@acronym{LR}(1) parser tables. +Once you are proficient with Bison, you can use it to develop a wide +range of language parsers, from those used in simple desk calculators to +complex programming languages. Bison is upward compatible with Yacc: all properly-written Yacc grammars ought to work with Bison with no change. Anyone familiar with Yacc @@ -460,26 +462,27 @@ order to specify the language Algol 60. Any grammar expressed in essentially machine-readable @acronym{BNF}. @cindex @acronym{LALR}(1) grammars +@cindex @acronym{IELR}(1) grammars @cindex @acronym{LR}(1) grammars -There are various important subclasses of context-free grammar. Although it -can handle almost all context-free grammars, Bison is optimized for what -are called @acronym{LALR}(1) grammars. -In brief, in these grammars, it must be possible to -tell how to parse any portion of an input string with just a single -token of lookahead. Strictly speaking, that is a description of an -@acronym{LR}(1) grammar, and @acronym{LALR}(1) involves additional -restrictions that are -hard to explain simply; but it is rare in actual practice to find an -@acronym{LR}(1) grammar that fails to be @acronym{LALR}(1). +There are various important subclasses of context-free grammars. +Although it can handle almost all context-free grammars, Bison is +optimized for what are called @acronym{LR}(1) grammars. +In brief, in these grammars, it must be possible to tell how to parse +any portion of an input string with just a single token of lookahead. +For historical reasons, Bison by default is limited by the additional +restrictions of @acronym{LALR}(1), which is hard to explain simply. @xref{Mystery Conflicts, ,Mysterious Reduce/Reduce Conflicts}, for more information on this. +To escape these additional restrictions, you can request +@acronym{IELR}(1) or canonical @acronym{LR}(1) parser tables. +@xref{Decl Summary,,lr.type}, to learn how. @cindex @acronym{GLR} parsing @cindex generalized @acronym{LR} (@acronym{GLR}) parsing @cindex ambiguous grammars @cindex nondeterministic parsing -Parsers for @acronym{LALR}(1) grammars are @dfn{deterministic}, meaning +Parsers for @acronym{LR}(1) grammars are @dfn{deterministic}, meaning roughly that the next grammar rule to apply at any point in the input is uniquely determined by the preceding input and a fixed, finite portion (called a @dfn{lookahead}) of the remaining input. A context-free @@ -708,8 +711,8 @@ from the values of the two subexpressions. @cindex shift/reduce conflicts @cindex reduce/reduce conflicts -In some grammars, Bison's standard -@acronym{LALR}(1) parsing algorithm cannot decide whether to apply a +In some grammars, Bison's deterministic +@acronym{LR}(1) parsing algorithm cannot decide whether to apply a certain grammar rule at a given point. That is, it may not be able to decide (on the basis of the input read so far) which of two possible reductions (applications of a grammar rule) applies, or whether to apply @@ -718,13 +721,13 @@ input. These are known respectively as @dfn{reduce/reduce} conflicts (@pxref{Reduce/Reduce}), and @dfn{shift/reduce} conflicts (@pxref{Shift/Reduce}). -To use a grammar that is not easily modified to be @acronym{LALR}(1), a +To use a grammar that is not easily modified to be @acronym{LR}(1), a more general parsing algorithm is sometimes necessary. If you include @code{%glr-parser} among the Bison declarations in your file (@pxref{Grammar Outline}), the result is a Generalized @acronym{LR} (@acronym{GLR}) parser. These parsers handle Bison grammars that contain no unresolved conflicts (i.e., after applying precedence -declarations) identically to @acronym{LALR}(1) parsers. However, when +declarations) identically to deterministic parsers. However, when faced with unresolved shift/reduce and reduce/reduce conflicts, @acronym{GLR} parsers use the simple expedient of doing both, effectively cloning the parser to follow both possibilities. Each of @@ -766,11 +769,8 @@ merged result. @cindex shift/reduce conflicts In the simplest cases, you can use the @acronym{GLR} algorithm -to parse grammars that are unambiguous, but fail to be @acronym{LALR}(1). -Such grammars typically require more than one symbol of lookahead, -or (in rare cases) fall into the category of grammars in which the -@acronym{LALR}(1) algorithm throws away too much information (they are in -@acronym{LR}(1), but not @acronym{LALR}(1), @ref{Mystery Conflicts}). +to parse grammars that are unambiguous but fail to be @acronym{LR}(1). +Such grammars typically require more than one symbol of lookahead. Consider a problem that arises in the declaration of enumerated and subrange types in the @@ -807,7 +807,7 @@ type enum = (a); valid, and more-complicated cases can come up in practical programs.) These two declarations look identical until the @samp{..} token. -With normal @acronym{LALR}(1) one-token lookahead it is not +With normal @acronym{LR}(1) one-token lookahead it is not possible to decide between the two forms when the identifier @samp{a} is parsed. It is, however, desirable for a parser to decide this, since in the latter case @@ -846,9 +846,9 @@ reports a syntax error as usual. The effect of all this is that the parser seems to ``guess'' the correct branch to take, or in other words, it seems to use more -lookahead than the underlying @acronym{LALR}(1) algorithm actually allows -for. In this example, @acronym{LALR}(2) would suffice, but also some cases -that are not @acronym{LALR}(@math{k}) for any @math{k} can be handled this way. +lookahead than the underlying @acronym{LR}(1) algorithm actually allows +for. In this example, @acronym{LR}(2) would suffice, but also some cases +that are not @acronym{LR}(@math{k}) for any @math{k} can be handled this way. In general, a @acronym{GLR} parser can take quadratic or cubic worst-case time, and the current Bison parser even takes exponential time and space @@ -901,7 +901,7 @@ expr : '(' expr ')' @end group @end example -When used as a normal @acronym{LALR}(1) grammar, Bison correctly complains +When used as a normal @acronym{LR}(1) grammar, Bison correctly complains about one reduce/reduce conflict. In the conflicting situation the parser chooses one of the alternatives, arbitrarily the one declared first. Therefore the following correct input is not @@ -933,7 +933,7 @@ there are at least two potential problems to beware. First, always analyze the conflicts reported by Bison to make sure that @acronym{GLR} splitting is only done where it is intended. A @acronym{GLR} parser splitting inadvertently may cause problems less obvious than an -@acronym{LALR} parser statically choosing the wrong alternative in a +@acronym{LR} parser statically choosing the wrong alternative in a conflict. Second, consider interactions with the lexer (@pxref{Semantic Tokens}) with great care. Since a split parser consumes tokens without performing any actions during the split, the lexer cannot obtain @@ -1153,7 +1153,7 @@ Another Bison feature requiring special consideration is @code{YYERROR} (@pxref{Action Features}), which you can invoke in a semantic action to initiate error recovery. During deterministic @acronym{GLR} operation, the effect of @code{YYERROR} is -the same as its effect in an @acronym{LALR}(1) parser. +the same as its effect in a deterministic parser. In a deferred semantic action, its effect is undefined. @c The effect is probably a syntax error at the split point. @@ -4463,7 +4463,7 @@ be @var{n} shift/reduce conflicts and no reduce/reduce conflicts. Bison reports an error if the number of shift/reduce conflicts differs from @var{n}, or if there are any reduce/reduce conflicts. -For normal @acronym{LALR}(1) parsers, reduce/reduce conflicts are more +For deterministic parsers, reduce/reduce conflicts are more serious, and should be eliminated entirely. Bison will always report reduce/reduce conflicts for these parsers. With @acronym{GLR} parsers, however, both kinds of conflicts are routine; otherwise, @@ -4887,7 +4887,7 @@ Some of the accepted @var{variable}s are: @findex %define api.push_pull @itemize @bullet -@item Language(s): C (LALR(1) only) +@item Language(s): C (deterministic parsers only) @item Purpose: Requests a pull parser, a push parser, or both. @xref{Push Decl, ,A Push Parser}. @@ -4899,6 +4899,71 @@ More user feedback will help to stabilize it.) @item Default Value: @code{"pull"} @end itemize +@item lr.default_rules +@cindex default rules +@findex %define lr.default_rules +@cindex delayed syntax errors +@cindex syntax errors delayed + +@itemize @bullet +@item Language(s): all + +@item Purpose: Specifies the kind of states that are permitted to +contain default rules. +That is, in such a state, Bison declares the rule with the largest +lookahead set to be the default rule by which to reduce and then removes +that lookahead set. +The advantages of default rules are discussed below. +The disadvantage is that, when the generated parser encounters a +syntactically unacceptable token, the parser might then perform +unnecessary reductions by default rules before it can detect the syntax +error. + +(This feature is experimental. +More user feedback will help to stabilize it.) + +@item Accepted Values: +@itemize +@item @code{"all"}. +For @acronym{LALR} and @acronym{IELR} parsers (@pxref{Decl +Summary,,lr.type}) by default, all states are permitted to contain +default rules. +The advantage is that parser table sizes can be significantly reduced. +The reason Bison does not by default attempt to address the disadvantage +of delayed syntax error detection is that this disadvantage is already +inherent in @acronym{LALR} and @acronym{IELR} parser tables. +That is, unlike a canonical @acronym{LR} state, an @acronym{LALR} or +@acronym{IELR} state can contain syntactically incorrect tokens in the +lookahead sets of its rules. + +@item @code{"consistent"}. +@cindex consistent states +A consistent state is a state that has only one possible action. +If that action is a reduction, then the parser does not need to request +a lookahead token from the scanner before performing that action. +However, the parser only recognizes the ability to ignore the lookahead +token when such a reduction is encoded as a default rule. +Thus, if default rules are permitted in and only in consistent states, +then a canonical @acronym{LR} parser reports a syntax error as soon as +it @emph{needs} the syntactically unacceptable token from the scanner. + +@item @code{"accepting"}. +@cindex accepting state +By default, the only default rule permitted in a canonical @acronym{LR} +parser is the accept rule in the accepting state, which the parser +reaches only after reading all tokens from the input. +Thus, the default canonical @acronym{LR} parser reports a syntax error +as soon as it @emph{reaches} the syntactically unacceptable token +without performing any extra reductions. +@end itemize + +@item Default Value: +@itemize +@item @code{"accepting"} if @code{lr.type} is @code{"canonical LR"}. +@item @code{"all"} otherwise. +@end itemize +@end itemize + @item lr.keep_unreachable_states @findex %define lr.keep_unreachable_states @@ -4942,6 +5007,83 @@ However, Bison does not compute which goto actions are useless. @end itemize @end itemize +@item lr.type +@findex %define lr.type +@cindex @acronym{LALR} +@cindex @acronym{IELR} +@cindex @acronym{LR} + +@itemize @bullet +@item Language(s): all + +@item Purpose: Specifies the type of parser tables within the +@acronym{LR}(1) family. +(This feature is experimental. +More user feedback will help to stabilize it.) + +@item Accepted Values: +@itemize +@item @code{"LALR"}. +While Bison generates @acronym{LALR} parser tables by default for +historical reasons, @acronym{IELR} or canonical @acronym{LR} is almost +always preferable for deterministic parsers. +The trouble is that @acronym{LALR} parser tables can suffer from +mysterious conflicts and may not accept the full set of sentences that +@acronym{IELR} and canonical @acronym{LR} accept. +@xref{Mystery Conflicts}, for details. +However, there are at least two scenarios where @acronym{LALR} may be +worthwhile: +@itemize +@cindex @acronym{GLR} with @acronym{LALR} +@item When employing @acronym{GLR} parsers (@pxref{GLR Parsers}), if you +do not resolve any conflicts statically (for example, with @code{%left} +or @code{%prec}), then the parser explores all potential parses of any +given input. +Thus, the use of @acronym{LALR} parser tables is guaranteed not to alter +the language accepted by the parser. +@acronym{LALR} parser tables are the smallest parser tables Bison can +currently generate, so they may be preferable. + +@item Occasionally during development, an especially malformed grammar +with a major recurring flaw may severely impede the @acronym{IELR} or +canonical @acronym{LR} parser table generation algorithm. +@acronym{LALR} can be a quick way to generate parser tables in order to +investigate such problems while ignoring the more subtle differences +from @acronym{IELR} and canonical @acronym{LR}. +@end itemize + +@item @code{"IELR"}. +@acronym{IELR} is a minimal @acronym{LR} algorithm. +That is, given any grammar (@acronym{LR} or non-@acronym{LR}), +@acronym{IELR} and canonical @acronym{LR} always accept exactly the same +set of sentences. +However, as for @acronym{LALR}, the number of parser states is often an +order of magnitude less for @acronym{IELR} than for canonical +@acronym{LR}. +More importantly, because canonical @acronym{LR}'s extra parser states +may contain duplicate conflicts in the case of non-@acronym{LR} +grammars, the number of conflicts for @acronym{IELR} is often an order +of magnitude less as well. +This can significantly reduce the complexity of developing of a grammar. + +@item @code{"canonical LR"}. +@cindex delayed syntax errors +@cindex syntax errors delayed +The only advantage of canonical @acronym{LR} over @acronym{IELR} is that +every canonical @acronym{LR} state encodes that state's exact set of +syntactically acceptable tokens. +The only difference in parsing behavior is then that the canonical +@acronym{LR} parser can report a syntax error as soon as possible +without performing any unnecessary reductions. +@xref{Decl Summary,,lr.default_rules}, for further details. +Even when canonical @acronym{LR} behavior is ultimately desired, +@acronym{IELR}'s elimination of duplicate conflicts should still +facilitate the development of a grammar. +@end itemize + +@item Default Value: @code{"LALR"} +@end itemize + @item namespace @findex %define namespace @@ -6610,12 +6752,13 @@ a @code{name} if a comma or colon follows, or a @code{type} if another @cindex @acronym{LR}(1) @cindex @acronym{LALR}(1) -However, Bison, like most parser generators, cannot actually handle all -@acronym{LR}(1) grammars. In this grammar, two contexts, that after -an @code{ID} -at the beginning of a @code{param_spec} and likewise at the beginning of -a @code{return_spec}, are similar enough that Bison assumes they are the -same. They appear similar because the same set of rules would be +However, for historical reasons, Bison cannot by default handle all +@acronym{LR}(1) grammars. +In this grammar, two contexts, that after an @code{ID} at the beginning +of a @code{param_spec} and likewise at the beginning of a +@code{return_spec}, are similar enough that Bison assumes they are the +same. +They appear similar because the same set of rules would be active---the rule for reducing to a @code{name} and that for reducing to a @code{type}. Bison is unable to determine at that stage of processing that the rules would require different lookahead tokens in the two @@ -6623,16 +6766,22 @@ contexts, so it makes a single parser state for them both. Combining the two contexts causes a conflict later. In parser terminology, this occurrence means that the grammar is not @acronym{LALR}(1). -In general, it is better to fix deficiencies than to document them. But -this particular deficiency is intrinsically hard to fix; parser -generators that can handle @acronym{LR}(1) grammars are hard to write -and tend to -produce parsers that are very large. In practice, Bison is more useful -as it is now. +For many practical grammars (specifically those that fall into the +non-@acronym{LR}(1) class), the limitations of @acronym{LALR}(1) result in +difficulties beyond just mysterious reduce/reduce conflicts. +The best way to fix all these problems is to select a different parser +table generation algorithm. +Either @acronym{IELR}(1) or canonical @acronym{LR}(1) would suffice, but +the former is more efficient and easier to debug during development. +@xref{Decl Summary,,lr.type}, for details. +(Bison's @acronym{IELR}(1) and canonical @acronym{LR}(1) implementations +are experimental. +More user feedback will help to stabilize them.) -When the problem arises, you can often fix it by identifying the two -parser states that are being confused, and adding something to make them -look distinct. In the above example, adding one rule to +If you instead wish to work around @acronym{LALR}(1)'s limitations, you +can often fix a mysterious conflict by identifying the two parser states +that are being confused, and adding something to make them look +distinct. In the above example, adding one rule to @code{return_spec} as follows makes the problem go away: @example @@ -6700,7 +6849,7 @@ The same is true of languages that require more than one symbol of lookahead, since the parser lacks the information necessary to make a decision at the point it must be made in a shift-reduce parser. Finally, as previously mentioned (@pxref{Mystery Conflicts}), -there are languages where Bison's particular choice of how to +there are languages where Bison's default choice of how to summarize the input seen so far loses necessary information. When you use the @samp{%glr-parser} declaration in your grammar file, @@ -6732,7 +6881,7 @@ grammar symbol that produces the same segment of the input token stream. Whenever the parser makes a transition from having multiple -states to having one, it reverts to the normal @acronym{LALR}(1) parsing +states to having one, it reverts to the normal deterministic parsing algorithm, after resolving and executing the saved-up actions. At this transition, some of the states on the stack will have semantic values that are sets (actually multisets) of possible actions. The @@ -6745,9 +6894,9 @@ Bison resolves and evaluates both and then calls the merge function on the result. Otherwise, it reports an ambiguity. It is possible to use a data structure for the @acronym{GLR} parsing tree that -permits the processing of any @acronym{LALR}(1) grammar in linear time (in the +permits the processing of any @acronym{LR}(1) grammar in linear time (in the size of the input), any unambiguous (not necessarily -@acronym{LALR}(1)) grammar in +@acronym{LR}(1)) grammar in quadratic worst-case time, and any general (possibly ambiguous) context-free grammar in cubic worst-case time. However, Bison currently uses a simpler data structure that requires time proportional to the @@ -6757,9 +6906,9 @@ grammars can require exponential time and space to process. Such badly behaving examples, however, are not generally of practical interest. Usually, nondeterminism in a grammar is local---the parser is ``in doubt'' only for a few tokens at a time. Therefore, the current data -structure should generally be adequate. On @acronym{LALR}(1) portions of a -grammar, in particular, it is only slightly slower than with the default -Bison parser. +structure should generally be adequate. On @acronym{LR}(1) portions of a +grammar, in particular, it is only slightly slower than with the +deterministic @acronym{LR}(1) Bison parser. For a more detailed exposition of @acronym{GLR} parsers, please see: Elizabeth Scott, Adrian Johnstone and Shamsa Sadaf Hussain, Tomita-Style @@ -6808,16 +6957,16 @@ The default value of @code{YYMAXDEPTH}, if you do not define it, is @vindex YYINITDEPTH You can control how much stack is allocated initially by defining the -macro @code{YYINITDEPTH} to a positive integer. For the C -@acronym{LALR}(1) parser, this value must be a compile-time constant +macro @code{YYINITDEPTH} to a positive integer. For the deterministic +parser in C, this value must be a compile-time constant unless you are assuming C99 or some other target language or compiler that allows variable-length arrays. The default is 200. Do not allow @code{YYINITDEPTH} to be greater than @code{YYMAXDEPTH}. @c FIXME: C++ output. -Because of semantical differences between C and C++, the -@acronym{LALR}(1) parsers in C produced by Bison cannot grow when compiled +Because of semantical differences between C and C++, the deterministic +parsers in C produced by Bison cannot grow when compiled by C++ compilers. In this precise case (compiling a C parser as C++) you are suggested to grow @code{YYINITDEPTH}. The Bison maintainers hope to fix this deficiency in a future release. @@ -7205,7 +7354,8 @@ useless: STR; @command{bison} reports: @example -calc.y: warning: 1 nonterminal and 1 rule useless in grammar +tmp.y: warning: 1 nonterminal useless in grammar +tmp.y: warning: 1 rule useless in grammar calc.y:11.1-7: warning: nonterminal useless in grammar: useless calc.y:11.10-12: warning: rule useless in grammar: useless: STR calc.y: conflicts: 7 shift/reduce @@ -7393,6 +7543,7 @@ control will jump to state 4, corresponding to the item @samp{exp -> exp '+' . exp}. Since there is no default action, any other token than those listed above will trigger a syntax error. +@cindex accepting state The state 3 is named the @dfn{final state}, or the @dfn{accepting state}: @@ -7473,7 +7624,7 @@ sentence @samp{NUM + NUM / NUM} can be parsed as @samp{NUM + (NUM / NUM)}, which corresponds to shifting @samp{/}, or as @samp{(NUM + NUM) / NUM}, which corresponds to reducing rule 1. -Because in @acronym{LALR}(1) parsing a single decision can be made, Bison +Because in deterministic parsing a single decision can be made, Bison arbitrarily chose to disable the reduction, see @ref{Shift/Reduce, , Shift/Reduce Conflicts}. Discarded actions are reported in between square brackets. @@ -7767,7 +7918,7 @@ other minor ways. Most importantly, imitate Yacc's output file name conventions, so that the parser output file is called @file{y.tab.c}, and the other outputs are called @file{y.output} and @file{y.tab.h}. -Also, if generating an @acronym{LALR}(1) parser in C, generate @code{#define} +Also, if generating a deterministic parser in C, generate @code{#define} statements in addition to an @code{enum} to associate token numbers with token names. Thus, the following shell script can substitute for Yacc, and the Bison @@ -7914,7 +8065,7 @@ separated list of @var{things} among: @table @code @item state Description of the grammar, conflicts (resolved and unresolved), and -@acronym{LALR} automaton. +parser's automaton. @item lookahead Implies @code{state} and augments the description of the automaton with @@ -7943,7 +8094,7 @@ described under the @samp{-v} and @samp{-d} options. @item -g [@var{file}] @itemx --graph[=@var{file}] -Output a graphical representation of the @acronym{LALR}(1) grammar +Output a graphical representation of the parser's automaton computed by Bison, in @uref{http://www.graphviz.org/, Graphviz} @uref{http://www.graphviz.org/doc/info/lang.html, @acronym{DOT}} format. @code{@var{file}} is optional. @@ -7952,7 +8103,7 @@ If omitted and the grammar file is @file{foo.y}, the output file will be @item -x [@var{file}] @itemx --xml[=@var{file}] -Output an XML report of the @acronym{LALR}(1) automaton computed by Bison. +Output an XML report of the parser's automaton computed by Bison. @code{@var{file}} is optional. If omitted and the grammar file is @file{foo.y}, the output file will be @file{foo.xml}. @@ -8025,7 +8176,7 @@ int yyparse (void); @c - Always pure @c - initial action -The C++ @acronym{LALR}(1) parser is selected using the skeleton directive, +The C++ deterministic parser is selected using the skeleton directive, @samp{%skeleton "lalr1.c"}, or the synonymous command-line option @option{--skeleton=lalr1.c}. @xref{Decl Summary}. @@ -8414,10 +8565,10 @@ calcxx_driver::error (const std::string& m) @subsubsection Calc++ Parser The parser definition file @file{calc++-parser.yy} starts by asking for -the C++ LALR(1) skeleton, the creation of the parser header file, and -specifies the name of the parser class. Because the C++ skeleton -changed several times, it is safer to require the version you designed -the grammar for. +the C++ deterministic parser skeleton, the creation of the parser header +file, and specifies the name of the parser class. +Because the C++ skeleton changed several times, it is safer to require +the version you designed the grammar for. @comment file: calc++-parser.yy @example @@ -10151,8 +10302,8 @@ is recovering from a syntax error, and 0 otherwise. @end deffn @deffn {Macro} YYSTACK_USE_ALLOCA -Macro used to control the use of @code{alloca} when the C -@acronym{LALR}(1) parser needs to extend its stacks. If defined to 0, +Macro used to control the use of @code{alloca} when the +deterministic parser in C needs to extend its stacks. If defined to 0, the parser will use @code{malloc} to extend its stacks. If defined to 1, the parser will use @code{alloca}. Values other than 0 and 1 are reserved for future Bison extensions. If not defined, @@ -10177,12 +10328,21 @@ Data type of semantic values; @code{int} by default. @cindex glossary @table @asis +@item Accepting State +A state whose only action is the accept action. +The accepting state is thus a consistent state. +@xref{Understanding,,}. + @item Backus-Naur Form (@acronym{BNF}; also called ``Backus Normal Form'') Formal method of specifying context-free grammars originally proposed by John Backus, and slightly improved by Peter Naur in his 1960-01-02 committee document contributing to what became the Algol 60 report. @xref{Language and Grammar, ,Languages and Context-Free Grammars}. +@item Consistent State +A state containing only one possible action. +@xref{Decl Summary,,lr.default_rules}. + @item Context-free grammars Grammars specified as rules that can be applied regardless of context. Thus, if there is a rule which says that an integer can be used as an @@ -10190,6 +10350,13 @@ expression, integers are allowed @emph{anywhere} an expression is permitted. @xref{Language and Grammar, ,Languages and Context-Free Grammars}. +@item Default Rule +The rule by which a parser should reduce if the current parser state +contains no other action for the lookahead token. +In permitted parser states, Bison declares the rule with the largest +lookahead set to be the default rule and removes that lookahead set. +@xref{Decl Summary,,lr.default_rules}. + @item Dynamic allocation Allocation of memory that occurs during execution, rather than at compile time or on entry to a function. @@ -10208,8 +10375,8 @@ rules. @xref{Algorithm, ,The Bison Parser Algorithm}. @item Generalized @acronym{LR} (@acronym{GLR}) A parsing algorithm that can handle all context-free grammars, including those -that are not @acronym{LALR}(1). It resolves situations that Bison's -usual @acronym{LALR}(1) +that are not @acronym{LR}(1). It resolves situations that Bison's +deterministic parsing algorithm cannot by effectively splitting off multiple parsers, trying all possible parsers, and discarding those that fail in the light of additional right context. @xref{Generalized LR Parsing, ,Generalized @@ -10220,6 +10387,20 @@ A language construct that is (in general) grammatically divisible; for example, `expression' or `declaration' in C@. @xref{Language and Grammar, ,Languages and Context-Free Grammars}. +@item @acronym{IELR}(1) +A minimal @acronym{LR}(1) parser table generation algorithm. +That is, given any context-free grammar, @acronym{IELR}(1) generates +parser tables with the full language recognition power of canonical +@acronym{LR}(1) but with nearly the same number of parser states as +@acronym{LALR}(1). +This reduction in parser states is often an order of magnitude. +More importantly, because canonical @acronym{LR}(1)'s extra parser +states may contain duplicate conflicts in the case of +non-@acronym{LR}(1) grammars, the number of conflicts for +@acronym{IELR}(1) is often an order of magnitude less as well. +This can significantly reduce the complexity of developing of a grammar. +@xref{Decl Summary,,lr.type}. + @item Infix operator An arithmetic operator that is placed between the operands on which it performs some operation. @@ -10263,8 +10444,8 @@ Tokens}. @item @acronym{LALR}(1) The class of context-free grammars that Bison (like most other parser -generators) can handle; a subset of @acronym{LR}(1). @xref{Mystery -Conflicts, ,Mysterious Reduce/Reduce Conflicts}. +generators) can handle by default; a subset of @acronym{LR}(1). +@xref{Mystery Conflicts, ,Mysterious Reduce/Reduce Conflicts}. @item @acronym{LR}(1) The class of context-free grammars in which at most one token of @@ -10382,4 +10563,4 @@ grammatically indivisible. The piece of text it represents is a token. @c LocalWords: infile ypp yxx outfile itemx tex leaderfill @c LocalWords: hbox hss hfill tt ly yyin fopen fclose ofirst gcc ll @c LocalWords: nbar yytext fst snd osplit ntwo strdup AST -@c LocalWords: YYSTACK DVI fdl printindex +@c LocalWords: YYSTACK DVI fdl printindex IELR diff --git a/src/getargs.c b/src/getargs.c index 4b35171e..2f2e9005 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -257,7 +257,8 @@ usage (int status) printf (_("Usage: %s [OPTION]... FILE\n"), program_name); fputs (_("\ -Generate LALR(1) and GLR parsers.\n\ +Generate a deterministic or GLR parser employing LALR(1), IELR(1), or\n\ +canonical LR(1) parser tables.\n\ \n\ "), stdout); From 620b5727730997767040a023463ce952a0d15ee9 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Thu, 23 Apr 2009 03:18:03 -0400 Subject: [PATCH 066/404] Rename "default rule" to "default reduction". This includes changing variable names in code, changing comments, and renaming %define lr.default_rules to %define lr.default_reductions. * NEWS (2.5): Update IELR documentation. * data/glr.c, data/lalr1.cc, data/lalr1.java, data/yacc.c: Adjust YYDEFACT and yydefact_ documentation. * doc/bison.texinfo (Decl Summary): Adjust lr.default_reductions and lr.type documentation. Make some other wording improvements. (Glossary): Adjust cross-references and Default Reduction definition. * src/lalr.c (state_lookahead_tokens_count): Adjust code. Remove a confusing comment pointed out by Akim Demaille. (initialize_LA): Adjust code. * src/print-xml.c (print_reductions): Adjust code. * src/print.c (print_reductions): Adjust code. * src/reader.c (reader): Adjust code. * src/tables.c (action_row): Adjust code. (token_actions): Adjust code. * src/tables.h: Adjust YYDEFACT documentation. * tests/input.at (%define lr.default_rules invalid values): Rename test group to... (%define lr.default_reductions invalid values): ... this, and update grammar file and expected output. * tests/reduce.at (AT_TEST_LR_DEFAULT_RULES): Rename to... (AT_TEST_LR_DEFAULT_REDUCTIONS): ... this, and update. --- ChangeLog | 30 +++++ NEWS | 9 +- data/glr.c | 14 +-- data/lalr1.cc | 16 +-- data/lalr1.java | 10 +- data/yacc.c | 12 +- doc/bison.texinfo | 74 +++++------ src/lalr.c | 28 +++-- src/parse-gram.c | 308 +++++++++++++++++++++++----------------------- src/parse-gram.h | 13 +- src/print-xml.c | 18 +-- src/print.c | 25 ++-- src/reader.c | 6 +- src/tables.c | 28 +++-- src/tables.h | 8 +- tests/input.at | 12 +- tests/reduce.at | 30 ++--- 17 files changed, 339 insertions(+), 302 deletions(-) diff --git a/ChangeLog b/ChangeLog index 013cba07..74169130 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2009-04-23 Joel E. Denny + + Rename "default rule" to "default reduction". + This includes changing variable names in code, changing + comments, and renaming %define lr.default_rules to %define + lr.default_reductions. + * NEWS (2.5): Update IELR documentation. + * data/glr.c, data/lalr1.cc, data/lalr1.java, data/yacc.c: + Adjust YYDEFACT and yydefact_ documentation. + * doc/bison.texinfo (Decl Summary): Adjust lr.default_reductions + and lr.type documentation. Make some other wording + improvements. + (Glossary): Adjust cross-references and Default Reduction + definition. + * src/lalr.c (state_lookahead_tokens_count): Adjust code. + Remove a confusing comment pointed out by Akim Demaille. + (initialize_LA): Adjust code. + * src/print-xml.c (print_reductions): Adjust code. + * src/print.c (print_reductions): Adjust code. + * src/reader.c (reader): Adjust code. + * src/tables.c (action_row): Adjust code. + (token_actions): Adjust code. + * src/tables.h: Adjust YYDEFACT documentation. + * tests/input.at (%define lr.default_rules invalid values): + Rename test group to... + (%define lr.default_reductions invalid values): ... this, and + update grammar file and expected output. + * tests/reduce.at (AT_TEST_LR_DEFAULT_RULES): Rename to... + (AT_TEST_LR_DEFAULT_REDUCTIONS): ... this, and update. + 2009-04-21 Joel E. Denny Document %define lr.type and lr.default_rules. diff --git a/NEWS b/NEWS index 91bde870..92a935fb 100644 --- a/NEWS +++ b/NEWS @@ -24,10 +24,11 @@ Bison News %define lr.type "IELR" %define lr.type "canonical LR" - The default rules optimization in the parser tables can also be - adjusted using `%define lr.default_rules'. See the documentation for - `%define lr.type' and `%define lr.default_rules' in the section `Bison - Declaration Summary' in the Bison manual for the details. + The default reduction optimization in the parser tables can also be + adjusted using `%define lr.default_reductions'. See the documentation + for `%define lr.type' and `%define lr.default_reductions' in the + section `Bison Declaration Summary' in the Bison manual for the + details. These features are experimental. More user feedback will help to stabilize them. diff --git a/data/glr.c b/data/glr.c index 0b4ad52c..661db956 100644 --- a/data/glr.c +++ b/data/glr.c @@ -1,8 +1,8 @@ -*- C -*- # GLR skeleton for Bison -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software -# Foundation, Inc. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 @@ -150,7 +150,7 @@ m4_changecom() m4_divert_push(0)dnl @output(b4_parser_file_name@)@ b4_copyright([Skeleton implementation for Bison GLR parsers in C], - [2002, 2003, 2004, 2005, 2006, 2007, 2008]) + [2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009]) [ /* C GLR parser skeleton written by Paul Hilfinger. */ @@ -412,9 +412,9 @@ static const ]b4_int_type_for([b4_merger])[ yymerger[] = ]b4_merger[ }; -/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE - doesn't specify something else to do. Zero means the default is an - error. */ +/* YYDEFACT[S] -- default reduction number in state S. 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[ @@ -2639,7 +2639,7 @@ m4_if(b4_skeleton, ["glr.c"], [b4_defines_if( [@output(b4_spec_defines_file@)@ b4_copyright([Skeleton interface for Bison GLR parsers in C], - [2002, 2003, 2004, 2005, 2006, 2007, 2008]) + [2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009]) b4_shared_declarations diff --git a/data/lalr1.cc b/data/lalr1.cc index 603786e5..342d87cf 100644 --- a/data/lalr1.cc +++ b/data/lalr1.cc @@ -1,6 +1,6 @@ # C++ skeleton for Bison -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 # Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify @@ -35,7 +35,7 @@ m4_divert_push(0)dnl b4_defines_if( [@output(b4_spec_defines_file@)@ b4_copyright([Skeleton interface for Bison LALR(1) parsers in C++], - [2002, 2003, 2004, 2005, 2006, 2007, 2008]) + [2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009]) dnl FIXME: This is wrong, we want computed header guards. [ /* C++ LALR(1) parser skeleton written by Akim Demaille. */ @@ -197,7 +197,7 @@ b4_error_verbose_if([, int tok])[); static const ]b4_int_type_for([b4_pact])[ yypact_[]; static const ]b4_int_type(b4_pact_ninf, b4_pact_ninf)[ yypact_ninf_; - /// For a state, default rule to reduce. + /// For a state, default reduction number. /// Unless\a yytable_ specifies something else to do. /// Zero means the default is an error. static const ]b4_int_type_for([b4_defact])[ yydefact_[]; @@ -300,7 +300,7 @@ b4_percent_code_get([[provides]])[]dnl ])dnl @output(b4_parser_file_name@)@ b4_copyright([Skeleton implementation for Bison LALR(1) parsers in C++], - [2002, 2003, 2004, 2005, 2006, 2007, 2008]) + [2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009]) b4_percent_code_get([[top]])[]dnl m4_if(b4_prefix, [yy], [], [ @@ -889,9 +889,9 @@ b4_error_verbose_if([, int tok])[) ]b4_pact[ }; - /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE - doesn't specify something else to do. Zero means the default is an - error. */ + /* YYDEFACT[S] -- default reduction number in state S. Performed when + YYTABLE doesn't specify something else to do. Zero means the + default is an error. */ const ]b4_int_type_for([b4_defact])[ ]b4_parser_class_name[::yydefact_[] = { @@ -1057,7 +1057,7 @@ b4_error_verbose_if([, int tok])[) dnl @output(b4_dir_prefix[]stack.hh@)@ b4_copyright([Stack handling for Bison parsers in C++], - [2002, 2003, 2004, 2005, 2006, 2007, 2008])[ + [2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009])[ #ifndef BISON_STACK_HH # define BISON_STACK_HH diff --git a/data/lalr1.java b/data/lalr1.java index c855a75f..5fbce2b5 100644 --- a/data/lalr1.java +++ b/data/lalr1.java @@ -1,6 +1,6 @@ # Java skeleton for Bison -*- autoconf -*- -# Copyright (C) 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2007, 2008, 2009 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 @@ -25,7 +25,7 @@ m4_ifval(m4_defn([b4_symbol_destructors]), m4_divert_push(0)dnl @output(b4_parser_file_name@)@ b4_copyright([Skeleton implementation for Bison LALR(1) parsers in Java], - [2007, 2008]) + [2007, 2008, 2009]) b4_percent_define_ifdef([package], [package b4_percent_define_get([package]); ])[/* First part of user declarations. */ @@ -732,9 +732,9 @@ m4_popdef([b4_at_dollar])])dnl ]b4_pact[ }; - /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE - doesn't specify something else to do. Zero means the default is an - error. */ + /* YYDEFACT[S] -- default reduction number in state S. Performed when + YYTABLE doesn't specify something else to do. Zero means the + default is an error. */ private static final ]b4_int_type_for([b4_defact])[ yydefact_[] = { ]b4_defact[ diff --git a/data/yacc.c b/data/yacc.c index 940b4a7a..3c7c602f 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -3,7 +3,7 @@ # Yacc compatible skeleton for Bison # Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, -# 2007, 2008 Free Software Foundation, Inc. +# 2007, 2008, 2009 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 @@ -155,7 +155,8 @@ m4_changecom() m4_divert_push(0)dnl @output(b4_parser_file_name@)@ b4_copyright([Skeleton implementation for Bison's Yacc-like parsers in C],dnl ' - [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006])[ + [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + 2009])[ /* C LALR(1) parser skeleton written by Richard Stallman, by simplifying the original so-called "semantic" parser. */ @@ -547,8 +548,8 @@ static const ]b4_int_type_for([b4_r2])[ yyr2[] = ]b4_r2[ }; -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero +/* 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[] = { @@ -1676,7 +1677,8 @@ yypushreturn: b4_defines_if( [@output(b4_spec_defines_file@)@ b4_copyright([Skeleton interface for Bison's Yacc-like parsers in C],dnl ' - [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006]) + [1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + 2009]) b4_percent_code_get([[requires]])[]dnl diff --git a/doc/bison.texinfo b/doc/bison.texinfo index ed092e2d..8e3ca224 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -4899,9 +4899,9 @@ More user feedback will help to stabilize it.) @item Default Value: @code{"pull"} @end itemize -@item lr.default_rules -@cindex default rules -@findex %define lr.default_rules +@item lr.default_reductions +@cindex default reductions +@findex %define lr.default_reductions @cindex delayed syntax errors @cindex syntax errors delayed @@ -4909,15 +4909,14 @@ More user feedback will help to stabilize it.) @item Language(s): all @item Purpose: Specifies the kind of states that are permitted to -contain default rules. -That is, in such a state, Bison declares the rule with the largest -lookahead set to be the default rule by which to reduce and then removes -that lookahead set. -The advantages of default rules are discussed below. +contain default reductions. +That is, in such a state, Bison declares the reduction with the largest +lookahead set to be the default reduction and then removes that +lookahead set. +The advantages of default reductions are discussed below. The disadvantage is that, when the generated parser encounters a syntactically unacceptable token, the parser might then perform -unnecessary reductions by default rules before it can detect the syntax -error. +unnecessary default reductions before it can detect the syntax error. (This feature is experimental. More user feedback will help to stabilize it.) @@ -4927,14 +4926,14 @@ More user feedback will help to stabilize it.) @item @code{"all"}. For @acronym{LALR} and @acronym{IELR} parsers (@pxref{Decl Summary,,lr.type}) by default, all states are permitted to contain -default rules. +default reductions. The advantage is that parser table sizes can be significantly reduced. The reason Bison does not by default attempt to address the disadvantage of delayed syntax error detection is that this disadvantage is already inherent in @acronym{LALR} and @acronym{IELR} parser tables. -That is, unlike a canonical @acronym{LR} state, an @acronym{LALR} or -@acronym{IELR} state can contain syntactically incorrect tokens in the -lookahead sets of its rules. +That is, unlike in a canonical @acronym{LR} state, the lookahead sets of +reductions in an @acronym{LALR} or @acronym{IELR} state can contain +tokens that are syntactically incorrect for some left contexts. @item @code{"consistent"}. @cindex consistent states @@ -4942,16 +4941,17 @@ A consistent state is a state that has only one possible action. If that action is a reduction, then the parser does not need to request a lookahead token from the scanner before performing that action. However, the parser only recognizes the ability to ignore the lookahead -token when such a reduction is encoded as a default rule. -Thus, if default rules are permitted in and only in consistent states, -then a canonical @acronym{LR} parser reports a syntax error as soon as -it @emph{needs} the syntactically unacceptable token from the scanner. +token when such a reduction is encoded as a default reduction. +Thus, if default reductions are permitted in and only in consistent +states, then a canonical @acronym{LR} parser reports a syntax error as +soon as it @emph{needs} the syntactically unacceptable token from the +scanner. @item @code{"accepting"}. @cindex accepting state -By default, the only default rule permitted in a canonical @acronym{LR} -parser is the accept rule in the accepting state, which the parser -reaches only after reading all tokens from the input. +By default, the only default reduction permitted in a canonical +@acronym{LR} parser is the accept action in the accepting state, which +the parser reaches only after reading all tokens from the input. Thus, the default canonical @acronym{LR} parser reports a syntax error as soon as it @emph{reaches} the syntactically unacceptable token without performing any extra reductions. @@ -5028,8 +5028,8 @@ While Bison generates @acronym{LALR} parser tables by default for historical reasons, @acronym{IELR} or canonical @acronym{LR} is almost always preferable for deterministic parsers. The trouble is that @acronym{LALR} parser tables can suffer from -mysterious conflicts and may not accept the full set of sentences that -@acronym{IELR} and canonical @acronym{LR} accept. +mysterious conflicts and thus may not accept the full set of sentences +that @acronym{IELR} and canonical @acronym{LR} accept. @xref{Mystery Conflicts}, for details. However, there are at least two scenarios where @acronym{LALR} may be worthwhile: @@ -5039,8 +5039,8 @@ worthwhile: do not resolve any conflicts statically (for example, with @code{%left} or @code{%prec}), then the parser explores all potential parses of any given input. -Thus, the use of @acronym{LALR} parser tables is guaranteed not to alter -the language accepted by the parser. +In this case, the use of @acronym{LALR} parser tables is guaranteed not +to alter the language accepted by the parser. @acronym{LALR} parser tables are the smallest parser tables Bison can currently generate, so they may be preferable. @@ -5069,13 +5069,14 @@ This can significantly reduce the complexity of developing of a grammar. @item @code{"canonical LR"}. @cindex delayed syntax errors @cindex syntax errors delayed -The only advantage of canonical @acronym{LR} over @acronym{IELR} is that -every canonical @acronym{LR} state encodes that state's exact set of -syntactically acceptable tokens. -The only difference in parsing behavior is then that the canonical +The only advantage of canonical @acronym{LR} over @acronym{IELR} is +that, for every left context of every canonical @acronym{LR} state, the +set of tokens accepted by that state is the exact set of tokens that is +syntactically acceptable in that left context. +Thus, the only difference in parsing behavior is that the canonical @acronym{LR} parser can report a syntax error as soon as possible without performing any unnecessary reductions. -@xref{Decl Summary,,lr.default_rules}, for further details. +@xref{Decl Summary,,lr.default_reductions}, for further details. Even when canonical @acronym{LR} behavior is ultimately desired, @acronym{IELR}'s elimination of duplicate conflicts should still facilitate the development of a grammar. @@ -10341,7 +10342,7 @@ committee document contributing to what became the Algol 60 report. @item Consistent State A state containing only one possible action. -@xref{Decl Summary,,lr.default_rules}. +@xref{Decl Summary,,lr.default_reductions}. @item Context-free grammars Grammars specified as rules that can be applied regardless of context. @@ -10350,12 +10351,13 @@ expression, integers are allowed @emph{anywhere} an expression is permitted. @xref{Language and Grammar, ,Languages and Context-Free Grammars}. -@item Default Rule -The rule by which a parser should reduce if the current parser state +@item Default Reduction +The reduction that a parser should perform if the current parser state contains no other action for the lookahead token. -In permitted parser states, Bison declares the rule with the largest -lookahead set to be the default rule and removes that lookahead set. -@xref{Decl Summary,,lr.default_rules}. +In permitted parser states, Bison declares the reduction with the +largest lookahead set to be the default reduction and removes that +lookahead set. +@xref{Decl Summary,,lr.default_reductions}. @item Dynamic allocation Allocation of memory that occurs during execution, rather than at diff --git a/src/lalr.c b/src/lalr.c index 01011498..a3a31b23 100644 --- a/src/lalr.c +++ b/src/lalr.c @@ -328,7 +328,7 @@ compute_lookahead_tokens (void) `----------------------------------------------------*/ static int -state_lookahead_tokens_count (state *s, bool default_rule_only_for_accept) +state_lookahead_tokens_count (state *s, bool default_reduction_only_for_accept) { int n_lookahead_tokens = 0; reductions *rp = s->reductions; @@ -344,14 +344,14 @@ state_lookahead_tokens_count (state *s, bool default_rule_only_for_accept) /* We need a lookahead either to distinguish different reductions (i.e., there are two or more), or to distinguish a reduction from a shift. Otherwise, it is straightforward, and the state is - `consistent'. However, for states that have any rules, treat only - the accepting state as consistent (since there is never a lookahead - token that makes sense there, and so no lookahead token should be - read) if the user has otherwise disabled default rules. */ + `consistent'. However, treat only the accepting state as + consistent (because there is never a lookahead token that makes + sense there, and so no lookahead token should be read) if the user + has otherwise disabled default reductions. */ if (rp->num > 1 || (rp->num == 1 && sp->num && TRANSITION_IS_SHIFT (sp, 0)) || (rp->num == 1 && rp->rules[0]->number != 0 - && default_rule_only_for_accept)) + && default_reduction_only_for_accept)) n_lookahead_tokens += rp->num; else s->consistent = 1; @@ -369,18 +369,21 @@ initialize_LA (void) { state_number i; bitsetv pLA; - bool default_rule_only_for_accept; + bool default_reduction_only_for_accept; { - char *default_rules = muscle_percent_define_get ("lr.default_rules"); - default_rule_only_for_accept = 0 == strcmp (default_rules, "accepting"); - free (default_rules); + char *default_reductions = + muscle_percent_define_get ("lr.default_reductions"); + default_reduction_only_for_accept = + 0 == strcmp (default_reductions, "accepting"); + free (default_reductions); } /* Compute the total number of reductions requiring a lookahead. */ nLA = 0; for (i = 0; i < nstates; i++) nLA += - state_lookahead_tokens_count (states[i], default_rule_only_for_accept); + state_lookahead_tokens_count (states[i], + default_reduction_only_for_accept); /* Avoid having to special case 0. */ if (!nLA) nLA = 1; @@ -392,7 +395,8 @@ initialize_LA (void) for (i = 0; i < nstates; i++) { int count = - state_lookahead_tokens_count (states[i], default_rule_only_for_accept); + state_lookahead_tokens_count (states[i], + default_reduction_only_for_accept); if (count) { states[i]->reductions->lookahead_tokens = pLA; diff --git a/src/parse-gram.c b/src/parse-gram.c index 516e4f4b..acae131b 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -1,10 +1,9 @@ - -/* A Bison parser, made by GNU Bison 2.4.4-738cd. */ +/* A Bison parser, made by GNU Bison 2.4.1.49-783b. */ /* Skeleton implementation for Bison's Yacc-like parsers in C - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2007, 2008, 2009 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 @@ -46,7 +45,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.4.4-738cd" +#define YYBISON_VERSION "2.4.1.49-783b" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -75,7 +74,7 @@ /* Copy the first part of user declarations. */ -/* Line 189 of yacc.c */ +/* Line 190 of yacc.c */ #line 1 "parse-gram.y" /* Bison Grammar Parser -*- C -*- @@ -150,8 +149,8 @@ static int current_prec = 0; #define YYTYPE_UINT8 uint_fast8_t -/* Line 189 of yacc.c */ -#line 155 "parse-gram.c" +/* Line 190 of yacc.c */ +#line 154 "parse-gram.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -299,7 +298,7 @@ static int current_prec = 0; typedef union YYSTYPE { -/* Line 222 of yacc.c */ +/* Line 223 of yacc.c */ #line 92 "parse-gram.y" symbol *symbol; @@ -313,8 +312,8 @@ typedef union YYSTYPE -/* Line 222 of yacc.c */ -#line 318 "parse-gram.c" +/* Line 223 of yacc.c */ +#line 317 "parse-gram.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -338,8 +337,8 @@ typedef struct YYLTYPE /* Copy the second part of user declarations. */ -/* Line 264 of yacc.c */ -#line 343 "parse-gram.c" +/* Line 265 of yacc.c */ +#line 342 "parse-gram.c" #ifdef short # undef short @@ -754,8 +753,8 @@ static const yytype_uint8 yyr2[] = 1, 1, 1, 1, 0, 2 }; -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero +/* 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 yytype_uint8 yydefact[] = { @@ -1029,147 +1028,147 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) { case 3: /* "\"string\"" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 180 "parse-gram.y" { fputs (quotearg_style (c_quoting_style, (yyvaluep->chars)), stderr); }; -/* Line 715 of yacc.c */ -#line 1038 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1037 "parse-gram.c" break; case 4: /* "\"integer\"" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 191 "parse-gram.y" { fprintf (stderr, "%d", (yyvaluep->integer)); }; -/* Line 715 of yacc.c */ -#line 1047 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1046 "parse-gram.c" break; case 43: /* "\"{...}\"" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 182 "parse-gram.y" { fprintf (stderr, "{\n%s\n}", (yyvaluep->code)); }; -/* Line 715 of yacc.c */ -#line 1056 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1055 "parse-gram.c" break; case 44: /* "\"char\"" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 174 "parse-gram.y" { fputs (char_name ((yyvaluep->character)), stderr); }; -/* Line 715 of yacc.c */ -#line 1065 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1064 "parse-gram.c" break; case 45: /* "\"epilogue\"" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 182 "parse-gram.y" { fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); }; -/* Line 715 of yacc.c */ -#line 1074 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1073 "parse-gram.c" break; case 47: /* "\"identifier\"" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 187 "parse-gram.y" { fputs ((yyvaluep->uniqstr), stderr); }; -/* Line 715 of yacc.c */ -#line 1083 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1082 "parse-gram.c" break; case 48: /* "\"identifier:\"" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 188 "parse-gram.y" { fprintf (stderr, "%s:", (yyvaluep->uniqstr)); }; -/* Line 715 of yacc.c */ -#line 1092 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1091 "parse-gram.c" break; case 51: /* "\"%{...%}\"" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 182 "parse-gram.y" { fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); }; -/* Line 715 of yacc.c */ -#line 1101 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1100 "parse-gram.c" break; case 53: /* "\"type\"" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 186 "parse-gram.y" { fprintf (stderr, "<%s>", (yyvaluep->uniqstr)); }; -/* Line 715 of yacc.c */ -#line 1110 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1109 "parse-gram.c" break; case 82: /* "variable" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 187 "parse-gram.y" { fputs ((yyvaluep->uniqstr), stderr); }; -/* Line 715 of yacc.c */ -#line 1119 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1118 "parse-gram.c" break; case 83: /* "content.opt" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 182 "parse-gram.y" { fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); }; -/* Line 715 of yacc.c */ -#line 1128 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1127 "parse-gram.c" break; case 84: /* "braceless" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 182 "parse-gram.y" { fprintf (stderr, "{\n%s\n}", (yyvaluep->chars)); }; -/* Line 715 of yacc.c */ -#line 1137 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1136 "parse-gram.c" break; case 85: /* "id" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 194 "parse-gram.y" { fprintf (stderr, "%s", (yyvaluep->symbol)->tag); }; -/* Line 715 of yacc.c */ -#line 1146 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1145 "parse-gram.c" break; case 86: /* "id_colon" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 195 "parse-gram.y" { fprintf (stderr, "%s:", (yyvaluep->symbol)->tag); }; -/* Line 715 of yacc.c */ -#line 1155 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1154 "parse-gram.c" break; case 87: /* "symbol" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 194 "parse-gram.y" { fprintf (stderr, "%s", (yyvaluep->symbol)->tag); }; -/* Line 715 of yacc.c */ -#line 1164 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1163 "parse-gram.c" break; case 88: /* "string_as_id" */ -/* Line 715 of yacc.c */ +/* Line 716 of yacc.c */ #line 194 "parse-gram.y" { fprintf (stderr, "%s", (yyvaluep->symbol)->tag); }; -/* Line 715 of yacc.c */ -#line 1173 "parse-gram.c" +/* Line 716 of yacc.c */ +#line 1172 "parse-gram.c" break; default: break; @@ -1688,7 +1687,7 @@ YYLTYPE yylloc; /* User initialization code. */ -/* Line 1248 of yacc.c */ +/* Line 1249 of yacc.c */ #line 84 "parse-gram.y" { /* Bison's grammar can initial empty locations, hence a default @@ -1697,8 +1696,8 @@ YYLTYPE yylloc; boundary_set (&yylloc.end, current_file, 1, 1); } -/* Line 1248 of yacc.c */ -#line 1702 "parse-gram.c" +/* Line 1249 of yacc.c */ +#line 1701 "parse-gram.c" yylsp[0] = yylloc; goto yysetstate; @@ -1885,7 +1884,7 @@ yyreduce: { case 6: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 218 "parse-gram.y" { code_props plain_code; @@ -1900,14 +1899,14 @@ yyreduce: case 7: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 227 "parse-gram.y" { debug_flag = true; } break; case 8: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 229 "parse-gram.y" { muscle_percent_define_insert ((yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].chars)); @@ -1916,14 +1915,14 @@ yyreduce: case 9: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 232 "parse-gram.y" { defines_flag = true; } break; case 10: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 234 "parse-gram.y" { defines_flag = true; @@ -1933,42 +1932,42 @@ yyreduce: case 11: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 238 "parse-gram.y" { error_verbose = true; } break; case 12: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 239 "parse-gram.y" { expected_sr_conflicts = (yyvsp[(2) - (2)].integer); } break; case 13: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 240 "parse-gram.y" { expected_rr_conflicts = (yyvsp[(2) - (2)].integer); } break; case 14: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 241 "parse-gram.y" { spec_file_prefix = (yyvsp[(2) - (2)].chars); } break; case 15: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 242 "parse-gram.y" { spec_file_prefix = (yyvsp[(3) - (3)].chars); } break; case 16: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 244 "parse-gram.y" { nondeterministic_parser = true; @@ -1978,7 +1977,7 @@ yyreduce: case 17: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 249 "parse-gram.y" { code_props action; @@ -1992,80 +1991,77 @@ yyreduce: case 18: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 257 "parse-gram.y" { language_argmatch ((yyvsp[(2) - (2)].chars), grammar_prio, (yylsp[(1) - (2)])); } - -/* Line 1457 of yacc.c */ -#line 2036 "../../../src/parse-gram.c" break; case 19: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 258 "parse-gram.y" { add_param ("lex_param", (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); } break; case 20: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 259 "parse-gram.y" { locations_flag = true; } break; case 21: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 260 "parse-gram.y" { spec_name_prefix = (yyvsp[(2) - (2)].chars); } break; case 22: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 261 "parse-gram.y" { spec_name_prefix = (yyvsp[(3) - (3)].chars); } break; case 23: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 262 "parse-gram.y" { no_lines_flag = true; } break; case 24: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 263 "parse-gram.y" { nondeterministic_parser = true; } break; case 25: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 264 "parse-gram.y" { spec_outfile = (yyvsp[(2) - (2)].chars); } break; case 26: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 265 "parse-gram.y" { spec_outfile = (yyvsp[(3) - (3)].chars); } break; case 27: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 266 "parse-gram.y" { add_param ("parse_param", (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); } break; case 28: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 268 "parse-gram.y" { /* %pure-parser is deprecated in favor of `%define api.pure', so use @@ -2083,14 +2079,14 @@ yyreduce: case 29: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 280 "parse-gram.y" { version_check (&(yylsp[(2) - (2)]), (yyvsp[(2) - (2)].chars)); } break; case 30: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 282 "parse-gram.y" { char const *skeleton_user = (yyvsp[(2) - (2)].chars); @@ -2119,28 +2115,28 @@ yyreduce: case 31: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 305 "parse-gram.y" { token_table_flag = true; } break; case 32: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 306 "parse-gram.y" { report_flag |= report_states; } break; case 33: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 307 "parse-gram.y" { yacc_flag = true; } break; case 37: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 315 "parse-gram.y" { grammar_start_symbol_set ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); @@ -2149,7 +2145,7 @@ yyreduce: case 38: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 319 "parse-gram.y" { symbol_list *list; @@ -2161,7 +2157,7 @@ yyreduce: case 39: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 326 "parse-gram.y" { symbol_list *list; @@ -2173,7 +2169,7 @@ yyreduce: case 40: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 333 "parse-gram.y" { default_prec = true; @@ -2182,7 +2178,7 @@ yyreduce: case 41: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 337 "parse-gram.y" { default_prec = false; @@ -2191,7 +2187,7 @@ yyreduce: case 42: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 341 "parse-gram.y" { /* Do not invoke muscle_percent_code_grow here since it invokes @@ -2203,7 +2199,7 @@ yyreduce: case 43: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 348 "parse-gram.y" { muscle_percent_code_grow ((yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].chars), (yylsp[(3) - (3)])); @@ -2213,21 +2209,21 @@ yyreduce: case 44: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 362 "parse-gram.y" {} break; case 45: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 363 "parse-gram.y" { muscle_code_grow ("union_name", (yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 46: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 368 "parse-gram.y" { union_seen = true; @@ -2238,14 +2234,14 @@ yyreduce: case 47: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 379 "parse-gram.y" { current_class = nterm_sym; } break; case 48: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 380 "parse-gram.y" { current_class = unknown_sym; @@ -2255,14 +2251,14 @@ yyreduce: case 49: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 384 "parse-gram.y" { current_class = token_sym; } break; case 50: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 385 "parse-gram.y" { current_class = unknown_sym; @@ -2272,7 +2268,7 @@ yyreduce: case 51: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 390 "parse-gram.y" { symbol_list *list; @@ -2285,7 +2281,7 @@ yyreduce: case 52: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 401 "parse-gram.y" { symbol_list *list; @@ -2302,126 +2298,126 @@ yyreduce: case 53: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 415 "parse-gram.y" { (yyval.assoc) = left_assoc; } break; case 54: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 416 "parse-gram.y" { (yyval.assoc) = right_assoc; } break; case 55: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 417 "parse-gram.y" { (yyval.assoc) = non_assoc; } break; case 56: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 421 "parse-gram.y" { current_type = NULL; } break; case 57: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 422 "parse-gram.y" { current_type = (yyvsp[(1) - (1)].uniqstr); tag_seen = true; } break; case 58: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 428 "parse-gram.y" { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); } break; case 59: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 430 "parse-gram.y" { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), symbol_list_sym_new ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]))); } break; case 60: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 434 "parse-gram.y" { (yyval.symbol) = (yyvsp[(1) - (1)].symbol); } break; case 61: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 435 "parse-gram.y" { (yyval.symbol) = (yyvsp[(1) - (2)].symbol); symbol_user_token_number_set ((yyvsp[(1) - (2)].symbol), (yyvsp[(2) - (2)].integer), (yylsp[(2) - (2)])); } break; case 62: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 441 "parse-gram.y" { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); } break; case 63: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 443 "parse-gram.y" { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), symbol_list_sym_new ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]))); } break; case 64: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 447 "parse-gram.y" { (yyval.list) = (yyvsp[(1) - (1)].list); } break; case 65: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 448 "parse-gram.y" { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list)); } break; case 66: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 452 "parse-gram.y" { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); } break; case 67: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 453 "parse-gram.y" { (yyval.list) = symbol_list_type_new ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 68: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 454 "parse-gram.y" { (yyval.list) = symbol_list_default_tagged_new ((yylsp[(1) - (1)])); } break; case 69: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 455 "parse-gram.y" { (yyval.list) = symbol_list_default_tagless_new ((yylsp[(1) - (1)])); } break; case 70: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 461 "parse-gram.y" { current_type = (yyvsp[(1) - (1)].uniqstr); @@ -2431,7 +2427,7 @@ yyreduce: case 71: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 466 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (1)].symbol), current_class, (yylsp[(1) - (1)]), true); @@ -2441,7 +2437,7 @@ yyreduce: case 72: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 471 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true); @@ -2452,7 +2448,7 @@ yyreduce: case 73: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 477 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true); @@ -2463,7 +2459,7 @@ yyreduce: case 74: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 483 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (3)].symbol), current_class, (yylsp[(1) - (3)]), true); @@ -2475,7 +2471,7 @@ yyreduce: case 81: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 513 "parse-gram.y" { yyerrok; @@ -2484,77 +2480,77 @@ yyreduce: case 82: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 519 "parse-gram.y" { current_lhs = (yyvsp[(1) - (1)].symbol); current_lhs_location = (yylsp[(1) - (1)]); } break; case 84: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 523 "parse-gram.y" { grammar_current_rule_end ((yylsp[(1) - (1)])); } break; case 85: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 524 "parse-gram.y" { grammar_current_rule_end ((yylsp[(3) - (3)])); } break; case 87: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 530 "parse-gram.y" { grammar_current_rule_begin (current_lhs, current_lhs_location); } break; case 88: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 532 "parse-gram.y" { grammar_current_rule_symbol_append ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); } break; case 89: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 534 "parse-gram.y" { grammar_current_rule_action_append ((yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); } break; case 90: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 536 "parse-gram.y" { grammar_current_rule_prec_set ((yyvsp[(3) - (3)].symbol), (yylsp[(3) - (3)])); } break; case 91: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 538 "parse-gram.y" { grammar_current_rule_dprec_set ((yyvsp[(3) - (3)].integer), (yylsp[(3) - (3)])); } break; case 92: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 540 "parse-gram.y" { grammar_current_rule_merge_set ((yyvsp[(3) - (3)].uniqstr), (yylsp[(3) - (3)])); } break; case 94: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 550 "parse-gram.y" { (yyval.uniqstr) = uniqstr_new ((yyvsp[(1) - (1)].chars)); } break; case 95: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 556 "parse-gram.y" { (yyval.chars) = ""; @@ -2563,7 +2559,7 @@ yyreduce: case 97: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 569 "parse-gram.y" { code_props plain_code; @@ -2577,14 +2573,14 @@ yyreduce: case 98: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 589 "parse-gram.y" { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 99: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 591 "parse-gram.y" { (yyval.symbol) = symbol_get (char_name ((yyvsp[(1) - (1)].character)), (yylsp[(1) - (1)])); @@ -2595,14 +2591,14 @@ yyreduce: case 100: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 599 "parse-gram.y" { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 103: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 611 "parse-gram.y" { (yyval.symbol) = symbol_get (quotearg_style (c_quoting_style, (yyvsp[(1) - (1)].chars)), (yylsp[(1) - (1)])); @@ -2612,7 +2608,7 @@ yyreduce: case 105: -/* Line 1455 of yacc.c */ +/* Line 1456 of yacc.c */ #line 620 "parse-gram.y" { code_props plain_code; @@ -2626,8 +2622,8 @@ yyreduce: -/* Line 1455 of yacc.c */ -#line 2628 "parse-gram.c" +/* Line 1456 of yacc.c */ +#line 2627 "parse-gram.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2845,7 +2841,7 @@ yyreturn: -/* Line 1675 of yacc.c */ +/* Line 1676 of yacc.c */ #line 630 "parse-gram.y" diff --git a/src/parse-gram.h b/src/parse-gram.h index 938b2017..ae82cd45 100644 --- a/src/parse-gram.h +++ b/src/parse-gram.h @@ -1,10 +1,9 @@ - -/* A Bison parser, made by GNU Bison 2.4.4-738cd. */ +/* A Bison parser, made by GNU Bison 2.4.1.49-783b. */ /* Skeleton interface for Bison's Yacc-like parsers in C - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + 2007, 2008, 2009 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 @@ -160,7 +159,7 @@ typedef union YYSTYPE { -/* Line 1740 of yacc.c */ +/* Line 1742 of yacc.c */ #line 92 "parse-gram.y" symbol *symbol; @@ -174,8 +173,8 @@ typedef union YYSTYPE -/* Line 1740 of yacc.c */ -#line 179 "parse-gram.h" +/* Line 1742 of yacc.c */ +#line 178 "parse-gram.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ diff --git a/src/print-xml.c b/src/print-xml.c index cb6707da..72e61a84 100644 --- a/src/print-xml.c +++ b/src/print-xml.c @@ -1,6 +1,6 @@ /* Print an xml on generated parser, for Bison, - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -244,7 +244,7 @@ print_reductions (FILE *out, int level, state *s) { transitions *trans = s->transitions; reductions *reds = s->reductions; - rule *default_rule = NULL; + rule *default_reduction = NULL; int report = false; int i, j; @@ -254,7 +254,7 @@ print_reductions (FILE *out, int level, state *s) } if (yydefact[s->number] != 0) - default_rule = &rules[yydefact[s->number] - 1]; + default_reduction = &rules[yydefact[s->number] - 1]; bitset_zero (no_reduce_set); FOR_EACH_SHIFT (trans, i) @@ -263,7 +263,7 @@ print_reductions (FILE *out, int level, state *s) if (s->errs->symbols[i]) bitset_set (no_reduce_set, s->errs->symbols[i]->number); - if (default_rule) + if (default_reduction) report = true; if (reds->lookahead_tokens) @@ -276,7 +276,7 @@ print_reductions (FILE *out, int level, state *s) { if (! count) { - if (reds->rules[j] != default_rule) + if (reds->rules[j] != default_reduction) report = true; count = true; } @@ -307,7 +307,7 @@ print_reductions (FILE *out, int level, state *s) { if (! count) { - if (reds->rules[j] != default_rule) + if (reds->rules[j] != default_reduction) print_reduction (out, level + 1, symbols[i]->tag, reds->rules[j], true); else @@ -318,7 +318,7 @@ print_reductions (FILE *out, int level, state *s) { if (defaulted) print_reduction (out, level + 1, symbols[i]->tag, - default_rule, true); + default_reduction, true); defaulted = false; print_reduction (out, level + 1, symbols[i]->tag, reds->rules[j], false); @@ -326,9 +326,9 @@ print_reductions (FILE *out, int level, state *s) } } - if (default_rule) + if (default_reduction) print_reduction (out, level + 1, - "$default", default_rule, true); + "$default", default_reduction, true); xml_puts (out, level, ""); } diff --git a/src/print.c b/src/print.c index 413896c2..7fc577c4 100644 --- a/src/print.c +++ b/src/print.c @@ -242,7 +242,7 @@ print_reductions (FILE *out, state *s) { transitions *trans = s->transitions; reductions *reds = s->reductions; - rule *default_rule = NULL; + rule *default_reduction = NULL; size_t width = 0; int i, j; bool non_default_action = false; @@ -251,7 +251,7 @@ print_reductions (FILE *out, state *s) return; if (yydefact[s->number] != 0) - default_rule = &rules[yydefact[s->number] - 1]; + default_reduction = &rules[yydefact[s->number] - 1]; bitset_zero (no_reduce_set); FOR_EACH_SHIFT (trans, i) @@ -261,7 +261,7 @@ print_reductions (FILE *out, state *s) bitset_set (no_reduce_set, s->errs->symbols[i]->number); /* Compute the width of the lookahead token column. */ - if (default_rule) + if (default_reduction) width = strlen (_("$default")); if (reds->lookahead_tokens) @@ -274,7 +274,7 @@ print_reductions (FILE *out, state *s) { if (! count) { - if (reds->rules[j] != default_rule) + if (reds->rules[j] != default_reduction) max_length (&width, symbols[i]->tag); count = true; } @@ -306,7 +306,7 @@ print_reductions (FILE *out, state *s) { if (! count) { - if (reds->rules[j] != default_rule) + if (reds->rules[j] != default_reduction) { non_default_action = true; print_reduction (out, width, @@ -323,7 +323,7 @@ print_reductions (FILE *out, state *s) if (defaulted) print_reduction (out, width, symbols[i]->tag, - default_rule, true); + default_reduction, true); defaulted = false; print_reduction (out, width, symbols[i]->tag, @@ -332,15 +332,16 @@ print_reductions (FILE *out, state *s) } } - if (default_rule) + if (default_reduction) { - char *default_rules = muscle_percent_define_get ("lr.default_rules"); - print_reduction (out, width, _("$default"), default_rule, true); - aver (0 == strcmp (default_rules, "all") - || (0 == strcmp (default_rules, "consistent") + char *default_reductions = + muscle_percent_define_get ("lr.default_reductions"); + print_reduction (out, width, _("$default"), default_reduction, true); + aver (0 == strcmp (default_reductions, "all") + || (0 == strcmp (default_reductions, "consistent") && !non_default_action) || (reds->num == 1 && reds->rules[0]->number == 0)); - free (default_rules); + free (default_reductions); } } diff --git a/src/reader.c b/src/reader.c index b2fdc3b6..17ff0f78 100644 --- a/src/reader.c +++ b/src/reader.c @@ -561,9 +561,9 @@ reader (void) muscle_percent_define_default ("lr.type", "LALR"); lr_type = muscle_percent_define_get ("lr.type"); if (0 != strcmp (lr_type, "canonical LR")) - muscle_percent_define_default ("lr.default_rules", "all"); + muscle_percent_define_default ("lr.default_reductions", "all"); else - muscle_percent_define_default ("lr.default_rules", "accepting"); + muscle_percent_define_default ("lr.default_reductions", "accepting"); free (lr_type); } @@ -571,7 +571,7 @@ reader (void) { static char const * const values[] = { "lr.type", "LALR", "IELR", "canonical LR", NULL, - "lr.default_rules", "all", "consistent", "accepting", NULL, + "lr.default_reductions", "all", "consistent", "accepting", NULL, NULL }; muscle_percent_define_check_values (values); diff --git a/src/tables.c b/src/tables.c index 958e77b1..186c1fec 100644 --- a/src/tables.c +++ b/src/tables.c @@ -240,7 +240,7 @@ static rule * action_row (state *s) { int i; - rule *default_rule = NULL; + rule *default_reduction = NULL; reductions *reds = s->reductions; transitions *trans = s->transitions; errs *errp = s->errs; @@ -304,14 +304,15 @@ action_row (state *s) actrow[sym->number] = ACTION_NUMBER_MINIMUM; } - /* Turn off default rules where requested by the user. See + /* Turn off default reductions where requested by the user. See state_lookahead_tokens_count in lalr.c to understand when states are labeled as consistent. */ { - char *default_rules = muscle_percent_define_get ("lr.default_rules"); - if (0 != strcmp (default_rules, "all") && !s->consistent) + char *default_reductions = + muscle_percent_define_get ("lr.default_reductions"); + if (0 != strcmp (default_reductions, "all") && !s->consistent) nodefault = true; - free (default_rules); + free (default_reductions); } /* Now find the most common reduction and make it the default action @@ -320,7 +321,7 @@ action_row (state *s) if (reds->num >= 1 && !nodefault) { if (s->consistent) - default_rule = reds->rules[0]; + default_reduction = reds->rules[0]; else { int max = 0; @@ -337,7 +338,7 @@ action_row (state *s) if (count > max) { max = count; - default_rule = r; + default_reduction = r; } } @@ -351,17 +352,18 @@ action_row (state *s) { int j; for (j = 0; j < ntokens; j++) - if (actrow[j] == rule_number_as_item_number (default_rule->number) + if (actrow[j] + == rule_number_as_item_number (default_reduction->number) && ! (nondeterministic_parser && conflrow[j])) actrow[j] = 0; } } } - /* If have no default rule, the default is an error. + /* If have no default reduction, the default is an error. So replace any action which says "error" with "use default". */ - if (!default_rule) + if (!default_reduction) for (i = 0; i < ntokens; i++) if (actrow[i] == ACTION_NUMBER_MINIMUM) actrow[i] = 0; @@ -369,7 +371,7 @@ action_row (state *s) if (conflicted) conflict_row (s); - return default_rule; + return default_reduction; } @@ -450,8 +452,8 @@ token_actions (void) for (i = 0; i < nstates; ++i) { - rule *default_rule = action_row (states[i]); - yydefact[i] = default_rule ? default_rule->number + 1 : 0; + rule *default_reduction = action_row (states[i]); + yydefact[i] = default_reduction ? default_reduction->number + 1 : 0; save_row (i); /* Now that the parser was computed, we can find which rules are diff --git a/src/tables.h b/src/tables.h index b0fbe9ac..a44cdb86 100644 --- a/src/tables.h +++ b/src/tables.h @@ -1,5 +1,5 @@ /* Prepare the LALR and GLR parser tables. - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -45,9 +45,9 @@ YYSTOS[S] = the symbol number of the symbol that leads to state S. - YYDEFACT[S] = default rule to reduce with in state s, when YYTABLE - doesn't specify something else to do. Zero means the default is an - error. + YYDEFACT[S] = default reduction number in state s. Performed when + YYTABLE doesn't specify something else to do. Zero means the default + is an error. YYDEFGOTO[I] = default state to go to after a reduction of a rule that generates variable NTOKENS + I, except when YYTABLE specifies diff --git a/tests/input.at b/tests/input.at index 9edf6132..9fa8af72 100644 --- a/tests/input.at +++ b/tests/input.at @@ -867,20 +867,20 @@ AT_BISON_CHECK([[Input.y]], [1], [], AT_CLEANUP -## ----------------------------------------- ## -## %define lr.default_rules invalid values. ## -## ----------------------------------------- ## +## ---------------------------------------------- ## +## %define lr.default_reductions invalid values. ## +## ---------------------------------------------- ## -AT_SETUP([[%define lr.default_rules invalid values]]) +AT_SETUP([[%define lr.default_reductions invalid values]]) AT_DATA([[input.y]], -[[%define lr.default_rules "bogus" +[[%define lr.default_reductions "bogus" %% start: ; ]]) AT_BISON_CHECK([[input.y]], [[1]], [[]], -[[input.y:1.9-24: invalid value for %define variable `lr.default_rules': `bogus' +[[input.y:1.9-29: invalid value for %define variable `lr.default_reductions': `bogus' ]]) AT_CLEANUP diff --git a/tests/reduce.at b/tests/reduce.at index 6642f654..a3d1e27c 100644 --- a/tests/reduce.at +++ b/tests/reduce.at @@ -1442,33 +1442,33 @@ dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR -## -------------------------- ## -## %define lr.default_rules. ## -## -------------------------- ## +## ------------------------------- ## +## %define lr.default_reductions. ## +## ------------------------------- ## -# AT_TEST_LR_DEFAULT_RULES(GRAMMAR, INPUT, TABLES) -# ------------------------------------------------ -m4_define([AT_TEST_LR_DEFAULT_RULES], +# AT_TEST_LR_DEFAULT_REDUCTIONS(GRAMMAR, INPUT, TABLES) +# ----------------------------------------------------- +m4_define([AT_TEST_LR_DEFAULT_REDUCTIONS], [ -AT_TEST_TABLES_AND_PARSE([[no %define lr.default_rules]], +AT_TEST_TABLES_AND_PARSE([[no %define lr.default_reductions]], [[all]], [[]], [[]], [$1], [$2], [[]], [$3]) -AT_TEST_TABLES_AND_PARSE([[%define lr.default_rules "all"]], +AT_TEST_TABLES_AND_PARSE([[%define lr.default_reductions "all"]], [[all]], [[]], - [[%define lr.default_rules "all"]], + [[%define lr.default_reductions "all"]], [$1], [$2], [[]], [$3]) -AT_TEST_TABLES_AND_PARSE([[%define lr.default_rules "consistent"]], +AT_TEST_TABLES_AND_PARSE([[%define lr.default_reductions "consistent"]], [[consistent]], [[]], - [[%define lr.default_rules "consistent"]], + [[%define lr.default_reductions "consistent"]], [$1], [$2], [[]], [$3]) -AT_TEST_TABLES_AND_PARSE([[%define lr.default_rules "accepting"]], +AT_TEST_TABLES_AND_PARSE([[%define lr.default_reductions "accepting"]], [[accepting]], [[]], - [[%define lr.default_rules "accepting"]], + [[%define lr.default_reductions "accepting"]], [$1], [$2], [[]], [$3]) ]) -AT_TEST_LR_DEFAULT_RULES([[ +AT_TEST_LR_DEFAULT_REDUCTIONS([[ /* The start state is consistent and has a shift on 'a' and no reductions. After pushing the b below, enter an inconsistent state that has a shift and one reduction with one lookahead. */ @@ -1484,7 +1484,7 @@ a: 'a' ; /* After the previous reduction, enter an inconsistent state that has no shift and multiple reductions. The first reduction has more lookaheads than the - second, so the first should always be preferred as the default rule if + second, so the first should always be preferred as the default reduction if enabled. The second reduction has one lookahead. */ b: ; c: ; From 25029e164a3b2385ae6d95ca4cd19bad36550c92 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 24 Apr 2009 01:42:58 -0400 Subject: [PATCH 067/404] List accepted values for a %define enum variable with an invalid value. Suggested by Akim Demaille at . * data/bison.m4 (_b4_percent_define_check_values): Implement. * src/muscle_tab.c (muscle_percent_define_check_values): Implement. * tests/input.at (%define lr.default_reductions invalid values): Merge into... (%define enum variables): ... here, and update output. --- ChangeLog | 11 +++++++++++ data/bison.m4 | 6 +++++- src/muscle_tab.c | 35 ++++++++++++++++++++--------------- tests/input.at | 36 +++++++++++++++++------------------- 4 files changed, 53 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74169130..508c955e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-04-24 Joel E. Denny + + List accepted values for a %define enum variable with an invalid value. + Suggested by Akim Demaille at + . + * data/bison.m4 (_b4_percent_define_check_values): Implement. + * src/muscle_tab.c (muscle_percent_define_check_values): Implement. + * tests/input.at (%define lr.default_reductions invalid values): Merge + into... + (%define enum variables): ... here, and update output. + 2009-04-23 Joel E. Denny Rename "default rule" to "default reduction". diff --git a/data/bison.m4 b/data/bison.m4 index f9dd503d..00a42e21 100644 --- a/data/bison.m4 +++ b/data/bison.m4 @@ -499,7 +499,11 @@ m4_define([_b4_percent_define_check_values], [b4_complain_at(b4_percent_define_get_loc([$1]), [[invalid value for %%define variable `%s': `%s']], [$1], - m4_dquote(m4_indir([b4_percent_define(]$1[)])))])dnl + m4_dquote(m4_indir([b4_percent_define(]$1[)]))) + m4_foreach([b4_value], m4_dquote(m4_shift($@)), + [b4_complain_at(b4_percent_define_get_loc([$1]), + [[accepted value: `%s']], + m4_dquote(b4_value))])])dnl m4_popdef([b4_good_value])], [b4_fatal([[undefined %%define variable `%s' passed to b4_percent_define_check_values]], [$1])])]) diff --git a/src/muscle_tab.c b/src/muscle_tab.c index 0265e45a..8e2a3e2d 100644 --- a/src/muscle_tab.c +++ b/src/muscle_tab.c @@ -553,35 +553,40 @@ muscle_percent_define_check_values (char const * const *values) { for (; *values; ++values) { - char const *variable = *values; + char const * const *variablep = values; char const *name; char *value; - MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")"); + MUSCLE_USER_NAME_CONVERT (name, "percent_define(", *variablep, ")"); value = muscle_string_decode (name); if (value) { - bool valid = false; for (++values; *values; ++values) { if (0 == strcmp (value, *values)) - { - valid = true; - while (*values) - ++values; - break; - } + break; + } + if (!*values) + { + location loc = muscle_percent_define_get_loc (*variablep); + complain_at(loc, + _("invalid value for %%define variable `%s': `%s'"), + *variablep, value); + for (values = variablep + 1; *values; ++values) + complain_at (loc, _("accepted value: `%s'"), *values); + } + else + { + while (*values) + ++values; } - if (!valid) - complain_at(muscle_percent_define_get_loc (variable), - _("invalid value for %%define variable `%s': `%s'"), - variable, value); free (value); } else - fatal(_("undefined %%define variable `%s' passed to muscle_percent_define_check_values"), - variable); + fatal(_("undefined %%define variable `%s' passed to" + " muscle_percent_define_check_values"), + *variablep); } } diff --git a/tests/input.at b/tests/input.at index 9fa8af72..6c56e2fc 100644 --- a/tests/input.at +++ b/tests/input.at @@ -867,38 +867,36 @@ AT_BISON_CHECK([[Input.y]], [1], [], AT_CLEANUP -## ---------------------------------------------- ## -## %define lr.default_reductions invalid values. ## -## ---------------------------------------------- ## - -AT_SETUP([[%define lr.default_reductions invalid values]]) - -AT_DATA([[input.y]], -[[%define lr.default_reductions "bogus" -%% -start: ; -]]) - -AT_BISON_CHECK([[input.y]], [[1]], [[]], -[[input.y:1.9-29: invalid value for %define variable `lr.default_reductions': `bogus' -]]) - -AT_CLEANUP - ## ------------------------ ## ## %define enum variables. ## ## ------------------------ ## AT_SETUP([[%define enum variables]]) +# Front-end. +AT_DATA([[input.y]], +[[%define lr.default_reductions "bogus" +%% +start: ; +]]) +AT_BISON_CHECK([[input.y]], [[1]], [[]], +[[input.y:1.9-29: invalid value for %define variable `lr.default_reductions': `bogus' +input.y:1.9-29: accepted value: `all' +input.y:1.9-29: accepted value: `consistent' +input.y:1.9-29: accepted value: `accepting' +]]) + +# Back-end. AT_DATA([[input.y]], [[%define api.push_pull "neither" %% start: ; ]]) - AT_BISON_CHECK([[input.y]], [1], [], [[input.y:1.9-21: invalid value for %define variable `api.push_pull': `neither' +input.y:1.9-21: accepted value: `pull' +input.y:1.9-21: accepted value: `push' +input.y:1.9-21: accepted value: `both' ]]) AT_CLEANUP From 379261b3fd4e799c37bda6d354e7b8fe582357a6 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 24 Apr 2009 02:13:26 -0400 Subject: [PATCH 068/404] Clean up recent patches a little. Reported by Akim Demaille. * doc/bison.texinfo (Understanding): Fix typos. * src/print.c (print_reductions): Don't use negated variable. --- ChangeLog | 7 +++++++ doc/bison.texinfo | 4 ++-- src/print.c | 10 +++++----- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 508c955e..b42a91d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-04-24 Joel E. Denny + + Clean up recent patches a little. + Reported by Akim Demaille. + * doc/bison.texinfo (Understanding): Fix typos. + * src/print.c (print_reductions): Don't use negated variable. + 2009-04-24 Joel E. Denny List accepted values for a %define enum variable with an invalid value. diff --git a/doc/bison.texinfo b/doc/bison.texinfo index 8e3ca224..c52d7b8a 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -7355,8 +7355,8 @@ useless: STR; @command{bison} reports: @example -tmp.y: warning: 1 nonterminal useless in grammar -tmp.y: warning: 1 rule useless in grammar +calc.y: warning: 1 nonterminal useless in grammar +calc.y: warning: 1 rule useless in grammar calc.y:11.1-7: warning: nonterminal useless in grammar: useless calc.y:11.10-12: warning: rule useless in grammar: useless: STR calc.y: conflicts: 7 shift/reduce diff --git a/src/print.c b/src/print.c index 7fc577c4..e307329d 100644 --- a/src/print.c +++ b/src/print.c @@ -245,7 +245,7 @@ print_reductions (FILE *out, state *s) rule *default_reduction = NULL; size_t width = 0; int i, j; - bool non_default_action = false; + bool default_reduction_only = true; if (reds->num == 0) return; @@ -299,7 +299,7 @@ print_reductions (FILE *out, state *s) bool defaulted = false; bool count = bitset_test (no_reduce_set, i); if (count) - non_default_action = true; + default_reduction_only = false; for (j = 0; j < reds->num; ++j) if (bitset_test (reds->lookahead_tokens[j], i)) @@ -308,7 +308,7 @@ print_reductions (FILE *out, state *s) { if (reds->rules[j] != default_reduction) { - non_default_action = true; + default_reduction_only = false; print_reduction (out, width, symbols[i]->tag, reds->rules[j], true); @@ -319,7 +319,7 @@ print_reductions (FILE *out, state *s) } else { - non_default_action = true; + default_reduction_only = false; if (defaulted) print_reduction (out, width, symbols[i]->tag, @@ -339,7 +339,7 @@ print_reductions (FILE *out, state *s) print_reduction (out, width, _("$default"), default_reduction, true); aver (0 == strcmp (default_reductions, "all") || (0 == strcmp (default_reductions, "consistent") - && !non_default_action) + && default_reduction_only) || (reds->num == 1 && reds->rules[0]->number == 0)); free (default_reductions); } From 663ce7bb3e7e325eaa321f22509e6163f1bec4e2 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 20 Apr 2009 12:24:23 +0200 Subject: [PATCH 069/404] variables: accept dashes. * src/scan-gram.l ({id}): Also accept dashes after the initial letter. ({directive}): Use {id}. * src/parse-gram.y: Comment and formatting changes. * doc/bison.texinfo (Symbols): Adjust the lexical definitions of symbols. * src/complain.h, src/complain.c (yacc_at): New. * src/symtab.c (symbol_new): Use yacc_at to report inappropriate symbol names. * src/output.c (token_definitions_output): Do not #define token names with dashes. (cherry picked from commit 4f646c3794c45940aaf96d5409eff02a2c74978e) Conflicts: data/bison.m4 src/parse-gram.y --- ChangeLog | 15 +++++++++++++++ doc/bison.texinfo | 8 ++++++-- src/complain.c | 23 ++++++++++++++++++++++- src/complain.h | 9 ++++++++- src/output.c | 8 +++++--- src/parse-gram.c | 30 ++++++++++++++---------------- src/parse-gram.h | 2 +- src/parse-gram.y | 9 +++------ src/scan-gram.l | 6 +++--- src/symtab.c | 10 +++++++++- 10 files changed, 86 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index b42a91d0..69edc6bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2009-04-20 Akim Demaille + + variables: accept dashes. + * src/scan-gram.l ({id}): Also accept dashes after the initial + letter. + ({directive}): Use {id}. + * src/parse-gram.y: Comment and formatting changes. + * doc/bison.texinfo (Symbols): Adjust the lexical definitions of + symbols. + * src/complain.h, src/complain.c (yacc_at): New. + * src/symtab.c (symbol_new): Use yacc_at to report inappropriate + symbol names. + * src/output.c (token_definitions_output): Do not #define token + names with dashes. + 2009-04-24 Joel E. Denny Clean up recent patches a little. diff --git a/doc/bison.texinfo b/doc/bison.texinfo index c52d7b8a..46c95f01 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -3051,8 +3051,12 @@ A @dfn{nonterminal symbol} stands for a class of syntactically equivalent groupings. The symbol name is used in writing grammar rules. By convention, it should be all lower case. -Symbol names can contain letters, digits (not at the beginning), -underscores and periods. Periods make sense only in nonterminals. +Symbol names can contain letters, underscores, period, and (not at the +beginning) digits and dashes. Dashes in symbol names are a GNU +extension, incompatible with @acronym{POSIX} Yacc. Terminal symbols +that contain periods or dashes make little sense: since they are not +valid symbols (in most programming languages) they are not exported as +token names. There are three ways of writing terminal symbols in the grammar: diff --git a/src/complain.c b/src/complain.c index 2c26c4e4..4cc35c8a 100644 --- a/src/complain.c +++ b/src/complain.c @@ -1,6 +1,6 @@ /* Declaration for error-reporting function for Bison. - Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006 + Copyright (C) 2000, 2001, 2002, 2004, 2005, 2006, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -120,6 +120,27 @@ complain (const char *message, ...) } +/*--------------------------------------------------------------. +| An incompatibility with POSIX Yacc: mapped either to warn* or | +| complain* depending on yacc_flag. | +`--------------------------------------------------------------*/ + +void +yacc_at (location loc, const char *message, ...) +{ + if (yacc_flag) + { + ERROR_MESSAGE (&loc, NULL, message); + complaint_issued = true; + } + else if (warnings_flag & warnings_yacc) + { + set_warning_issued (); + ERROR_MESSAGE (&loc, _("warning"), message); + } +} + + /*-------------------------------------------------. | A severe error has occurred, we cannot proceed. | `-------------------------------------------------*/ diff --git a/src/complain.h b/src/complain.h index a633613c..89cdd91d 100644 --- a/src/complain.h +++ b/src/complain.h @@ -1,5 +1,5 @@ /* Declaration for error-reporting function for Bison. - Copyright (C) 2000, 2001, 2002, 2006 Free Software Foundation, Inc. + Copyright (C) 2000, 2001, 2002, 2006, 2009 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 @@ -39,6 +39,13 @@ void complain (char const *format, ...) void complain_at (location loc, char const *format, ...) __attribute__ ((__format__ (__printf__, 2, 3))); +/** An incompatibility with POSIX Yacc: mapped either to warn* or + complain* depending on yacc_flag. */ + +void yacc_at (location loc, char const *format, ...) + __attribute__ ((__format__ (__printf__, 2, 3))); + + /** A fatal error, causing immediate exit. */ void fatal (char const *format, ...) diff --git a/src/output.c b/src/output.c index f7251473..e299230b 100644 --- a/src/output.c +++ b/src/output.c @@ -363,9 +363,11 @@ token_definitions_output (FILE *out) if (sym->tag[0] == '\'' || sym->tag[0] == '\"') continue; - /* Don't #define nonliteral tokens whose names contain periods - or '$' (as does the default value of the EOF token). */ - if (strchr (sym->tag, '.') || strchr (sym->tag, '$')) + /* Don't #define nonliteral tokens whose names contain periods, + dashes or '$' (as does the default value of the EOF token). */ + if (strchr (sym->tag, '.') + || strchr (sym->tag, '-') + || strchr (sym->tag, '$')) continue; fprintf (out, "%s[[[%s]], %d]", diff --git a/src/parse-gram.c b/src/parse-gram.c index acae131b..38e64d61 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 2.4.1.49-783b. */ +/* A Bison parser, made by GNU Bison 2.4.1.52-77be. */ /* Skeleton implementation for Bison's Yacc-like parsers in C @@ -45,7 +45,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.4.1.49-783b" +#define YYBISON_VERSION "2.4.1.52-77be" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -672,8 +672,8 @@ static const yytype_uint16 yyrline[] = 434, 435, 440, 442, 447, 448, 452, 453, 454, 455, 460, 465, 470, 476, 482, 493, 494, 503, 504, 510, 511, 512, 519, 519, 523, 524, 525, 530, 531, 533, - 535, 537, 539, 549, 550, 556, 559, 568, 588, 590, - 599, 604, 605, 610, 617, 619 + 535, 537, 539, 549, 550, 555, 556, 565, 585, 587, + 596, 601, 602, 607, 614, 616 }; #endif @@ -2551,16 +2551,14 @@ yyreduce: case 95: /* Line 1456 of yacc.c */ -#line 556 "parse-gram.y" - { - (yyval.chars) = ""; - } +#line 555 "parse-gram.y" + { (yyval.chars) = ""; } break; case 97: /* Line 1456 of yacc.c */ -#line 569 "parse-gram.y" +#line 566 "parse-gram.y" { code_props plain_code; (yyvsp[(1) - (1)].code)[strlen ((yyvsp[(1) - (1)].code)) - 1] = '\n'; @@ -2574,14 +2572,14 @@ yyreduce: case 98: /* Line 1456 of yacc.c */ -#line 589 "parse-gram.y" +#line 586 "parse-gram.y" { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 99: /* Line 1456 of yacc.c */ -#line 591 "parse-gram.y" +#line 588 "parse-gram.y" { (yyval.symbol) = symbol_get (char_name ((yyvsp[(1) - (1)].character)), (yylsp[(1) - (1)])); symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false); @@ -2592,14 +2590,14 @@ yyreduce: case 100: /* Line 1456 of yacc.c */ -#line 599 "parse-gram.y" +#line 596 "parse-gram.y" { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 103: /* Line 1456 of yacc.c */ -#line 611 "parse-gram.y" +#line 608 "parse-gram.y" { (yyval.symbol) = symbol_get (quotearg_style (c_quoting_style, (yyvsp[(1) - (1)].chars)), (yylsp[(1) - (1)])); symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false); @@ -2609,7 +2607,7 @@ yyreduce: case 105: /* Line 1456 of yacc.c */ -#line 620 "parse-gram.y" +#line 617 "parse-gram.y" { code_props plain_code; code_props_plain_init (&plain_code, (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)])); @@ -2623,7 +2621,7 @@ yyreduce: /* Line 1456 of yacc.c */ -#line 2627 "parse-gram.c" +#line 2625 "parse-gram.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2842,7 +2840,7 @@ yyreturn: /* Line 1676 of yacc.c */ -#line 630 "parse-gram.y" +#line 627 "parse-gram.y" diff --git a/src/parse-gram.h b/src/parse-gram.h index ae82cd45..fecb9199 100644 --- a/src/parse-gram.h +++ b/src/parse-gram.h @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 2.4.1.49-783b. */ +/* A Bison parser, made by GNU Bison 2.4.1.52-77be. */ /* Skeleton interface for Bison's Yacc-like parsers in C diff --git a/src/parse-gram.y b/src/parse-gram.y index 83b02e36..2e4168b7 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -547,15 +547,12 @@ rhs: variable: ID - | STRING { $$ = uniqstr_new ($1); } /* deprecated and not M4-friendly */ - ; +| STRING { $$ = uniqstr_new ($1); } +; /* Some content or empty by default. */ content.opt: - /* Nothing. */ - { - $$ = ""; - } + /* Nothing. */ { $$ = ""; } | STRING ; diff --git a/src/scan-gram.l b/src/scan-gram.l index 292960cb..2ef4eb3b 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -90,8 +90,8 @@ static void unexpected_newline (boundary, char const *); %x SC_STRING SC_CHARACTER letter [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] -id {letter}({letter}|[0-9])* -directive %{letter}({letter}|[0-9]|-)* +id {letter}({letter}|[0-9]|-)* +directive %{id} int [0-9]+ /* POSIX says that a tag must be both an id and a C union member, but @@ -382,7 +382,7 @@ splice (\\[ \f\t\v]*\n)* unexpected_eof (token_start, "'"); STRING_FINISH; loc->start = token_start; - if (strlen(last_string) > 1) + if (strlen (last_string) > 1) val->character = last_string[1]; else val->character = last_string[0]; diff --git a/src/symtab.c b/src/symtab.c index 1db83f63..f9560efa 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -1,6 +1,7 @@ /* Symbol table manager for Bison. - Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008 + Copyright (C) 1984, 1989, 2000, 2001, 2002, 2004, 2005, 2006, 2007, + 2008, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -58,6 +59,13 @@ symbol_new (uniqstr tag, location loc) symbol *res = xmalloc (sizeof *res); uniqstr_assert (tag); + + /* If the tag is not a string (starts with a double quote), check + that it is valid for Yacc. */ + if (tag[0] != '\"' && tag[0] != '\'' && strchr (tag, '-')) + yacc_at (loc, _("POSIX Yacc forbids dashes in symbol names: %s"), + tag); + res->tag = tag; res->location = loc; From 6789b8bd7b11e8f28923bac273e85a7375e80f8b Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Wed, 29 Apr 2009 20:03:52 -0400 Subject: [PATCH 070/404] Add copyright updates missed during previous cherry pick. * src/output.c: Here. * src/parse-gram.y: Here. * src/scan-gram.l: Here. --- ChangeLog | 7 +++++++ src/output.c | 2 +- src/parse-gram.y | 4 ++-- src/scan-gram.l | 4 ++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 69edc6bd..0bbcc426 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-04-24 Joel E. Denny + + Add copyright updates missed during previous cherry pick. + * src/output.c: Here. + * src/parse-gram.y: Here. + * src/scan-gram.l: Here. + 2009-04-20 Akim Demaille variables: accept dashes. diff --git a/src/output.c b/src/output.c index e299230b..d5e30b8a 100644 --- a/src/output.c +++ b/src/output.c @@ -1,7 +1,7 @@ /* Output the generated parsing program for Bison. Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. diff --git a/src/parse-gram.y b/src/parse-gram.y index 2e4168b7..5bf66949 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -1,7 +1,7 @@ %{/* Bison Grammar Parser -*- C -*- - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software - Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free + Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. diff --git a/src/scan-gram.l b/src/scan-gram.l index 2ef4eb3b..c29e167d 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -1,7 +1,7 @@ /* Bison Grammar Scanner -*- C -*- - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software - Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free + Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. From ae618dcca57abb16ad4e5e11083480ecdcfc511f Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Wed, 29 Apr 2009 20:05:32 -0400 Subject: [PATCH 071/404] Document how `%define "var" "value"' is not M4-friendly. * src/parse-gram.y (variable): In comments here. --- ChangeLog | 5 +++++ src/parse-gram.c | 26 +++++++++++++------------- src/parse-gram.y | 2 ++ 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0bbcc426..9c0502c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-04-24 Joel E. Denny + + Document how `%define "var" "value"' is not M4-friendly. + * src/parse-gram.y (variable): In comments here. + 2009-04-24 Joel E. Denny Add copyright updates missed during previous cherry pick. diff --git a/src/parse-gram.c b/src/parse-gram.c index 38e64d61..23f388b7 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -78,8 +78,8 @@ #line 1 "parse-gram.y" /* Bison Grammar Parser -*- C -*- - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software - Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free + Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -672,8 +672,8 @@ static const yytype_uint16 yyrline[] = 434, 435, 440, 442, 447, 448, 452, 453, 454, 455, 460, 465, 470, 476, 482, 493, 494, 503, 504, 510, 511, 512, 519, 519, 523, 524, 525, 530, 531, 533, - 535, 537, 539, 549, 550, 555, 556, 565, 585, 587, - 596, 601, 602, 607, 614, 616 + 535, 537, 539, 551, 552, 557, 558, 567, 587, 589, + 598, 603, 604, 609, 616, 618 }; #endif @@ -2544,21 +2544,21 @@ yyreduce: case 94: /* Line 1456 of yacc.c */ -#line 550 "parse-gram.y" +#line 552 "parse-gram.y" { (yyval.uniqstr) = uniqstr_new ((yyvsp[(1) - (1)].chars)); } break; case 95: /* Line 1456 of yacc.c */ -#line 555 "parse-gram.y" +#line 557 "parse-gram.y" { (yyval.chars) = ""; } break; case 97: /* Line 1456 of yacc.c */ -#line 566 "parse-gram.y" +#line 568 "parse-gram.y" { code_props plain_code; (yyvsp[(1) - (1)].code)[strlen ((yyvsp[(1) - (1)].code)) - 1] = '\n'; @@ -2572,14 +2572,14 @@ yyreduce: case 98: /* Line 1456 of yacc.c */ -#line 586 "parse-gram.y" +#line 588 "parse-gram.y" { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 99: /* Line 1456 of yacc.c */ -#line 588 "parse-gram.y" +#line 590 "parse-gram.y" { (yyval.symbol) = symbol_get (char_name ((yyvsp[(1) - (1)].character)), (yylsp[(1) - (1)])); symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false); @@ -2590,14 +2590,14 @@ yyreduce: case 100: /* Line 1456 of yacc.c */ -#line 596 "parse-gram.y" +#line 598 "parse-gram.y" { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 103: /* Line 1456 of yacc.c */ -#line 608 "parse-gram.y" +#line 610 "parse-gram.y" { (yyval.symbol) = symbol_get (quotearg_style (c_quoting_style, (yyvsp[(1) - (1)].chars)), (yylsp[(1) - (1)])); symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false); @@ -2607,7 +2607,7 @@ yyreduce: case 105: /* Line 1456 of yacc.c */ -#line 617 "parse-gram.y" +#line 619 "parse-gram.y" { code_props plain_code; code_props_plain_init (&plain_code, (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)])); @@ -2840,7 +2840,7 @@ yyreturn: /* Line 1676 of yacc.c */ -#line 627 "parse-gram.y" +#line 629 "parse-gram.y" diff --git a/src/parse-gram.y b/src/parse-gram.y index 5bf66949..5af473c7 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -545,6 +545,8 @@ rhs: | variable and content.opt. | *---------------------------*/ +/* The STRING form of variable is deprecated and is not M4-friendly. + For example, M4 fails for `%define "[" "value"'. */ variable: ID | STRING { $$ = uniqstr_new ($1); } From 0939aa2d3cc35de2143a0027e32297a40f895219 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 21 Apr 2009 22:17:25 +0200 Subject: [PATCH 072/404] tests: check the use of dashes and periods in symbols. * tests/input.at (Symbol): New test group. (cherry picked from commit 746ee38c7cff93ad1fc97da6f06f124f394fb437) --- ChangeLog | 5 +++++ tests/input.at | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9c0502c0..d7324eec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-04-21 Akim Demaille + + tests: check the use of dashes and periods in symbols. + * tests/input.at (Symbol): New test group. + 2009-04-24 Joel E. Denny Document how `%define "var" "value"' is not M4-friendly. diff --git a/tests/input.at b/tests/input.at index 6c56e2fc..05ded403 100644 --- a/tests/input.at +++ b/tests/input.at @@ -615,6 +615,65 @@ AT_BISON_CHECK([-o input.c input.y]) AT_CLEANUP +## -------------- ## +## Symbol names. ## +## -------------- ## + +AT_SETUP([Symbols]) + +# Bison once thought a character token and its alias were different +# symbols with the same user token number. + +AT_DATA_GRAMMAR([input.y], +[[%token WITH-DASH +%token WITHOUT_DASH "WITHOUT-DASH" +%token WITH.PERIOD +%token WITHOUT_PERIOD "WITHOUT.PERIOD" +%% +start: with-dash without_dash with.period without_period; +with-dash: WITH-DASH; +without_dash: "WITHOUT-DASH"; +with.period: WITH.PERIOD; +without_period: "WITHOUT.PERIOD"; +%% +]]) + +# POSIX Yacc accept periods, but not dashes. +AT_BISON_CHECK([--yacc input.y], [1], [], +[[input.y:9.8-16: POSIX Yacc forbids dashes in symbol names: WITH-DASH +input.y:14.8-16: POSIX Yacc forbids dashes in symbol names: with-dash +]]) + +# So warn about them. +AT_BISON_CHECK([-Wyacc input.y], [], [], +[[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: WITH-DASH +input.y:14.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash +]]) + +# Dashes are fine for GNU Bison. +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]) + + +# Period are genuine letters, they can start identifiers. Dashes +# and digits can't. +AT_DATA_GRAMMAR([input.y], +[[%token .good +%token -wrong +%token 1nv4l1d +%% +start: .good +]]) +AT_BISON_CHECK([-o input.c input.y], [1], [], +[[input.y:10.8: invalid character: `-' +input.y:11.8: syntax error, unexpected integer, expecting char or identifier or type +]]) + +AT_CLEANUP + + ## --------------------- ## ## Unclosed constructs. ## ## --------------------- ## From 0b59345789e88b34ec7e3a68b99d6fbd368cb798 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Wed, 29 Apr 2009 20:50:01 -0400 Subject: [PATCH 073/404] Pacify ./configure --enable-gcc-warnings. * tests/input.at (Symbols): Prototype yyerror and yylex. --- ChangeLog | 9 +++++++-- tests/input.at | 8 ++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index d7324eec..be1c8a34 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,14 +1,19 @@ +2009-04-29 Joel E. Denny + + Pacify ./configure --enable-gcc-warnings. + * tests/input.at (Symbols): Prototype yyerror and yylex. + 2009-04-21 Akim Demaille tests: check the use of dashes and periods in symbols. * tests/input.at (Symbol): New test group. -2009-04-24 Joel E. Denny +2009-04-29 Joel E. Denny Document how `%define "var" "value"' is not M4-friendly. * src/parse-gram.y (variable): In comments here. -2009-04-24 Joel E. Denny +2009-04-29 Joel E. Denny Add copyright updates missed during previous cherry pick. * src/output.c: Here. diff --git a/tests/input.at b/tests/input.at index 05ded403..96ba0fc0 100644 --- a/tests/input.at +++ b/tests/input.at @@ -629,6 +629,10 @@ AT_DATA_GRAMMAR([input.y], %token WITHOUT_DASH "WITHOUT-DASH" %token WITH.PERIOD %token WITHOUT_PERIOD "WITHOUT.PERIOD" +%code { + void yyerror (char const *); + int yylex (void); +} %% start: with-dash without_dash with.period without_period; with-dash: WITH-DASH; @@ -641,13 +645,13 @@ without_period: "WITHOUT.PERIOD"; # POSIX Yacc accept periods, but not dashes. AT_BISON_CHECK([--yacc input.y], [1], [], [[input.y:9.8-16: POSIX Yacc forbids dashes in symbol names: WITH-DASH -input.y:14.8-16: POSIX Yacc forbids dashes in symbol names: with-dash +input.y:18.8-16: POSIX Yacc forbids dashes in symbol names: with-dash ]]) # So warn about them. AT_BISON_CHECK([-Wyacc input.y], [], [], [[input.y:9.8-16: warning: POSIX Yacc forbids dashes in symbol names: WITH-DASH -input.y:14.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash +input.y:18.8-16: warning: POSIX Yacc forbids dashes in symbol names: with-dash ]]) # Dashes are fine for GNU Bison. From 1d0f55cc843d6dfca01e2c13fd49ee2c119c6631 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Wed, 29 Apr 2009 21:48:21 -0400 Subject: [PATCH 074/404] Rename lr.default_reductions to lr.default-reductions. * NEWS (2.5): Here. * doc/bison.texinfo: Here. * src/lalr.c (initialize_LA): Here. * src/print.c (print_reductions): Here. * src/reader.c (reader): Here. * src/tables.c (action_row): Here. * tests/input.at (%define enum variables): Here. * tests/reduce.at (AT_TEST_LR_DEFAULT_REDUCTIONS): Here. --- ChangeLog | 12 ++++++++++++ NEWS | 4 ++-- doc/bison.texinfo | 10 +++++----- src/lalr.c | 2 +- src/print.c | 2 +- src/reader.c | 6 +++--- src/tables.c | 2 +- tests/input.at | 4 ++-- tests/reduce.at | 16 ++++++++-------- 9 files changed, 35 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index be1c8a34..af426e5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2009-04-29 Joel E. Denny + + Rename lr.default_reductions to lr.default-reductions. + * NEWS (2.5): Here. + * doc/bison.texinfo: Here. + * src/lalr.c (initialize_LA): Here. + * src/print.c (print_reductions): Here. + * src/reader.c (reader): Here. + * src/tables.c (action_row): Here. + * tests/input.at (%define enum variables): Here. + * tests/reduce.at (AT_TEST_LR_DEFAULT_REDUCTIONS): Here. + 2009-04-29 Joel E. Denny Pacify ./configure --enable-gcc-warnings. diff --git a/NEWS b/NEWS index 92a935fb..80b49da6 100644 --- a/NEWS +++ b/NEWS @@ -25,8 +25,8 @@ Bison News %define lr.type "canonical LR" The default reduction optimization in the parser tables can also be - adjusted using `%define lr.default_reductions'. See the documentation - for `%define lr.type' and `%define lr.default_reductions' in the + adjusted using `%define lr.default-reductions'. See the documentation + for `%define lr.type' and `%define lr.default-reductions' in the section `Bison Declaration Summary' in the Bison manual for the details. diff --git a/doc/bison.texinfo b/doc/bison.texinfo index 46c95f01..a81f9cf8 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -4903,9 +4903,9 @@ More user feedback will help to stabilize it.) @item Default Value: @code{"pull"} @end itemize -@item lr.default_reductions +@item lr.default-reductions @cindex default reductions -@findex %define lr.default_reductions +@findex %define lr.default-reductions @cindex delayed syntax errors @cindex syntax errors delayed @@ -5080,7 +5080,7 @@ syntactically acceptable in that left context. Thus, the only difference in parsing behavior is that the canonical @acronym{LR} parser can report a syntax error as soon as possible without performing any unnecessary reductions. -@xref{Decl Summary,,lr.default_reductions}, for further details. +@xref{Decl Summary,,lr.default-reductions}, for further details. Even when canonical @acronym{LR} behavior is ultimately desired, @acronym{IELR}'s elimination of duplicate conflicts should still facilitate the development of a grammar. @@ -10346,7 +10346,7 @@ committee document contributing to what became the Algol 60 report. @item Consistent State A state containing only one possible action. -@xref{Decl Summary,,lr.default_reductions}. +@xref{Decl Summary,,lr.default-reductions}. @item Context-free grammars Grammars specified as rules that can be applied regardless of context. @@ -10361,7 +10361,7 @@ contains no other action for the lookahead token. In permitted parser states, Bison declares the reduction with the largest lookahead set to be the default reduction and removes that lookahead set. -@xref{Decl Summary,,lr.default_reductions}. +@xref{Decl Summary,,lr.default-reductions}. @item Dynamic allocation Allocation of memory that occurs during execution, rather than at diff --git a/src/lalr.c b/src/lalr.c index a3a31b23..4aa05b9e 100644 --- a/src/lalr.c +++ b/src/lalr.c @@ -372,7 +372,7 @@ initialize_LA (void) bool default_reduction_only_for_accept; { char *default_reductions = - muscle_percent_define_get ("lr.default_reductions"); + muscle_percent_define_get ("lr.default-reductions"); default_reduction_only_for_accept = 0 == strcmp (default_reductions, "accepting"); free (default_reductions); diff --git a/src/print.c b/src/print.c index e307329d..b4256576 100644 --- a/src/print.c +++ b/src/print.c @@ -335,7 +335,7 @@ print_reductions (FILE *out, state *s) if (default_reduction) { char *default_reductions = - muscle_percent_define_get ("lr.default_reductions"); + muscle_percent_define_get ("lr.default-reductions"); print_reduction (out, width, _("$default"), default_reduction, true); aver (0 == strcmp (default_reductions, "all") || (0 == strcmp (default_reductions, "consistent") diff --git a/src/reader.c b/src/reader.c index 17ff0f78..76e379fa 100644 --- a/src/reader.c +++ b/src/reader.c @@ -561,9 +561,9 @@ reader (void) muscle_percent_define_default ("lr.type", "LALR"); lr_type = muscle_percent_define_get ("lr.type"); if (0 != strcmp (lr_type, "canonical LR")) - muscle_percent_define_default ("lr.default_reductions", "all"); + muscle_percent_define_default ("lr.default-reductions", "all"); else - muscle_percent_define_default ("lr.default_reductions", "accepting"); + muscle_percent_define_default ("lr.default-reductions", "accepting"); free (lr_type); } @@ -571,7 +571,7 @@ reader (void) { static char const * const values[] = { "lr.type", "LALR", "IELR", "canonical LR", NULL, - "lr.default_reductions", "all", "consistent", "accepting", NULL, + "lr.default-reductions", "all", "consistent", "accepting", NULL, NULL }; muscle_percent_define_check_values (values); diff --git a/src/tables.c b/src/tables.c index 186c1fec..8704f105 100644 --- a/src/tables.c +++ b/src/tables.c @@ -309,7 +309,7 @@ action_row (state *s) labeled as consistent. */ { char *default_reductions = - muscle_percent_define_get ("lr.default_reductions"); + muscle_percent_define_get ("lr.default-reductions"); if (0 != strcmp (default_reductions, "all") && !s->consistent) nodefault = true; free (default_reductions); diff --git a/tests/input.at b/tests/input.at index 96ba0fc0..b1f5f0a3 100644 --- a/tests/input.at +++ b/tests/input.at @@ -938,12 +938,12 @@ AT_SETUP([[%define enum variables]]) # Front-end. AT_DATA([[input.y]], -[[%define lr.default_reductions "bogus" +[[%define lr.default-reductions "bogus" %% start: ; ]]) AT_BISON_CHECK([[input.y]], [[1]], [[]], -[[input.y:1.9-29: invalid value for %define variable `lr.default_reductions': `bogus' +[[input.y:1.9-29: invalid value for %define variable `lr.default-reductions': `bogus' input.y:1.9-29: accepted value: `all' input.y:1.9-29: accepted value: `consistent' input.y:1.9-29: accepted value: `accepting' diff --git a/tests/reduce.at b/tests/reduce.at index a3d1e27c..af13e16f 100644 --- a/tests/reduce.at +++ b/tests/reduce.at @@ -1443,28 +1443,28 @@ dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR ## ------------------------------- ## -## %define lr.default_reductions. ## +## %define lr.default-reductions. ## ## ------------------------------- ## # AT_TEST_LR_DEFAULT_REDUCTIONS(GRAMMAR, INPUT, TABLES) # ----------------------------------------------------- m4_define([AT_TEST_LR_DEFAULT_REDUCTIONS], [ -AT_TEST_TABLES_AND_PARSE([[no %define lr.default_reductions]], +AT_TEST_TABLES_AND_PARSE([[no %define lr.default-reductions]], [[all]], [[]], [[]], [$1], [$2], [[]], [$3]) -AT_TEST_TABLES_AND_PARSE([[%define lr.default_reductions "all"]], +AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions "all"]], [[all]], [[]], - [[%define lr.default_reductions "all"]], + [[%define lr.default-reductions "all"]], [$1], [$2], [[]], [$3]) -AT_TEST_TABLES_AND_PARSE([[%define lr.default_reductions "consistent"]], +AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions "consistent"]], [[consistent]], [[]], - [[%define lr.default_reductions "consistent"]], + [[%define lr.default-reductions "consistent"]], [$1], [$2], [[]], [$3]) -AT_TEST_TABLES_AND_PARSE([[%define lr.default_reductions "accepting"]], +AT_TEST_TABLES_AND_PARSE([[%define lr.default-reductions "accepting"]], [[accepting]], [[]], - [[%define lr.default_reductions "accepting"]], + [[%define lr.default-reductions "accepting"]], [$1], [$2], [[]], [$3]) ]) From 1c4aa81df1fd11e2be5b2af78b4375f85bb2e59e Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Thu, 30 Apr 2009 00:31:12 -0400 Subject: [PATCH 075/404] Set all front-end %define defaults in one place. * src/main.c (main): Move lr.keep_unreachable_states default... * src/reader.c (reader): ... to here. --- ChangeLog | 6 ++++++ src/main.c | 1 - src/reader.c | 7 +++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index af426e5c..9551184b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-04-30 Joel E. Denny + + Set all front-end %define defaults in one place. + * src/main.c (main): Move lr.keep_unreachable_states default... + * src/reader.c (reader): ... to here. + 2009-04-29 Joel E. Denny Rename lr.default_reductions to lr.default-reductions. diff --git a/src/main.c b/src/main.c index 6c93a4ef..5769693e 100644 --- a/src/main.c +++ b/src/main.c @@ -114,7 +114,6 @@ main (int argc, char *argv[]) declarations. */ timevar_push (TV_CONFLICTS); conflicts_solve (); - muscle_percent_define_default ("lr.keep_unreachable_states", "false"); if (!muscle_percent_define_flag_if ("lr.keep_unreachable_states")) { state_number *old_to_new = xnmalloc (nstates, sizeof *old_to_new); diff --git a/src/reader.c b/src/reader.c index 76e379fa..2f3cd824 100644 --- a/src/reader.c +++ b/src/reader.c @@ -555,9 +555,12 @@ reader (void) gram_scanner_initialize (); gram_parse (); - /* IELR would be a better default, but LALR is historically the default. */ + /* Set front-end %define variable defaults. */ + muscle_percent_define_default ("lr.keep_unreachable_states", "false"); { char *lr_type; + /* IELR would be a better default, but LALR is historically the + default. */ muscle_percent_define_default ("lr.type", "LALR"); lr_type = muscle_percent_define_get ("lr.type"); if (0 != strcmp (lr_type, "canonical LR")) @@ -567,7 +570,7 @@ reader (void) free (lr_type); } - /* Check front-end %define variable values. */ + /* Check front-end %define variables. */ { static char const * const values[] = { "lr.type", "LALR", "IELR", "canonical LR", NULL, From 812775a0391e122eff1983afea2da96c600c7307 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Thu, 30 Apr 2009 01:04:33 -0400 Subject: [PATCH 076/404] Convert underscores to dashes in some %define variable names. For now, just api.push-pull and lr.keep-unreachable-states. Maintain old names for backward compatibility. * NEWS (2.5): Document. * data/c.m4 (b4_identification): Update comment. * data/yacc.c: Update access. * doc/bison.texinfo: Update. * etc/bench.pl.in (bench_grammar): Update use. * src/files.c (tr): Move to... * src/getargs.c, src/getargs.h (tr): ... here because I can't think of a better place to expose it. My logic is that, for all uses of tr so far, command-line arguments can be involved, and getargs.h is already included. * src/main.c (main): Update access. * src/muscle_tab.c (muscle_percent_define_insert): Convert old variable names to new variable names before assigning value. * src/reader.c (reader): Update setting default. * tests/calc.at: Update uses. * tests/conflicts.at (Unreachable States After Conflict Resolution): Update use. * tests/input.at (%define enum variables): Update use. (%define backward compatibility): New test group. * tests/push.at: Update uses. * tests/reduce.at: Update uses. * tests/torture.at: Update uses. --- ChangeLog | 28 ++++++++++++++++++++++++++++ NEWS | 15 +++++++++++++++ data/c.m4 | 4 ++-- data/yacc.c | 8 ++++---- doc/bison.texinfo | 42 +++++++++++++++++++++--------------------- etc/bench.pl.in | 6 +++--- src/files.c | 11 +---------- src/getargs.c | 8 ++++++++ src/getargs.h | 3 +++ src/main.c | 2 +- src/muscle_tab.c | 12 ++++++++++++ src/parse-gram.c | 4 ++-- src/parse-gram.h | 2 +- src/reader.c | 2 +- tests/calc.at | 8 ++++---- tests/conflicts.at | 5 +++-- tests/input.at | 43 ++++++++++++++++++++++++++++++++++++++++++- tests/push.at | 10 +++++----- tests/reduce.at | 8 ++++---- tests/torture.at | 8 ++++---- 20 files changed, 164 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9551184b..8a782624 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2009-04-30 Joel E. Denny + + Convert underscores to dashes in some %define variable names. + For now, just api.push-pull and lr.keep-unreachable-states. + Maintain old names for backward compatibility. + * NEWS (2.5): Document. + * data/c.m4 (b4_identification): Update comment. + * data/yacc.c: Update access. + * doc/bison.texinfo: Update. + * etc/bench.pl.in (bench_grammar): Update use. + * src/files.c (tr): Move to... + * src/getargs.c, src/getargs.h (tr): ... here because I can't + think of a better place to expose it. My logic is that, for all + uses of tr so far, command-line arguments can be involved, and + getargs.h is already included. + * src/main.c (main): Update access. + * src/muscle_tab.c (muscle_percent_define_insert): Convert old + variable names to new variable names before assigning value. + * src/reader.c (reader): Update setting default. + * tests/calc.at: Update uses. + * tests/conflicts.at (Unreachable States After Conflict + Resolution): Update use. + * tests/input.at (%define enum variables): Update use. + (%define backward compatibility): New test group. + * tests/push.at: Update uses. + * tests/reduce.at: Update uses. + * tests/torture.at: Update uses. + 2009-04-30 Joel E. Denny Set all front-end %define defaults in one place. diff --git a/NEWS b/NEWS index 80b49da6..edb16109 100644 --- a/NEWS +++ b/NEWS @@ -47,6 +47,21 @@ Bison News for any NAME and VALUE. Omitting `=VALUE' on the command line is equivalent to omitting `"VALUE"' in the declaration. +** %define variables renamed. + + The following %define variables + + api.push_pull + lr.keep_unreachable_states + + have been renamed to + + api.push-pull + lr.keep-unreachable-states + + The old names are now deprecated but will be maintained indefinitely + for backward compatibility. + ** Temporary hack for adding a semicolon to the user action. Previously, Bison appended a semicolon to every user action for diff --git a/data/c.m4 b/data/c.m4 index 1fe4bc56..39b6e58e 100644 --- a/data/c.m4 +++ b/data/c.m4 @@ -1,7 +1,7 @@ -*- Autoconf -*- # C M4 Macros for Bison. -# Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008 Free Software +# Copyright (C) 2002, 2004, 2005, 2006, 2007, 2008, 2009 Free Software # Foundation, Inc. # This program is free software: you can redistribute it and/or modify @@ -31,7 +31,7 @@ m4_define([b4_comment], [/* m4_bpatsubst([$1], [ # ----------------- # Depends on individual skeletons to define b4_pure_flag, b4_push_flag, or # b4_pull_flag if they use the values of the %define variables api.pure or -# api.push_pull. +# api.push-pull. m4_define([b4_identification], [[/* Identify Bison output. */ #define YYBISON 1 diff --git a/data/yacc.c b/data/yacc.c index 3c7c602f..76a1baa4 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -18,13 +18,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# Check the value of %define api.push_pull. -b4_percent_define_default([[api.push_pull]], [[pull]]) -b4_percent_define_check_values([[[[api.push_pull]], +# Check the value of %define api.push-pull. +b4_percent_define_default([[api.push-pull]], [[pull]]) +b4_percent_define_check_values([[[[api.push-pull]], [[pull]], [[push]], [[both]]]]) b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]]) b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]]) -m4_case(b4_percent_define_get([[api.push_pull]]), +m4_case(b4_percent_define_get([[api.push-pull]]), [pull], [m4_define([b4_push_flag], [[0]])], [push], [m4_define([b4_pull_flag], [[0]])]) diff --git a/doc/bison.texinfo b/doc/bison.texinfo index a81f9cf8..99cd38ff 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -4561,7 +4561,7 @@ valid grammar. @subsection A Push Parser @cindex push parser @cindex push parser -@findex %define api.push_pull +@findex %define api.push-pull (The current push parsing interface is experimental and may evolve. More user feedback will help to stabilize it.) @@ -4577,10 +4577,10 @@ within a certain time period. Normally, Bison generates a pull parser. The following Bison declaration says that you want the parser to be a push -parser (@pxref{Decl Summary,,%define api.push_pull}): +parser (@pxref{Decl Summary,,%define api.push-pull}): @example -%define api.push_pull "push" +%define api.push-pull "push" @end example In almost all cases, you want to ensure that your push parser is also @@ -4591,7 +4591,7 @@ what you are doing, your declarations should look like this: @example %define api.pure -%define api.push_pull "push" +%define api.push-pull "push" @end example There is a major notable functional difference between the pure push parser @@ -4640,14 +4640,14 @@ for use by the next invocation of the @code{yypush_parse} function. Bison also supports both the push parser interface along with the pull parser interface in the same generated parser. In order to get this functionality, -you should replace the @code{%define api.push_pull "push"} declaration with the -@code{%define api.push_pull "both"} declaration. Doing this will create all of +you should replace the @code{%define api.push-pull "push"} declaration with the +@code{%define api.push-pull "both"} declaration. Doing this will create all of the symbols mentioned earlier along with the two extra symbols, @code{yyparse} and @code{yypull_parse}. @code{yyparse} can be used exactly as it normally would be used. However, the user should note that it is implemented in the generated parser by calling @code{yypull_parse}. This makes the @code{yyparse} function that is generated with the -@code{%define api.push_pull "both"} declaration slower than the normal +@code{%define api.push-pull "both"} declaration slower than the normal @code{yyparse} function. If the user calls the @code{yypull_parse} function it will parse the rest of the input stream. It is possible to @code{yypush_parse} tokens to select a subgrammar @@ -4664,8 +4664,8 @@ yypstate_delete (ps); @end example Adding the @code{%define api.pure} declaration does exactly the same thing to -the generated parser with @code{%define api.push_pull "both"} as it did for -@code{%define api.push_pull "push"}. +the generated parser with @code{%define api.push-pull "both"} as it did for +@code{%define api.push-pull "push"}. @node Decl Summary @subsection Bison Declaration Summary @@ -4887,8 +4887,8 @@ Some of the accepted @var{variable}s are: @item Default Value: @code{"false"} @end itemize -@item api.push_pull -@findex %define api.push_pull +@item api.push-pull +@findex %define api.push-pull @itemize @bullet @item Language(s): C (deterministic parsers only) @@ -4968,8 +4968,8 @@ without performing any extra reductions. @end itemize @end itemize -@item lr.keep_unreachable_states -@findex %define lr.keep_unreachable_states +@item lr.keep-unreachable-states +@findex %define lr.keep-unreachable-states @itemize @bullet @item Language(s): all @@ -5467,8 +5467,8 @@ exp: @dots{} @{ @dots{}; *randomness += 1; @dots{} @} More user feedback will help to stabilize it.) You call the function @code{yypush_parse} to parse a single token. This -function is available if either the @code{%define api.push_pull "push"} or -@code{%define api.push_pull "both"} declaration is used. +function is available if either the @code{%define api.push-pull "push"} or +@code{%define api.push-pull "both"} declaration is used. @xref{Push Decl, ,A Push Parser}. @deftypefun int yypush_parse (yypstate *yyps) @@ -5485,7 +5485,7 @@ is required to finish parsing the grammar. More user feedback will help to stabilize it.) You call the function @code{yypull_parse} to parse the rest of the input -stream. This function is available if the @code{%define api.push_pull "both"} +stream. This function is available if the @code{%define api.push-pull "both"} declaration is used. @xref{Push Decl, ,A Push Parser}. @@ -5501,8 +5501,8 @@ The value returned by @code{yypull_parse} is the same as for @code{yyparse}. More user feedback will help to stabilize it.) You call the function @code{yypstate_new} to create a new parser instance. -This function is available if either the @code{%define api.push_pull "push"} or -@code{%define api.push_pull "both"} declaration is used. +This function is available if either the @code{%define api.push-pull "push"} or +@code{%define api.push-pull "both"} declaration is used. @xref{Push Decl, ,A Push Parser}. @deftypefun yypstate *yypstate_new (void) @@ -5520,8 +5520,8 @@ allocated. More user feedback will help to stabilize it.) You call the function @code{yypstate_delete} to delete a parser instance. -function is available if either the @code{%define api.push_pull "push"} or -@code{%define api.push_pull "both"} declaration is used. +function is available if either the @code{%define api.push-pull "push"} or +@code{%define api.push-pull "both"} declaration is used. @xref{Push Decl, ,A Push Parser}. @deftypefun void yypstate_delete (yypstate *yyps) @@ -8929,7 +8929,7 @@ and @code{%define api.pure} directives does not do anything when used in Java. Push parsers are currently unsupported in Java and @code{%define -api.push_pull} have no effect. +api.push-pull} have no effect. @acronym{GLR} parsers are currently unsupported in Java. Do not use the @code{glr-parser} directive. diff --git a/etc/bench.pl.in b/etc/bench.pl.in index ca433493..f36691fe 100755 --- a/etc/bench.pl.in +++ b/etc/bench.pl.in @@ -1,6 +1,6 @@ #! /usr/bin/perl -w -# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is part of Bison, the GNU Compiler Compiler. # @@ -343,8 +343,8 @@ sub bench_grammar ($) ( "pull-impure" => '', "pull-pure" => '%define api.pure', - "push-impure" => '%define api.push_pull "both"', - "push-pure" => '%define api.push_pull "both" %define api.pure', + "push-impure" => '%define api.push-pull "both"', + "push-pure" => '%define api.push-pull "both" %define api.pure', ); my %bench; diff --git a/src/files.c b/src/files.c index 07f761b4..41e2453b 100644 --- a/src/files.c +++ b/src/files.c @@ -1,7 +1,7 @@ /* Open and close files for Bison. Copyright (C) 1984, 1986, 1989, 1992, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -136,15 +136,6 @@ xfclose (FILE *ptr) | Compute ALL_BUT_EXT, ALL_BUT_TAB_EXT and output files extensions. | `------------------------------------------------------------------*/ -/* In the string S, replace all characters FROM by TO. */ -static void -tr (char *s, char from, char to) -{ - for (; *s; s++) - if (*s == from) - *s = to; -} - /* Compute extensions from the grammar file extension. */ static void compute_exts_from_gf (const char *ext) diff --git a/src/getargs.c b/src/getargs.c index 2f2e9005..962dad4d 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -663,3 +663,11 @@ getargs (int argc, char *argv[]) current_file = grammar_file = uniqstr_new (argv[optind]); MUSCLE_INSERT_C_STRING ("file_name", grammar_file); } + +void +tr (char *s, char from, char to) +{ + for (; *s; s++) + if (*s == from) + *s = to; +} diff --git a/src/getargs.h b/src/getargs.h index d9d95202..b3a2a9b2 100644 --- a/src/getargs.h +++ b/src/getargs.h @@ -140,4 +140,7 @@ void getargs (int argc, char *argv[]); void language_argmatch (char const *arg, int prio, location loc); void skeleton_arg (const char *arg, int prio, location loc); +/** In the string \c s, replace all characters \c from by \c to. */ +void tr (char *s, char from, char to); + #endif /* !GETARGS_H_ */ diff --git a/src/main.c b/src/main.c index 5769693e..c80ed870 100644 --- a/src/main.c +++ b/src/main.c @@ -114,7 +114,7 @@ main (int argc, char *argv[]) declarations. */ timevar_push (TV_CONFLICTS); conflicts_solve (); - if (!muscle_percent_define_flag_if ("lr.keep_unreachable_states")) + if (!muscle_percent_define_flag_if ("lr.keep-unreachable-states")) { state_number *old_to_new = xnmalloc (nstates, sizeof *old_to_new); state_number nstates_old = nstates; diff --git a/src/muscle_tab.c b/src/muscle_tab.c index 8e2a3e2d..764ea93e 100644 --- a/src/muscle_tab.c +++ b/src/muscle_tab.c @@ -403,10 +403,20 @@ void muscle_percent_define_insert (char const *variable, location variable_loc, char const *value) { + char *variable_tr = NULL; char const *name; char const *loc_name; char const *syncline_name; + /* Permit certain names with underscores for backward compatibility. */ + if (0 == strcmp (variable, "api.push_pull") + || 0 == strcmp (variable, "lr.keep_unreachable_states")) + { + variable_tr = strdup (variable); + tr (variable_tr, '_', '-'); + variable = variable_tr; + } + MUSCLE_USER_NAME_CONVERT (name, "percent_define(", variable, ")"); MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")"); MUSCLE_USER_NAME_CONVERT (syncline_name, @@ -427,6 +437,8 @@ muscle_percent_define_insert (char const *variable, location variable_loc, muscle_syncline_grow (syncline_name, variable_loc); muscle_user_name_list_grow ("percent_define_user_variables", variable, variable_loc); + + free (variable_tr); } char * diff --git a/src/parse-gram.c b/src/parse-gram.c index 23f388b7..c167f481 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 2.4.1.52-77be. */ +/* A Bison parser, made by GNU Bison 2.4.1.57-1d0f-dirty. */ /* Skeleton implementation for Bison's Yacc-like parsers in C @@ -45,7 +45,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.4.1.52-77be" +#define YYBISON_VERSION "2.4.1.57-1d0f-dirty" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" diff --git a/src/parse-gram.h b/src/parse-gram.h index fecb9199..a17d93d7 100644 --- a/src/parse-gram.h +++ b/src/parse-gram.h @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 2.4.1.52-77be. */ +/* A Bison parser, made by GNU Bison 2.4.1.57-1d0f-dirty. */ /* Skeleton interface for Bison's Yacc-like parsers in C diff --git a/src/reader.c b/src/reader.c index 2f3cd824..c542a5cd 100644 --- a/src/reader.c +++ b/src/reader.c @@ -556,7 +556,7 @@ reader (void) gram_parse (); /* Set front-end %define variable defaults. */ - muscle_percent_define_default ("lr.keep_unreachable_states", "false"); + muscle_percent_define_default ("lr.keep-unreachable-states", "false"); { char *lr_type; /* IELR would be a better default, but LALR is historically the diff --git a/tests/calc.at b/tests/calc.at index 5f118580..802d4830 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -1,7 +1,7 @@ # Simple calculator. -*- Autotest -*- -# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free -# Software Foundation, Inc. +# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +# 2009 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 @@ -576,7 +576,7 @@ AT_CHECK_CALC_LALR([%yacc]) AT_CHECK_CALC_LALR([%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([%define api.push-pull "both" %define api.pure %locations]) AT_CHECK_CALC_LALR([%error-verbose %locations]) AT_CHECK_CALC_LALR([%error-verbose %locations %defines %name-prefix "calc" %verbose %yacc]) @@ -585,7 +585,7 @@ AT_CHECK_CALC_LALR([%debug]) AT_CHECK_CALC_LALR([%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.push-pull "both" %define api.pure %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}]) diff --git a/tests/conflicts.at b/tests/conflicts.at index 866b9441..78a90ad0 100644 --- a/tests/conflicts.at +++ b/tests/conflicts.at @@ -1,6 +1,7 @@ # Exercising Bison on conflicts. -*- Autotest -*- -# Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2004, 2005, 2007, 2009 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 @@ -813,7 +814,7 @@ state 7 ]]) AT_DATA([[input-keep.y]], -[[%define lr.keep_unreachable_states +[[%define lr.keep-unreachable-states ]]) AT_CHECK([[cat input.y >> input-keep.y]]) diff --git a/tests/input.at b/tests/input.at index b1f5f0a3..73bf7345 100644 --- a/tests/input.at +++ b/tests/input.at @@ -950,18 +950,59 @@ input.y:1.9-29: accepted value: `accepting' ]]) # Back-end. +AT_DATA([[input.y]], +[[%define api.push-pull "neither" +%% +start: ; +]]) +AT_BISON_CHECK([[input.y]], [1], [], +[[input.y:1.9-21: invalid value for %define variable `api.push-pull': `neither' +input.y:1.9-21: accepted value: `pull' +input.y:1.9-21: accepted value: `push' +input.y:1.9-21: accepted value: `both' +]]) + +AT_CLEANUP + +## -------------------------------- ## +## %define backward compatibility. ## +## -------------------------------- ## + +AT_SETUP([[%define backward compatibility]]) + +# The error messages tell us whether underscores in these variables are +# being converted to dashes. + AT_DATA([[input.y]], [[%define api.push_pull "neither" %% start: ; ]]) AT_BISON_CHECK([[input.y]], [1], [], -[[input.y:1.9-21: invalid value for %define variable `api.push_pull': `neither' +[[input.y:1.9-21: invalid value for %define variable `api.push-pull': `neither' input.y:1.9-21: accepted value: `pull' input.y:1.9-21: accepted value: `push' input.y:1.9-21: accepted value: `both' ]]) +AT_DATA([[input.y]], +[[%define lr.keep_unreachable_states "maybe" +%% +start: ; +]]) +AT_BISON_CHECK([[input.y]], [1], [], +[[input.y:1.9-34: invalid value for %define Boolean variable `lr.keep-unreachable-states' +]]) + +AT_DATA([[input.y]], +[[%define foo_bar "baz" +%% +start: ; +]]) +AT_BISON_CHECK([[input.y]], [0], [], +[[input.y:1.9-15: warning: %define variable `foo_bar' is not used +]]) + AT_CLEANUP ## ------------------------- ## diff --git a/tests/push.at b/tests/push.at index 70c1fdce..bf48c682 100644 --- a/tests/push.at +++ b/tests/push.at @@ -1,5 +1,5 @@ # Checking Push Parsing. -*- Autotest -*- -# Copyright (C) 2007 Free Software Foundation, Inc. +# Copyright (C) 2007, 2009 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 @@ -33,7 +33,7 @@ AT_DATA_GRAMMAR([[input.y]], void yyerror (char const *msg); %} -%define api.pure %define api.push_pull "push" +%define api.pure %define api.push-pull "push" %% @@ -93,7 +93,7 @@ AT_DATA_GRAMMAR([[input.y]], int yylex (void); %} -%define api.push_pull "]$1[" +%define api.push-pull "]$1[" %% @@ -156,13 +156,13 @@ AT_SETUP([[Push Parsing: Unsupported Skeletons]]) AT_DATA([[input.y]], [[%glr-parser -%define api.push_pull "push" +%define api.push-pull "push" %% start: ; ]]) AT_BISON_CHECK([[input.y]], [0], [], -[[input.y:2.9-21: warning: %define variable `api.push_pull' is not used +[[input.y:2.9-21: warning: %define variable `api.push-pull' is not used ]]) AT_CLEANUP diff --git a/tests/reduce.at b/tests/reduce.at index af13e16f..0db3830b 100644 --- a/tests/reduce.at +++ b/tests/reduce.at @@ -396,7 +396,7 @@ AT_TEST_LR_TYPE([[Single State Split]], [[%left 'a' // Conflict resolution renders state 12 unreachable for canonical LR(1). We // keep it so that the paser table diff is easier to code. -%define lr.keep_unreachable_states]], +%define lr.keep-unreachable-states]], [[ S: 'a' A 'a' /* rule 1 */ | 'b' A 'b' /* rule 2 */ @@ -629,7 +629,7 @@ AT_TEST_LR_TYPE([[Lane Split]], [[%left 'a' // Conflict resolution renders state 16 unreachable for canonical LR(1). We // keep it so that the paser table diff is easier to code. -%define lr.keep_unreachable_states]], +%define lr.keep-unreachable-states]], [[ /* Similar to the last test case set but two states must be split. */ S: 'a' A 'a' /* rule 1 */ @@ -873,7 +873,7 @@ AT_TEST_LR_TYPE([[Complex Lane Split]], [[%left 'a' // Conflict resolution renders state 16 unreachable for canonical LR(1). We // keep it so that the paser table diff is easier to code. -%define lr.keep_unreachable_states]], +%define lr.keep-unreachable-states]], [[ /* Similar to the last test case set but forseeing the S/R conflict from the first state that must be split is becoming difficult. Imagine if B were @@ -1139,7 +1139,7 @@ dnl PARSER-EXIT-VALUE, PARSER-STDOUT, PARSER-STDERR ]])]) AT_TEST_LR_TYPE([[Split During Added Lookahead Propagation]], -[[%define lr.keep_unreachable_states]], +[[%define lr.keep-unreachable-states]], [[ /* The partial state chart diagram below is for LALR(1). State 0 is the start state. States are iterated for successor construction in numerical order. diff --git a/tests/torture.at b/tests/torture.at index 753fc919..91b3b1b9 100644 --- a/tests/torture.at +++ b/tests/torture.at @@ -1,6 +1,6 @@ # Torturing Bison. -*- Autotest -*- -# Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007 Free Software Foundation, -# Inc. +# Copyright (C) 2001, 2002, 2004, 2005, 2006, 2007, 2009 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 @@ -496,7 +496,7 @@ AT_PARSER_CHECK([./input 10000], 2, [], [ignore], # just helps guarantee we don't let the YYSTACK_USE_ALLOCA feature affect # push parsers. AT_DATA_STACK_TORTURE([AT_USE_ALLOCA], -[[%define api.push_pull "both" +[[%define api.push-pull "both" ]]) AT_PARSER_CHECK([./input 20], 0, [], [ignore], [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]]) @@ -534,7 +534,7 @@ AT_PARSER_CHECK([./input 10000], 2, [], [ignore], [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]]) AT_DATA_STACK_TORTURE([AT_USE_ALLOCA], -[[%define api.push_pull "both" +[[%define api.push-pull "both" ]]) AT_PARSER_CHECK([./input 20], 0, [], [ignore], [[VALGRIND_OPTS="$VALGRIND_OPTS --log-fd=1"]]) From 966aba6583640869f5a0ab4a9ffc60dd40fd7406 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 1 May 2009 02:51:31 -0400 Subject: [PATCH 077/404] Declare %code to be a permanent feature. * NEWS (2.4.2): Here. * doc/bison.texinfo (Prologue Alternatives): Don't say it's experimental. (Decl Summary): Likewise. (cherry picked from commit cefb18280b83ea19b742a22f7be8661b518874b5) --- ChangeLog | 8 ++++++++ NEWS | 23 +++++++++++++++++++++++ doc/bison.texinfo | 11 ----------- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8a782624..90c44b64 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-05-01 Joel E. Denny + + Declare %code to be a permanent feature. + * NEWS (2.4.2): Here. + * doc/bison.texinfo (Prologue Alternatives): Don't say it's + experimental. + (Decl Summary): Likewise. + 2009-04-30 Joel E. Denny Convert underscores to dashes in some %define variable names. diff --git a/NEWS b/NEWS index edb16109..b3ba74fa 100644 --- a/NEWS +++ b/NEWS @@ -85,6 +85,29 @@ Bison News * Changes in version 2.4.2 (????-??-??): +** %code is now a permanent feature. + + A traditional Yacc prologue directive is written in the form: + + %{CODE%} + + To provide a more flexible alternative, Bison 2.3b introduced the + %code directive with the following forms for C/C++: + + %code {CODE} + %code requires {CODE} + %code provides {CODE} + %code top {CODE} + + These forms are now considered permanent features of Bison. See the + %code entries in the section "Bison Declaration Summary" in the Bison + manual for a summary of their functionality. See the section + "Prologue Alternatives" for a detailed discussion including the + advantages of %code over the traditional Yacc prologue directive. + + Bison's Java feature as a whole including its current usage of %code + is still considered experimental. + * Changes in version 2.4.1 (2008-12-11): ** In the GLR defines file, unexpanded M4 macros in the yylval and yylloc diff --git a/doc/bison.texinfo b/doc/bison.texinfo index 99cd38ff..a02d0760 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -2704,9 +2704,6 @@ feature test macros can affect the behavior of Bison-generated @findex %code requires @findex %code provides @findex %code top -(The prologue alternatives described here are experimental. -More user feedback will help to determine whether they should become permanent -features.) The functionality of @var{Prologue} sections can often be subtle and inflexible. @@ -4745,10 +4742,6 @@ Thus, @code{%code} replaces the traditional Yacc prologue, For a detailed discussion, see @ref{Prologue Alternatives}. For Java, the default location is inside the parser class. - -(Like all the Yacc prologue alternatives, this directive is experimental. -More user feedback will help to determine whether it should become a permanent -feature.) @end deffn @deffn {Directive} %code @var{qualifier} @{@var{code}@} @@ -4826,10 +4819,6 @@ before any class definitions. @end itemize @end itemize -(Like all the Yacc prologue alternatives, this directive is experimental. -More user feedback will help to determine whether it should become a permanent -feature.) - @cindex Prologue For a detailed discussion of how to use @code{%code} in place of the traditional Yacc prologue for C/C++, see @ref{Prologue Alternatives}. From c046698e6e98aefa7f234b8035fe4cf20ce5d05d Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 4 May 2009 21:15:17 +0200 Subject: [PATCH 078/404] identifiers: dashes are letters. Dashes can now start identifiers (symbols and directives). * src/scan-gram.l ({letter}): Add dash. ({id}): Remove it. * tests/input.at (Symbols): Adjust. Remove stray comment. * tests/regression.at (Invalid inputs): Adjust error message. * doc/bison.texinfo (Symbols): Update. --- ChangeLog | 12 ++++++++++++ NEWS | 8 ++++++++ doc/bison.texinfo | 10 +++++----- src/scan-gram.l | 4 ++-- tests/input.at | 18 +++++++----------- tests/regression.at | 5 ++--- 6 files changed, 36 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 90c44b64..bdf9789f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2009-05-04 Akim Demaille + + identifiers: dashes are letters. + Dashes can now start identifiers (symbols and directives). + + * src/scan-gram.l ({letter}): Add dash. + ({id}): Remove it. + * tests/input.at (Symbols): Adjust. + Remove stray comment. + * tests/regression.at (Invalid inputs): Adjust error message. + * doc/bison.texinfo (Symbols): Update. + 2009-05-01 Joel E. Denny Declare %code to be a permanent feature. diff --git a/NEWS b/NEWS index b3ba74fa..65781606 100644 --- a/NEWS +++ b/NEWS @@ -62,6 +62,14 @@ Bison News The old names are now deprecated but will be maintained indefinitely for backward compatibility. +** Symbols names + + Consistently with directives (such as %error-verbose) and variables + (e.g. push-pull), symbol names may include dashes in any position, + similarly to periods and underscores. This is GNU extension over + POSIX Yacc whose use is reported by -Wyacc, and rejected in Yacc + mode (--yacc). + ** Temporary hack for adding a semicolon to the user action. Previously, Bison appended a semicolon to every user action for diff --git a/doc/bison.texinfo b/doc/bison.texinfo index a02d0760..9b600785 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -3048,8 +3048,8 @@ A @dfn{nonterminal symbol} stands for a class of syntactically equivalent groupings. The symbol name is used in writing grammar rules. By convention, it should be all lower case. -Symbol names can contain letters, underscores, period, and (not at the -beginning) digits and dashes. Dashes in symbol names are a GNU +Symbol names can contain letters, underscores, periods, dashes, and (not +at the beginning) digits. Dashes in symbol names are a GNU extension, incompatible with @acronym{POSIX} Yacc. Terminal symbols that contain periods or dashes make little sense: since they are not valid symbols (in most programming languages) they are not exported as @@ -9008,7 +9008,7 @@ The first, inclusive, position of the range, and the first beyond. @end deftypeivar @deftypeop {Constructor} {Location} {} Location (Position @var{loc}) -Create a @code{Location} denoting an empty range located at a given point. +Create a @code{Location} denoting an empty range located at a given point. @end deftypeop @deftypeop {Constructor} {Location} {} Location (Position @var{begin}, Position @var{end}) @@ -9222,12 +9222,12 @@ Return immediately from the parser, indicating success. @end deffn @deffn {Statement} {return YYERROR;} -Start error recovery without printing an error message. +Start error recovery without printing an error message. @xref{Error Recovery}. @end deffn @deffn {Statement} {return YYFAIL;} -Print an error message and start error recovery. +Print an error message and start error recovery. @xref{Error Recovery}. @end deffn diff --git a/src/scan-gram.l b/src/scan-gram.l index c29e167d..b37b29b0 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -89,8 +89,8 @@ static void unexpected_newline (boundary, char const *); /* Strings and characters in code. */ %x SC_STRING SC_CHARACTER -letter [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] -id {letter}({letter}|[0-9]|-)* +letter [-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] +id {letter}({letter}|[0-9])* directive %{id} int [0-9]+ diff --git a/tests/input.at b/tests/input.at index 73bf7345..7eaafaae 100644 --- a/tests/input.at +++ b/tests/input.at @@ -621,9 +621,6 @@ AT_CLEANUP AT_SETUP([Symbols]) -# Bison once thought a character token and its alias were different -# symbols with the same user token number. - AT_DATA_GRAMMAR([input.y], [[%token WITH-DASH %token WITHOUT_DASH "WITHOUT-DASH" @@ -661,18 +658,17 @@ AT_BISON_CHECK([-o input.c input.y]) AT_COMPILE([input.o], [-c input.c]) -# Period are genuine letters, they can start identifiers. Dashes -# and digits can't. +# Periods and dashes are genuine letters, they can start identifiers. +# Digits cannot. AT_DATA_GRAMMAR([input.y], -[[%token .good -%token -wrong -%token 1nv4l1d +[[%token .GOOD +%token -GOOD +%token 1NV4L1D %% -start: .good +start: .GOOD -GOOD ]]) AT_BISON_CHECK([-o input.c input.y], [1], [], -[[input.y:10.8: invalid character: `-' -input.y:11.8: syntax error, unexpected integer, expecting char or identifier or type +[[input.y:11.8: syntax error, unexpected integer, expecting char or identifier or type ]]) AT_CLEANUP diff --git a/tests/regression.at b/tests/regression.at index 32e676c6..cb9cd9a4 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -1,6 +1,6 @@ # Bison Regressions. -*- Autotest -*- -# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software # Foundation, Inc. # This program is free software: you can redistribute it and/or modify @@ -393,8 +393,7 @@ input.y:3.14: invalid character: `}' input.y:4.1: invalid character: `%' input.y:4.2: invalid character: `&' input.y:5.1-17: invalid directive: `%a-does-not-exist' -input.y:6.1: invalid character: `%' -input.y:6.2: invalid character: `-' +input.y:6.1-2: invalid directive: `%-' input.y:7.1-8.0: missing `%}' at end of file input.y:7.1-8.0: syntax error, unexpected %{...%} ]]) From 43e6aea52686b0be3083c5b3c5657a06a79d22ef Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 4 May 2009 21:15:52 +0200 Subject: [PATCH 079/404] space changes. * src/scan-gram.l: Untabify to be robust to zealous editors. --- ChangeLog | 5 ++++ src/scan-gram.l | 80 ++++++++++++++++++++++++------------------------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index bdf9789f..ae38cf3e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-05-04 Akim Demaille + + space changes. + * src/scan-gram.l: Untabify to be robust to zealous editors. + 2009-05-04 Akim Demaille identifiers: dashes are letters. diff --git a/src/scan-gram.l b/src/scan-gram.l index b37b29b0..9bf156b2 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -161,48 +161,48 @@ splice (\\[ \f\t\v]*\n)* { - "%binary" return PERCENT_NONASSOC; + "%binary" return PERCENT_NONASSOC; "%code" return PERCENT_CODE; - "%debug" return PERCENT_DEBUG; - "%default"[-_]"prec" return PERCENT_DEFAULT_PREC; - "%define" return PERCENT_DEFINE; - "%defines" return PERCENT_DEFINES; - "%destructor" return PERCENT_DESTRUCTOR; - "%dprec" return PERCENT_DPREC; - "%error"[-_]"verbose" return PERCENT_ERROR_VERBOSE; - "%expect" return PERCENT_EXPECT; - "%expect"[-_]"rr" return PERCENT_EXPECT_RR; - "%file-prefix" return PERCENT_FILE_PREFIX; + "%debug" return PERCENT_DEBUG; + "%default"[-_]"prec" return PERCENT_DEFAULT_PREC; + "%define" return PERCENT_DEFINE; + "%defines" return PERCENT_DEFINES; + "%destructor" return PERCENT_DESTRUCTOR; + "%dprec" return PERCENT_DPREC; + "%error"[-_]"verbose" return PERCENT_ERROR_VERBOSE; + "%expect" return PERCENT_EXPECT; + "%expect"[-_]"rr" return PERCENT_EXPECT_RR; + "%file-prefix" return PERCENT_FILE_PREFIX; "%fixed"[-_]"output"[-_]"files" return PERCENT_YACC; - "%initial-action" return PERCENT_INITIAL_ACTION; - "%glr-parser" return PERCENT_GLR_PARSER; - "%language" return PERCENT_LANGUAGE; - "%left" return PERCENT_LEFT; - "%lex-param" return PERCENT_LEX_PARAM; - "%locations" return PERCENT_LOCATIONS; - "%merge" return PERCENT_MERGE; - "%name"[-_]"prefix" return PERCENT_NAME_PREFIX; - "%no"[-_]"default"[-_]"prec" return PERCENT_NO_DEFAULT_PREC; - "%no"[-_]"lines" return PERCENT_NO_LINES; - "%nonassoc" return PERCENT_NONASSOC; - "%nondeterministic-parser" return PERCENT_NONDETERMINISTIC_PARSER; - "%nterm" return PERCENT_NTERM; - "%output" return PERCENT_OUTPUT; - "%parse-param" return PERCENT_PARSE_PARAM; - "%prec" return PERCENT_PREC; - "%printer" return PERCENT_PRINTER; - "%pure"[-_]"parser" return PERCENT_PURE_PARSER; - "%require" return PERCENT_REQUIRE; - "%right" return PERCENT_RIGHT; - "%skeleton" return PERCENT_SKELETON; - "%start" return PERCENT_START; - "%term" return PERCENT_TOKEN; - "%token" return PERCENT_TOKEN; - "%token"[-_]"table" return PERCENT_TOKEN_TABLE; - "%type" return PERCENT_TYPE; - "%union" return PERCENT_UNION; - "%verbose" return PERCENT_VERBOSE; - "%yacc" return PERCENT_YACC; + "%initial-action" return PERCENT_INITIAL_ACTION; + "%glr-parser" return PERCENT_GLR_PARSER; + "%language" return PERCENT_LANGUAGE; + "%left" return PERCENT_LEFT; + "%lex-param" return PERCENT_LEX_PARAM; + "%locations" return PERCENT_LOCATIONS; + "%merge" return PERCENT_MERGE; + "%name"[-_]"prefix" return PERCENT_NAME_PREFIX; + "%no"[-_]"default"[-_]"prec" return PERCENT_NO_DEFAULT_PREC; + "%no"[-_]"lines" return PERCENT_NO_LINES; + "%nonassoc" return PERCENT_NONASSOC; + "%nondeterministic-parser" return PERCENT_NONDETERMINISTIC_PARSER; + "%nterm" return PERCENT_NTERM; + "%output" return PERCENT_OUTPUT; + "%parse-param" return PERCENT_PARSE_PARAM; + "%prec" return PERCENT_PREC; + "%printer" return PERCENT_PRINTER; + "%pure"[-_]"parser" return PERCENT_PURE_PARSER; + "%require" return PERCENT_REQUIRE; + "%right" return PERCENT_RIGHT; + "%skeleton" return PERCENT_SKELETON; + "%start" return PERCENT_START; + "%term" return PERCENT_TOKEN; + "%token" return PERCENT_TOKEN; + "%token"[-_]"table" return PERCENT_TOKEN_TABLE; + "%type" return PERCENT_TYPE; + "%union" return PERCENT_UNION; + "%verbose" return PERCENT_VERBOSE; + "%yacc" return PERCENT_YACC; {directive} { complain_at (*loc, _("invalid directive: %s"), quote (yytext)); From ecdfea9a128a309e27a8ffb50da3a1ddd13387d2 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 4 May 2009 21:23:55 +0200 Subject: [PATCH 080/404] bison: catch bad symbol names. * src/scan-gram.l({int}{id}): Report as an invalid identifier. * tests/input.at: Adjust. --- ChangeLog | 6 ++++++ src/scan-gram.l | 6 ++++++ tests/input.at | 6 +++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ae38cf3e..db56d974 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-05-04 Akim Demaille + + bison: catch bad symbol names. + * src/scan-gram.l({int}{id}): Report as an invalid identifier. + * tests/input.at: Adjust. + 2009-05-04 Akim Demaille space changes. diff --git a/src/scan-gram.l b/src/scan-gram.l index 9bf156b2..a22cafdc 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -208,6 +208,12 @@ splice (\\[ \f\t\v]*\n)* complain_at (*loc, _("invalid directive: %s"), quote (yytext)); } + /* Identifiers may not start with a digit. Yet, don't silently + accept "1FOO" as "1 FOO". */ + {int}{id} { + complain_at (*loc, _("invalid identifier: %s"), quote (yytext)); + } + "=" return EQUAL; "|" return PIPE; ";" return SEMICOLON; diff --git a/tests/input.at b/tests/input.at index 7eaafaae..4345eddd 100644 --- a/tests/input.at +++ b/tests/input.at @@ -662,13 +662,13 @@ AT_COMPILE([input.o], [-c input.c]) # Digits cannot. AT_DATA_GRAMMAR([input.y], [[%token .GOOD -%token -GOOD -%token 1NV4L1D + -GOOD + 1NV4L1D %% start: .GOOD -GOOD ]]) AT_BISON_CHECK([-o input.c input.y], [1], [], -[[input.y:11.8: syntax error, unexpected integer, expecting char or identifier or type +[[input.y:11.10-16: invalid identifier: `1NV4L1D' ]]) AT_CLEANUP From d19123e612529ad3670b91f0764b7c9122789ae8 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 5 May 2009 09:35:34 +0200 Subject: [PATCH 081/404] tests: check token numbers. * tests/input.at (Numbered tokens): New. --- ChangeLog | 5 +++++ tests/input.at | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/ChangeLog b/ChangeLog index db56d974..ba901d60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-05-05 Akim Demaille + + tests: check token numbers. + * tests/input.at (Numbered tokens): New. + 2009-05-04 Akim Demaille bison: catch bad symbol names. diff --git a/tests/input.at b/tests/input.at index 4345eddd..1eaf4821 100644 --- a/tests/input.at +++ b/tests/input.at @@ -674,6 +674,43 @@ AT_BISON_CHECK([-o input.c input.y], [1], [], AT_CLEANUP +## ----------------- ## +## Numbered tokens. ## +## ----------------- ## + +AT_SETUP([Numbered tokens]) + +AT_DATA_GRAMMAR([input.y], +[[%token HEXADECIMAL_1 0xabcdef + DECIMAL_1 11259375 +%token HEXADECIMAL_2 0XFEDCBA + DECIMAL_2 16702650 +%% +start: HEXADECIMAL_1 HEXADECIMAL_2 +%% +]]) + +AT_BISON_CHECK([input.y], [1], [], +[[input.y:12.12-20: tokens HEXADECIMAL_2 and DECIMAL_2 both assigned number 16702650 +input.y:9.8-20: tokens DECIMAL_1 and HEXADECIMAL_1 both assigned number 11259375 +]]) + +AT_DATA_GRAMMAR([input.y], +[[%token TOO_LARGE_DEC 999999999999999999999 + TOO_LARGE_HEX 0xFFFFFFFFFFFFFFFFFFF +%% +start: TOO_LARGE_DEC TOO_LARGE_HEX +%% +]]) + +AT_BISON_CHECK([input.y], [1], [], +[[input.y:9.22-42: integer out of range: `999999999999999999999' +input.y:10.24-44: integer out of range: `0xFFFFFFFFFFFFFFFFFFF' +]]) + +AT_CLEANUP + + ## --------------------- ## ## Unclosed constructs. ## ## --------------------- ## From 601bdfabe277f58ffaa6280cbea06259edacef09 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 5 May 2009 09:36:06 +0200 Subject: [PATCH 082/404] fix hexadecimal token number support. * src/scan-gram.l: Catch incorrect ids after hexadecimal numbers. --- ChangeLog | 5 +++++ src/scan-gram.l | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index ba901d60..cac83fd3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2009-05-05 Akim Demaille + + fix hexadecimal token number support. + * src/scan-gram.l: Catch incorrect ids after hexadecimal numbers. + 2009-05-05 Akim Demaille tests: check token numbers. diff --git a/src/scan-gram.l b/src/scan-gram.l index a22cafdc..c8c9771c 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -208,12 +208,6 @@ splice (\\[ \f\t\v]*\n)* complain_at (*loc, _("invalid directive: %s"), quote (yytext)); } - /* Identifiers may not start with a digit. Yet, don't silently - accept "1FOO" as "1 FOO". */ - {int}{id} { - complain_at (*loc, _("invalid identifier: %s"), quote (yytext)); - } - "=" return EQUAL; "|" return PIPE; ";" return SEMICOLON; @@ -235,6 +229,12 @@ splice (\\[ \f\t\v]*\n)* return INT; } + /* Identifiers may not start with a digit. Yet, don't silently + accept "1FOO" as "1 FOO". */ + {int}{id} { + complain_at (*loc, _("invalid identifier: %s"), quote (yytext)); + } + /* Characters. We don't check there is only one. */ "'" STRING_GROW; token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER; From b10dd689b645f4f62d616cb9fbc14f416e8e06bd Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 7 May 2009 23:18:44 +0200 Subject: [PATCH 083/404] doc: use C++ headers. * doc/bison.texinfo (Calc++ Scanner): Prefer C++ headers to C headers. --- ChangeLog | 8 +++++++- doc/bison.texinfo | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index cac83fd3..30d09f38 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,12 @@ tests: check token numbers. * tests/input.at (Numbered tokens): New. +2009-05-11 Akim Demaille + + doc: use C++ headers. + * doc/bison.texinfo (Calc++ Scanner): Prefer C++ headers to C + headers. + 2009-05-04 Akim Demaille bison: catch bad symbol names. @@ -23,7 +29,7 @@ identifiers: dashes are letters. Dashes can now start identifiers (symbols and directives). - + * src/scan-gram.l ({letter}): Add dash. ({id}): Remove it. * tests/input.at (Symbols): Adjust. diff --git a/doc/bison.texinfo b/doc/bison.texinfo index 9b600785..1a66edc4 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -8735,8 +8735,8 @@ parser's to get the set of defined tokens. @example %@{ /* -*- C++ -*- */ # include -# include -# include +# include +# include # include # include "calc++-driver.hh" # include "calc++-parser.hh" From 7ac45a46875b0204dbafde1456a1b32bf8e26b25 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 11 May 2009 08:53:35 +0200 Subject: [PATCH 084/404] Fix ChangeLog for the previous patch. --- ChangeLog | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 30d09f38..93c08536 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-05-11 Akim Demaille + + doc: use C++ headers. + * doc/bison.texinfo (Calc++ Scanner): Prefer C++ headers to C + headers. + 2009-05-05 Akim Demaille fix hexadecimal token number support. @@ -8,12 +14,6 @@ tests: check token numbers. * tests/input.at (Numbered tokens): New. -2009-05-11 Akim Demaille - - doc: use C++ headers. - * doc/bison.texinfo (Calc++ Scanner): Prefer C++ headers to C - headers. - 2009-05-04 Akim Demaille bison: catch bad symbol names. From c8bf65f07e235360835f4c3a97ba7f10ccfa0030 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 19 May 2009 11:29:40 +0200 Subject: [PATCH 085/404] remove useless variable. * src/getargs.c (skeleton_arg): Remove now useless variable. Should help the compiler see that this printf-like call is sane. --- ChangeLog | 6 ++++++ src/getargs.c | 6 +----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 93c08536..a46ff2ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-05-19 Akim Demaille + + remove useless variable. + * src/getargs.c (skeleton_arg): Remove now useless variable. + Should help the compiler see that this printf-like call is sane. + 2009-05-11 Akim Demaille doc: use C++ headers. diff --git a/src/getargs.c b/src/getargs.c index 962dad4d..3852de04 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -379,11 +379,7 @@ skeleton_arg (char const *arg, int prio, location loc) skeleton = arg; } else if (prio == skeleton_prio) - { - char const *msg = - _("multiple skeleton declarations are invalid"); - complain_at (loc, msg); - } + complain_at (loc, _("multiple skeleton declarations are invalid")); } void From 8c221795affd367ac106161610d42fc94633e3fd Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Tue, 19 May 2009 17:51:05 -0400 Subject: [PATCH 086/404] Handle a trailing `:' in a user-supplied C++ namespace better. * data/c++.m4 (b4_namespace_close): Don't let it be printed among the closing braces here. This fix might make the generated code easier to debug, but otherwise it should be insignificant because a trailing `:' is a C++ error already. --- ChangeLog | 8 ++++++++ data/c++.m4 | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a46ff2ba..87c37012 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-05-19 Joel E. Denny + + Handle a trailing `:' in a user-supplied C++ namespace better. + * data/c++.m4 (b4_namespace_close): Don't let it be printed + among the closing braces here. This fix might make the + generated code easier to debug, but otherwise it should be + insignificant because a trailing `:' is a C++ error already. + 2009-05-19 Akim Demaille remove useless variable. diff --git a/data/c++.m4 b/data/c++.m4 index 593390d6..e82e98b3 100644 --- a/data/c++.m4 +++ b/data/c++.m4 @@ -74,7 +74,7 @@ m4_define([b4_namespace_open], m4_define([b4_namespace_close], [b4_user_code([b4_percent_define_get_syncline([[namespace]]) -m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref), +m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref[ ]), [^\(.\)[ ]*\(::\)?\([^][:]\|:[^][:]\)*], [\1])), [::\([^][:]\|:[^][:]\)*], [} ])[} // ]b4_namespace_ref])]) From e7bfa8b7211e2a02f4cec6f122b3141ad2ca97fb Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Wed, 20 May 2009 17:14:08 -0400 Subject: [PATCH 087/404] * data/c++.m4 (b4_namespace_close): Simplify slightly. --- ChangeLog | 4 ++++ data/c++.m4 | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 87c37012..359363ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-05-20 Joel E. Denny + + * data/c++.m4 (b4_namespace_close): Simplify slightly. + 2009-05-19 Joel E. Denny Handle a trailing `:' in a user-supplied C++ namespace better. diff --git a/data/c++.m4 b/data/c++.m4 index e82e98b3..619db31f 100644 --- a/data/c++.m4 +++ b/data/c++.m4 @@ -75,9 +75,9 @@ m4_define([b4_namespace_open], m4_define([b4_namespace_close], [b4_user_code([b4_percent_define_get_syncline([[namespace]]) m4_bpatsubst(m4_dquote(m4_bpatsubst(m4_dquote(b4_namespace_ref[ ]), - [^\(.\)[ ]*\(::\)?\([^][:]\|:[^][:]\)*], + [^\(.\)[ ]*\(::\)?\([^][:]\|:[^:]\)*], [\1])), - [::\([^][:]\|:[^][:]\)*], [} ])[} // ]b4_namespace_ref])]) + [::\([^][:]\|:[^:]\)*], [} ])[} // ]b4_namespace_ref])]) # b4_token_enums(LIST-OF-PAIRS-TOKEN-NAME-TOKEN-NUMBER) From 531683e74b893b44a37cf61918281112a1e3efa0 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 22 May 2009 01:47:38 -0400 Subject: [PATCH 088/404] * data/c++.m4: Update copyright year. --- ChangeLog | 4 ++++ data/c++.m4 | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 359363ff..e1b424ea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2009-05-22 Joel E. Denny + + * data/c++.m4: Update copyright year. + 2009-05-20 Joel E. Denny * data/c++.m4 (b4_namespace_close): Simplify slightly. diff --git a/data/c++.m4 b/data/c++.m4 index 619db31f..0502dfe9 100644 --- a/data/c++.m4 +++ b/data/c++.m4 @@ -2,8 +2,8 @@ # C++ skeleton for Bison -# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, -# Inc. +# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 From 246c4efafed178058a22b96d7a046340f6119057 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 22 May 2009 01:39:07 -0400 Subject: [PATCH 089/404] Update some comments to make sense for -D. * data/bison.m4 (b4_check_user_names): In header comments, say "user occurrence" instead of "grammar occurrence". * src/muscle_tab.h (muscle_percent_define_insert): Likewise. (muscle_percent_code_grow): Likewise just for consistency. --- ChangeLog | 8 ++++++++ data/bison.m4 | 4 ++-- src/muscle_tab.h | 16 +++++++++------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index e1b424ea..738e36e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-05-22 Joel E. Denny + + Update some comments to make sense for -D. + * data/bison.m4 (b4_check_user_names): In header comments, say + "user occurrence" instead of "grammar occurrence". + * src/muscle_tab.h (muscle_percent_define_insert): Likewise. + (muscle_percent_code_grow): Likewise just for consistency. + 2009-05-22 Joel E. Denny * data/c++.m4: Update copyright year. diff --git a/data/bison.m4 b/data/bison.m4 index 00a42e21..585fb1d0 100644 --- a/data/bison.m4 +++ b/data/bison.m4 @@ -317,8 +317,8 @@ b4_define_user_code([stype]) # but is not used by Bison (as recorded by macros in the namespace # BISON-NAMESPACE). # -# USER-LIST must expand to a list specifying all grammar occurrences of all -# names of type WHAT. Each item in the list must be a triplet specifying one +# USER-LIST must expand to a list specifying all user occurrences of all names +# of type WHAT. Each item in the list must be a triplet specifying one # occurrence: name, start boundary, and end boundary. Empty string names are # fine. An empty list is fine. # diff --git a/src/muscle_tab.h b/src/muscle_tab.h index 19fba8b9..21249b73 100644 --- a/src/muscle_tab.h +++ b/src/muscle_tab.h @@ -1,5 +1,6 @@ /* Muscle table manager for Bison, - Copyright (C) 2001, 2002, 2003, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2006, 2007, 2009 Free Software + Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -123,9 +124,9 @@ void muscle_user_name_list_grow (char const *key, char const *user_name, location loc); /* Define the muscle for the %define variable VARIABLE appearing at - VARIABLE_LOC in the grammar file with value VALUE. Warn if VARIABLE is - already defined. Record this as a grammar occurrence of VARIABLE by - invoking muscle_user_name_list_grow. */ + VARIABLE_LOC with value VALUE. Warn if VARIABLE is already defined. + Record this as a user occurrence of VARIABLE by invoking + muscle_user_name_list_grow. */ void muscle_percent_define_insert (char const *variable, location variable_loc, char const *value); @@ -185,9 +186,10 @@ void muscle_percent_define_default (char const *variable, char const *value); output. */ void muscle_percent_define_check_values (char const * const *values); -/* Grow the muscle for the %code qualifier QUALIFIER appearing at QUALIFIER_LOC - in the grammar file with code CODE appearing at CODE_LOC. Record this as a - grammar occurrence of VARIABLE by invoking muscle_user_name_list_grow. */ +/* Grow the muscle for the %code qualifier QUALIFIER appearing at + QUALIFIER_LOC with code CODE appearing at CODE_LOC. Record this as a + user occurrence of QUALIFIER by invoking + muscle_user_name_list_grow. */ void muscle_percent_code_grow (char const *qualifier, location qualifier_loc, char const *code, location code_loc); From 34d419381579dd30642e5646aaeaece36207be94 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Fri, 22 May 2009 17:14:08 -0400 Subject: [PATCH 090/404] -F/--force-define and relative %define/-D/--define priorities. * NEWS (2.5): Add documentation to -D/--define entry. * build-aux/cross-options.pl: Hard-code association of --force-define with %define. * doc/bison.texinfo (Decl Summary): In %define entry, cross-reference command-line options. (Bison Options): Add documentation to -D/--define entry. (Option Cross Key): Widen column for --force-define row. * src/getargs.c (usage): Document -F/--force-define. Realign options in output. (short_options, long_options, getargs): Parse -F/--force-define, and update muscle_percent_define_insert invocation. * src/muscle_tab.h (muscle_percent_define_how): New enum type. (muscle_percent_define_insert): Add argument with that type. * src/muscle_tab.c (muscle_percent_define_insert): Implement -F/--force-define behavior and priorities. * src/parse-gram.y (prologue_declaration): Update muscle_percent_define_insert invocations. * tests/input.at (`%define, --define'): Rename to... (`%define, --define, --force-define'): ... this and extend. --- ChangeLog | 23 +++++ NEWS | 17 ++-- build-aux/cross-options.pl | 6 +- doc/bison.texinfo | 32 +++++- src/getargs.c | 58 ++++++----- src/muscle_tab.c | 21 +++- src/muscle_tab.h | 21 +++- src/parse-gram.c | 201 +++++++++++++++++++------------------ src/parse-gram.h | 2 +- src/parse-gram.y | 9 +- tests/input.at | 50 ++++++--- 11 files changed, 277 insertions(+), 163 deletions(-) diff --git a/ChangeLog b/ChangeLog index 738e36e8..03c6de13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2009-05-22 Joel E. Denny + + -F/--force-define and relative %define/-D/--define priorities. + * NEWS (2.5): Add documentation to -D/--define entry. + * build-aux/cross-options.pl: Hard-code association of + --force-define with %define. + * doc/bison.texinfo (Decl Summary): In %define entry, + cross-reference command-line options. + (Bison Options): Add documentation to -D/--define entry. + (Option Cross Key): Widen column for --force-define row. + * src/getargs.c (usage): Document -F/--force-define. Realign + options in output. + (short_options, long_options, getargs): Parse -F/--force-define, + and update muscle_percent_define_insert invocation. + * src/muscle_tab.h (muscle_percent_define_how): New enum type. + (muscle_percent_define_insert): Add argument with that type. + * src/muscle_tab.c (muscle_percent_define_insert): Implement + -F/--force-define behavior and priorities. + * src/parse-gram.y (prologue_declaration): Update + muscle_percent_define_insert invocations. + * tests/input.at (`%define, --define'): Rename to... + (`%define, --define, --force-define'): ... this and extend. + 2009-05-22 Joel E. Denny Update some comments to make sense for -D. diff --git a/NEWS b/NEWS index 65781606..ed8819f0 100644 --- a/NEWS +++ b/NEWS @@ -35,17 +35,22 @@ Bison News ** %define can now be invoked via the command line. - Each of these bison command-line options + Each of these command-line options - -D NAME=VALUE - --define=NAME=VALUE + -D NAME[=VALUE] + --define=NAME[=VALUE] + + -F NAME[=VALUE] + --force-define=NAME[=VALUE] is equivalent to this grammar file declaration - %define NAME "VALUE" + %define NAME ["VALUE"] - for any NAME and VALUE. Omitting `=VALUE' on the command line is - equivalent to omitting `"VALUE"' in the declaration. + except that the manner in which Bison processes multiple definitions + for the same NAME differs. Most importantly, -F and --force-define + quietly override %define, but -D and --define do not. For further + details, see the section "Bison Options" in the Bison manual. ** %define variables renamed. diff --git a/build-aux/cross-options.pl b/build-aux/cross-options.pl index 241c741b..7762e276 100755 --- a/build-aux/cross-options.pl +++ b/build-aux/cross-options.pl @@ -22,7 +22,11 @@ while () $short = '' if ! defined $short; $short = '-d' if $long eq '--defines' && ! $short; my $dir = '%' . substr($long, 2); - $dir = '' if index ($scanner, "\"$dir\"") < 0; + if (index ($scanner, "\"$dir\"") < 0) + { + if ($long eq '--force-define') { $dir = '%define'; } + else { $dir = ''; } + } if ($arg) { # if $opt, $arg contains the closing ]. diff --git a/doc/bison.texinfo b/doc/bison.texinfo index 1a66edc4..d377b5c6 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -4837,7 +4837,8 @@ The possible choices for @var{variable}, as well as their meanings, depend on the selected target language and/or the parser skeleton (@pxref{Decl Summary,,%language}, @pxref{Decl Summary,,%skeleton}). -Bison will warn if a @var{variable} is defined multiple times. +Bison will warn if a @var{variable} is defined by @code{%define} +multiple times, but @ref{Bison Options,,-D @var{name}[=@var{value}]}. Omitting @code{"@var{value}"} is always equivalent to specifying it as @code{""}. @@ -7982,8 +7983,29 @@ already defined, so that the debugging facilities are compiled. @item -D @var{name}[=@var{value}] @itemx --define=@var{name}[=@var{value}] -Same as running @samp{%define @var{name} "@var{value}"} (@pxref{Decl -Summary, ,%define}). +@item -F @var{name}[=@var{value}] +@itemx --force-define=@var{name}[=@var{value}] +Each of these is equivalent to @samp{%define @var{name} "@var{value}"} +(@pxref{Decl Summary, ,%define}) except that Bison processes multiple +definitions for the same @var{name} as follows: + +@itemize +@item +Bison processes all command-line definitions in order and then processes +all @code{%define} definitions in order. +@item +Later definitions override earlier definitions except that Bison quietly +ignores all @code{%define} definitions if the last command-line +definition is specified by @code{-F} or @code{--force-define}. +@item +Bison never warns when a command-line definition overrides another +definition, but Bison always warns when a @code{%define} definition +overrides a command-line or @code{%define} definition. +@end itemize + +You should avoid using @code{-F} and @code{--force-define} in your +makefiles unless you are confident that it is safe to quietly ignore any +conflicting @code{%define} that may be added to the grammar file. @item -L @var{language} @itemx --language=@var{language} @@ -8109,9 +8131,9 @@ More user feedback will help to stabilize it.) @section Option Cross Key Here is a list of options, alphabetized by long option, to help you find -the corresponding short option. +the corresponding short option and directive. -@multitable {@option{--defines=@var{defines-file}}} {@option{-D @var{name}[=@var{value}]}} {@code{%nondeterministic-parser}} +@multitable {@option{--force-define=@var{name}[=@var{value}]}} {@option{-F @var{name}[=@var{value}]}} {@code{%nondeterministic-parser}} @headitem Long Option @tab Short Option @tab Bison Directive @include cross-options.texi @end multitable diff --git a/src/getargs.c b/src/getargs.c index 3852de04..322e0b42 100644 --- a/src/getargs.c +++ b/src/getargs.c @@ -272,26 +272,27 @@ The same is true for optional arguments.\n\ fputs (_("\ \n\ Operation modes:\n\ - -h, --help display this help and exit\n\ - -V, --version output version information and exit\n\ - --print-localedir output directory containing locale-dependent data\n\ - --print-datadir output directory containing skeletons and XSLT\n\ - -y, --yacc emulate POSIX Yacc\n\ - -W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\ + -h, --help display this help and exit\n\ + -V, --version output version information and exit\n\ + --print-localedir output directory of locale-dependent data\n\ + --print-datadir output directory of skeletons and XSLT\n\ + -y, --yacc emulate POSIX Yacc\n\ + -W, --warnings[=CATEGORY] report the warnings falling in CATEGORY\n\ \n\ "), stdout); fputs (_("\ Parser:\n\ - -L, --language=LANGUAGE specify the output programming language\n\ - (this is an experimental feature)\n\ - -S, --skeleton=FILE specify the skeleton to use\n\ - -t, --debug instrument the parser for debugging\n\ - --locations enable location support\n\ - -D, --define=NAME[=VALUE] same as `%define NAME \"VALUE\"'\n\ - -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\ - -l, --no-lines don't generate `#line' directives\n\ - -k, --token-table include a table of token names\n\ + -L, --language=LANGUAGE specify the output programming language\n\ + (this is an experimental feature)\n\ + -S, --skeleton=FILE specify the skeleton to use\n\ + -t, --debug instrument the parser for debugging\n\ + --locations enable location support\n\ + -D, --define=NAME[=VALUE] similar to `%define NAME \"VALUE\"'\n\ + -F, --force-define=NAME[=VALUE] override `%define NAME \"VALUE\"'\n\ + -p, --name-prefix=PREFIX prepend PREFIX to the external symbols\n\ + -l, --no-lines don't generate `#line' directives\n\ + -k, --token-table include a table of token names\n\ \n\ "), stdout); @@ -299,16 +300,16 @@ Parser:\n\ * won't assume that -d also takes an argument. */ fputs (_("\ Output:\n\ - --defines[=FILE] also produce a header file\n\ - -d likewise but cannot specify FILE (for POSIX Yacc)\n\ - -r, --report=THINGS also produce details on the automaton\n\ - --report-file=FILE write report to FILE\n\ - -v, --verbose same as `--report=state'\n\ - -b, --file-prefix=PREFIX specify a PREFIX for output files\n\ - -o, --output=FILE leave output to FILE\n\ - -g, --graph[=FILE] also output a graph of the automaton\n\ - -x, --xml[=FILE] also output an XML report of the automaton\n\ - (the XML schema is experimental)\n\ + --defines[=FILE] also produce a header file\n\ + -d likewise but cannot specify FILE (for POSIX)\n\ + -r, --report=THINGS also produce details on the automaton\n\ + --report-file=FILE write report to FILE\n\ + -v, --verbose same as `--report=state'\n\ + -b, --file-prefix=PREFIX specify a PREFIX for output files\n\ + -o, --output=FILE leave output to FILE\n\ + -g, --graph[=FILE] also output a graph of the automaton\n\ + -x, --xml[=FILE] also output an XML report of the automaton\n\ + (the XML schema is experimental)\n\ \n\ "), stdout); @@ -415,6 +416,7 @@ language_argmatch (char const *arg, int prio, location loc) Should be computed from long_options. */ static char const short_options[] = "D:" + "F:" "L:" "S:" "T::" @@ -482,6 +484,7 @@ static struct option const long_options[] = /* Parser. */ { "debug", no_argument, 0, 't' }, { "define", required_argument, 0, 'D' }, + { "force-define", required_argument, 0, 'F' }, { "locations", no_argument, 0, LOCATIONS_OPTION }, { "no-lines", no_argument, 0, 'l' }, { "raw", no_argument, 0, 0 }, @@ -530,13 +533,16 @@ getargs (int argc, char *argv[]) break; case 'D': /* -DNAME[=VALUE]. */ + case 'F': /* -FNAME[=VALUE]. */ { char* name = optarg; char* value = strchr (optarg, '='); if (value) *value++ = 0; muscle_percent_define_insert (name, command_line_location (), - value ? value : ""); + value ? value : "", + c == 'D' ? MUSCLE_PERCENT_DEFINE_D + : MUSCLE_PERCENT_DEFINE_F); } break; diff --git a/src/muscle_tab.c b/src/muscle_tab.c index 764ea93e..fdb03c29 100644 --- a/src/muscle_tab.c +++ b/src/muscle_tab.c @@ -401,12 +401,14 @@ do { \ void muscle_percent_define_insert (char const *variable, location variable_loc, - char const *value) + char const *value, + muscle_percent_define_how how) { char *variable_tr = NULL; char const *name; char const *loc_name; char const *syncline_name; + char const *how_name; /* Permit certain names with underscores for backward compatibility. */ if (0 == strcmp (variable, "api.push_pull") @@ -421,22 +423,33 @@ muscle_percent_define_insert (char const *variable, location variable_loc, MUSCLE_USER_NAME_CONVERT (loc_name, "percent_define_loc(", variable, ")"); MUSCLE_USER_NAME_CONVERT (syncline_name, "percent_define_syncline(", variable, ")"); + MUSCLE_USER_NAME_CONVERT (how_name, "percent_define_how(", variable, ")"); - if (muscle_find_const (name)) + /* Command-line options are processed before the grammar file. */ + if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE + && muscle_find_const (name)) { + muscle_percent_define_how how_old = + atoi (muscle_find_const (how_name)); + if (how_old == MUSCLE_PERCENT_DEFINE_F) + { + free (variable_tr); + return; + } warn_at (variable_loc, _("%s `%s' redefined"), "%define variable", variable); warn_at (muscle_percent_define_get_loc (variable), - _("previous definition")); + _("previous definition")); } - MUSCLE_INSERT_STRING (name, value); + MUSCLE_INSERT_STRING (name, value); muscle_insert (loc_name, ""); muscle_location_grow (loc_name, variable_loc); muscle_insert (syncline_name, ""); muscle_syncline_grow (syncline_name, variable_loc); muscle_user_name_list_grow ("percent_define_user_variables", variable, variable_loc); + MUSCLE_INSERT_INT (how_name, how); free (variable_tr); } diff --git a/src/muscle_tab.h b/src/muscle_tab.h index 21249b73..6edcbbb1 100644 --- a/src/muscle_tab.h +++ b/src/muscle_tab.h @@ -123,12 +123,25 @@ void muscle_boundary_grow (char const *key, boundary bound); void muscle_user_name_list_grow (char const *key, char const *user_name, location loc); -/* Define the muscle for the %define variable VARIABLE appearing at - VARIABLE_LOC with value VALUE. Warn if VARIABLE is already defined. - Record this as a user occurrence of VARIABLE by invoking +/* Indicates whether a variable's value was specified with -D/--define, with + -F/--force-define, or in the grammar file. */ +typedef enum { + MUSCLE_PERCENT_DEFINE_D = 0, MUSCLE_PERCENT_DEFINE_F, + MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE +} muscle_percent_define_how; + +/* Define the muscles for %define variable VARIABLE with VALUE specified + at VARIABLE_LOC in the manner HOW unless it was specified in the + grammar file while the previous definition for VARIABLE was specified + with -F/--force-define. Warn if a previous definition is being + overridden and the new definition is specified in the grammar file. + (These rules support the documented behavior as long as command-line + definitions are processed before grammar file definitions.) Record + this as a user occurrence of VARIABLE by invoking muscle_user_name_list_grow. */ void muscle_percent_define_insert (char const *variable, location variable_loc, - char const *value); + char const *value, + muscle_percent_define_how how); /* Mimic b4_percent_define_get in ../data/bison.m4 exactly. That is, if the %define variable VARIABLE is defined, return its value. Otherwise, return diff --git a/src/parse-gram.c b/src/parse-gram.c index c167f481..bd5c5eb4 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 2.4.1.57-1d0f-dirty. */ +/* A Bison parser, made by GNU Bison 2.4.1.71-377d. */ /* Skeleton implementation for Bison's Yacc-like parsers in C @@ -45,7 +45,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.4.1.57-1d0f-dirty" +#define YYBISON_VERSION "2.4.1.71-377d" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -663,17 +663,17 @@ static const yytype_int8 yyrhs[] = /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 202, 202, 210, 212, 216, 217, 227, 228, 232, - 233, 238, 239, 240, 241, 242, 243, 248, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 280, - 281, 305, 306, 307, 308, 312, 313, 314, 318, 325, - 332, 336, 340, 347, 362, 363, 367, 379, 379, 384, - 384, 389, 400, 415, 416, 417, 421, 422, 427, 429, - 434, 435, 440, 442, 447, 448, 452, 453, 454, 455, - 460, 465, 470, 476, 482, 493, 494, 503, 504, 510, - 511, 512, 519, 519, 523, 524, 525, 530, 531, 533, - 535, 537, 539, 551, 552, 557, 558, 567, 587, 589, - 598, 603, 604, 609, 616, 618 + 0, 202, 202, 210, 212, 216, 217, 227, 228, 233, + 234, 239, 240, 241, 242, 243, 244, 249, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 283, + 284, 308, 309, 310, 311, 315, 316, 317, 321, 328, + 335, 339, 343, 350, 365, 366, 370, 382, 382, 387, + 387, 392, 403, 418, 419, 420, 424, 425, 430, 432, + 437, 438, 443, 445, 450, 451, 455, 456, 457, 458, + 463, 468, 473, 479, 485, 496, 497, 506, 507, 513, + 514, 515, 522, 522, 526, 527, 528, 533, 534, 536, + 538, 540, 542, 554, 555, 560, 561, 570, 590, 592, + 601, 606, 607, 612, 619, 621 }; #endif @@ -1909,21 +1909,22 @@ yyreduce: /* Line 1456 of yacc.c */ #line 229 "parse-gram.y" { - muscle_percent_define_insert ((yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].chars)); + muscle_percent_define_insert ((yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].chars), + MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); } break; case 9: /* Line 1456 of yacc.c */ -#line 232 "parse-gram.y" +#line 233 "parse-gram.y" { defines_flag = true; } break; case 10: /* Line 1456 of yacc.c */ -#line 234 "parse-gram.y" +#line 235 "parse-gram.y" { defines_flag = true; spec_defines_file = xstrdup ((yyvsp[(2) - (2)].chars)); @@ -1933,42 +1934,42 @@ yyreduce: case 11: /* Line 1456 of yacc.c */ -#line 238 "parse-gram.y" +#line 239 "parse-gram.y" { error_verbose = true; } break; case 12: /* Line 1456 of yacc.c */ -#line 239 "parse-gram.y" +#line 240 "parse-gram.y" { expected_sr_conflicts = (yyvsp[(2) - (2)].integer); } break; case 13: /* Line 1456 of yacc.c */ -#line 240 "parse-gram.y" +#line 241 "parse-gram.y" { expected_rr_conflicts = (yyvsp[(2) - (2)].integer); } break; case 14: /* Line 1456 of yacc.c */ -#line 241 "parse-gram.y" +#line 242 "parse-gram.y" { spec_file_prefix = (yyvsp[(2) - (2)].chars); } break; case 15: /* Line 1456 of yacc.c */ -#line 242 "parse-gram.y" +#line 243 "parse-gram.y" { spec_file_prefix = (yyvsp[(3) - (3)].chars); } break; case 16: /* Line 1456 of yacc.c */ -#line 244 "parse-gram.y" +#line 245 "parse-gram.y" { nondeterministic_parser = true; glr_parser = true; @@ -1978,7 +1979,7 @@ yyreduce: case 17: /* Line 1456 of yacc.c */ -#line 249 "parse-gram.y" +#line 250 "parse-gram.y" { code_props action; code_props_symbol_action_init (&action, (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); @@ -1992,102 +1993,104 @@ yyreduce: case 18: /* Line 1456 of yacc.c */ -#line 257 "parse-gram.y" +#line 258 "parse-gram.y" { language_argmatch ((yyvsp[(2) - (2)].chars), grammar_prio, (yylsp[(1) - (2)])); } break; case 19: /* Line 1456 of yacc.c */ -#line 258 "parse-gram.y" +#line 259 "parse-gram.y" { add_param ("lex_param", (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); } break; case 20: /* Line 1456 of yacc.c */ -#line 259 "parse-gram.y" +#line 260 "parse-gram.y" { locations_flag = true; } break; case 21: /* Line 1456 of yacc.c */ -#line 260 "parse-gram.y" +#line 261 "parse-gram.y" { spec_name_prefix = (yyvsp[(2) - (2)].chars); } break; case 22: /* Line 1456 of yacc.c */ -#line 261 "parse-gram.y" +#line 262 "parse-gram.y" { spec_name_prefix = (yyvsp[(3) - (3)].chars); } break; case 23: /* Line 1456 of yacc.c */ -#line 262 "parse-gram.y" +#line 263 "parse-gram.y" { no_lines_flag = true; } break; case 24: /* Line 1456 of yacc.c */ -#line 263 "parse-gram.y" +#line 264 "parse-gram.y" { nondeterministic_parser = true; } break; case 25: /* Line 1456 of yacc.c */ -#line 264 "parse-gram.y" +#line 265 "parse-gram.y" { spec_outfile = (yyvsp[(2) - (2)].chars); } break; case 26: /* Line 1456 of yacc.c */ -#line 265 "parse-gram.y" +#line 266 "parse-gram.y" { spec_outfile = (yyvsp[(3) - (3)].chars); } break; case 27: /* Line 1456 of yacc.c */ -#line 266 "parse-gram.y" +#line 267 "parse-gram.y" { add_param ("parse_param", (yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); } break; case 28: /* Line 1456 of yacc.c */ -#line 268 "parse-gram.y" +#line 269 "parse-gram.y" { /* %pure-parser is deprecated in favor of `%define api.pure', so use `%define api.pure' in a backward-compatible manner here. First, don't complain if %pure-parser is specified multiple times. */ if (!muscle_find_const ("percent_define(api.pure)")) - muscle_percent_define_insert ("api.pure", (yylsp[(1) - (1)]), ""); + muscle_percent_define_insert ("api.pure", (yylsp[(1) - (1)]), "", + MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); /* In all cases, use api.pure now so that the backend doesn't complain if the skeleton ignores api.pure, but do warn now if there's a previous conflicting definition from an actual %define. */ if (!muscle_percent_define_flag_if ("api.pure")) - muscle_percent_define_insert ("api.pure", (yylsp[(1) - (1)]), ""); + muscle_percent_define_insert ("api.pure", (yylsp[(1) - (1)]), "", + MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); } break; case 29: /* Line 1456 of yacc.c */ -#line 280 "parse-gram.y" +#line 283 "parse-gram.y" { version_check (&(yylsp[(2) - (2)]), (yyvsp[(2) - (2)].chars)); } break; case 30: /* Line 1456 of yacc.c */ -#line 282 "parse-gram.y" +#line 285 "parse-gram.y" { char const *skeleton_user = (yyvsp[(2) - (2)].chars); if (strchr (skeleton_user, '/')) @@ -2116,28 +2119,28 @@ yyreduce: case 31: /* Line 1456 of yacc.c */ -#line 305 "parse-gram.y" +#line 308 "parse-gram.y" { token_table_flag = true; } break; case 32: /* Line 1456 of yacc.c */ -#line 306 "parse-gram.y" +#line 309 "parse-gram.y" { report_flag |= report_states; } break; case 33: /* Line 1456 of yacc.c */ -#line 307 "parse-gram.y" +#line 310 "parse-gram.y" { yacc_flag = true; } break; case 37: /* Line 1456 of yacc.c */ -#line 315 "parse-gram.y" +#line 318 "parse-gram.y" { grammar_start_symbol_set ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); } @@ -2146,7 +2149,7 @@ yyreduce: case 38: /* Line 1456 of yacc.c */ -#line 319 "parse-gram.y" +#line 322 "parse-gram.y" { symbol_list *list; for (list = (yyvsp[(3) - (3)].list); list; list = list->next) @@ -2158,7 +2161,7 @@ yyreduce: case 39: /* Line 1456 of yacc.c */ -#line 326 "parse-gram.y" +#line 329 "parse-gram.y" { symbol_list *list; for (list = (yyvsp[(3) - (3)].list); list; list = list->next) @@ -2170,7 +2173,7 @@ yyreduce: case 40: /* Line 1456 of yacc.c */ -#line 333 "parse-gram.y" +#line 336 "parse-gram.y" { default_prec = true; } @@ -2179,7 +2182,7 @@ yyreduce: case 41: /* Line 1456 of yacc.c */ -#line 337 "parse-gram.y" +#line 340 "parse-gram.y" { default_prec = false; } @@ -2188,7 +2191,7 @@ yyreduce: case 42: /* Line 1456 of yacc.c */ -#line 341 "parse-gram.y" +#line 344 "parse-gram.y" { /* Do not invoke muscle_percent_code_grow here since it invokes muscle_user_name_list_grow. */ @@ -2200,7 +2203,7 @@ yyreduce: case 43: /* Line 1456 of yacc.c */ -#line 348 "parse-gram.y" +#line 351 "parse-gram.y" { muscle_percent_code_grow ((yyvsp[(2) - (3)].uniqstr), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].chars), (yylsp[(3) - (3)])); code_scanner_last_string_free (); @@ -2210,21 +2213,21 @@ yyreduce: case 44: /* Line 1456 of yacc.c */ -#line 362 "parse-gram.y" +#line 365 "parse-gram.y" {} break; case 45: /* Line 1456 of yacc.c */ -#line 363 "parse-gram.y" +#line 366 "parse-gram.y" { muscle_code_grow ("union_name", (yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 46: /* Line 1456 of yacc.c */ -#line 368 "parse-gram.y" +#line 371 "parse-gram.y" { union_seen = true; muscle_code_grow ("stype", (yyvsp[(3) - (3)].chars), (yylsp[(3) - (3)])); @@ -2235,14 +2238,14 @@ yyreduce: case 47: /* Line 1456 of yacc.c */ -#line 379 "parse-gram.y" +#line 382 "parse-gram.y" { current_class = nterm_sym; } break; case 48: /* Line 1456 of yacc.c */ -#line 380 "parse-gram.y" +#line 383 "parse-gram.y" { current_class = unknown_sym; current_type = NULL; @@ -2252,14 +2255,14 @@ yyreduce: case 49: /* Line 1456 of yacc.c */ -#line 384 "parse-gram.y" +#line 387 "parse-gram.y" { current_class = token_sym; } break; case 50: /* Line 1456 of yacc.c */ -#line 385 "parse-gram.y" +#line 388 "parse-gram.y" { current_class = unknown_sym; current_type = NULL; @@ -2269,7 +2272,7 @@ yyreduce: case 51: /* Line 1456 of yacc.c */ -#line 390 "parse-gram.y" +#line 393 "parse-gram.y" { symbol_list *list; tag_seen = true; @@ -2282,7 +2285,7 @@ yyreduce: case 52: /* Line 1456 of yacc.c */ -#line 401 "parse-gram.y" +#line 404 "parse-gram.y" { symbol_list *list; ++current_prec; @@ -2299,126 +2302,126 @@ yyreduce: case 53: /* Line 1456 of yacc.c */ -#line 415 "parse-gram.y" +#line 418 "parse-gram.y" { (yyval.assoc) = left_assoc; } break; case 54: /* Line 1456 of yacc.c */ -#line 416 "parse-gram.y" +#line 419 "parse-gram.y" { (yyval.assoc) = right_assoc; } break; case 55: /* Line 1456 of yacc.c */ -#line 417 "parse-gram.y" +#line 420 "parse-gram.y" { (yyval.assoc) = non_assoc; } break; case 56: /* Line 1456 of yacc.c */ -#line 421 "parse-gram.y" +#line 424 "parse-gram.y" { current_type = NULL; } break; case 57: /* Line 1456 of yacc.c */ -#line 422 "parse-gram.y" +#line 425 "parse-gram.y" { current_type = (yyvsp[(1) - (1)].uniqstr); tag_seen = true; } break; case 58: /* Line 1456 of yacc.c */ -#line 428 "parse-gram.y" +#line 431 "parse-gram.y" { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); } break; case 59: /* Line 1456 of yacc.c */ -#line 430 "parse-gram.y" +#line 433 "parse-gram.y" { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), symbol_list_sym_new ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]))); } break; case 60: /* Line 1456 of yacc.c */ -#line 434 "parse-gram.y" +#line 437 "parse-gram.y" { (yyval.symbol) = (yyvsp[(1) - (1)].symbol); } break; case 61: /* Line 1456 of yacc.c */ -#line 435 "parse-gram.y" +#line 438 "parse-gram.y" { (yyval.symbol) = (yyvsp[(1) - (2)].symbol); symbol_user_token_number_set ((yyvsp[(1) - (2)].symbol), (yyvsp[(2) - (2)].integer), (yylsp[(2) - (2)])); } break; case 62: /* Line 1456 of yacc.c */ -#line 441 "parse-gram.y" +#line 444 "parse-gram.y" { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); } break; case 63: /* Line 1456 of yacc.c */ -#line 443 "parse-gram.y" +#line 446 "parse-gram.y" { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), symbol_list_sym_new ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)]))); } break; case 64: /* Line 1456 of yacc.c */ -#line 447 "parse-gram.y" +#line 450 "parse-gram.y" { (yyval.list) = (yyvsp[(1) - (1)].list); } break; case 65: /* Line 1456 of yacc.c */ -#line 448 "parse-gram.y" +#line 451 "parse-gram.y" { (yyval.list) = symbol_list_prepend ((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list)); } break; case 66: /* Line 1456 of yacc.c */ -#line 452 "parse-gram.y" +#line 455 "parse-gram.y" { (yyval.list) = symbol_list_sym_new ((yyvsp[(1) - (1)].symbol), (yylsp[(1) - (1)])); } break; case 67: /* Line 1456 of yacc.c */ -#line 453 "parse-gram.y" +#line 456 "parse-gram.y" { (yyval.list) = symbol_list_type_new ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 68: /* Line 1456 of yacc.c */ -#line 454 "parse-gram.y" +#line 457 "parse-gram.y" { (yyval.list) = symbol_list_default_tagged_new ((yylsp[(1) - (1)])); } break; case 69: /* Line 1456 of yacc.c */ -#line 455 "parse-gram.y" +#line 458 "parse-gram.y" { (yyval.list) = symbol_list_default_tagless_new ((yylsp[(1) - (1)])); } break; case 70: /* Line 1456 of yacc.c */ -#line 461 "parse-gram.y" +#line 464 "parse-gram.y" { current_type = (yyvsp[(1) - (1)].uniqstr); tag_seen = true; @@ -2428,7 +2431,7 @@ yyreduce: case 71: /* Line 1456 of yacc.c */ -#line 466 "parse-gram.y" +#line 469 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (1)].symbol), current_class, (yylsp[(1) - (1)]), true); symbol_type_set ((yyvsp[(1) - (1)].symbol), current_type, (yylsp[(1) - (1)])); @@ -2438,7 +2441,7 @@ yyreduce: case 72: /* Line 1456 of yacc.c */ -#line 471 "parse-gram.y" +#line 474 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true); symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)])); @@ -2449,7 +2452,7 @@ yyreduce: case 73: /* Line 1456 of yacc.c */ -#line 477 "parse-gram.y" +#line 480 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (2)].symbol), current_class, (yylsp[(1) - (2)]), true); symbol_type_set ((yyvsp[(1) - (2)].symbol), current_type, (yylsp[(1) - (2)])); @@ -2460,7 +2463,7 @@ yyreduce: case 74: /* Line 1456 of yacc.c */ -#line 483 "parse-gram.y" +#line 486 "parse-gram.y" { symbol_class_set ((yyvsp[(1) - (3)].symbol), current_class, (yylsp[(1) - (3)]), true); symbol_type_set ((yyvsp[(1) - (3)].symbol), current_type, (yylsp[(1) - (3)])); @@ -2472,7 +2475,7 @@ yyreduce: case 81: /* Line 1456 of yacc.c */ -#line 513 "parse-gram.y" +#line 516 "parse-gram.y" { yyerrok; } @@ -2481,84 +2484,84 @@ yyreduce: case 82: /* Line 1456 of yacc.c */ -#line 519 "parse-gram.y" +#line 522 "parse-gram.y" { current_lhs = (yyvsp[(1) - (1)].symbol); current_lhs_location = (yylsp[(1) - (1)]); } break; case 84: /* Line 1456 of yacc.c */ -#line 523 "parse-gram.y" +#line 526 "parse-gram.y" { grammar_current_rule_end ((yylsp[(1) - (1)])); } break; case 85: /* Line 1456 of yacc.c */ -#line 524 "parse-gram.y" +#line 527 "parse-gram.y" { grammar_current_rule_end ((yylsp[(3) - (3)])); } break; case 87: /* Line 1456 of yacc.c */ -#line 530 "parse-gram.y" +#line 533 "parse-gram.y" { grammar_current_rule_begin (current_lhs, current_lhs_location); } break; case 88: /* Line 1456 of yacc.c */ -#line 532 "parse-gram.y" +#line 535 "parse-gram.y" { grammar_current_rule_symbol_append ((yyvsp[(2) - (2)].symbol), (yylsp[(2) - (2)])); } break; case 89: /* Line 1456 of yacc.c */ -#line 534 "parse-gram.y" +#line 537 "parse-gram.y" { grammar_current_rule_action_append ((yyvsp[(2) - (2)].code), (yylsp[(2) - (2)])); } break; case 90: /* Line 1456 of yacc.c */ -#line 536 "parse-gram.y" +#line 539 "parse-gram.y" { grammar_current_rule_prec_set ((yyvsp[(3) - (3)].symbol), (yylsp[(3) - (3)])); } break; case 91: /* Line 1456 of yacc.c */ -#line 538 "parse-gram.y" +#line 541 "parse-gram.y" { grammar_current_rule_dprec_set ((yyvsp[(3) - (3)].integer), (yylsp[(3) - (3)])); } break; case 92: /* Line 1456 of yacc.c */ -#line 540 "parse-gram.y" +#line 543 "parse-gram.y" { grammar_current_rule_merge_set ((yyvsp[(3) - (3)].uniqstr), (yylsp[(3) - (3)])); } break; case 94: /* Line 1456 of yacc.c */ -#line 552 "parse-gram.y" +#line 555 "parse-gram.y" { (yyval.uniqstr) = uniqstr_new ((yyvsp[(1) - (1)].chars)); } break; case 95: /* Line 1456 of yacc.c */ -#line 557 "parse-gram.y" +#line 560 "parse-gram.y" { (yyval.chars) = ""; } break; case 97: /* Line 1456 of yacc.c */ -#line 568 "parse-gram.y" +#line 571 "parse-gram.y" { code_props plain_code; (yyvsp[(1) - (1)].code)[strlen ((yyvsp[(1) - (1)].code)) - 1] = '\n'; @@ -2572,14 +2575,14 @@ yyreduce: case 98: /* Line 1456 of yacc.c */ -#line 588 "parse-gram.y" +#line 591 "parse-gram.y" { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 99: /* Line 1456 of yacc.c */ -#line 590 "parse-gram.y" +#line 593 "parse-gram.y" { (yyval.symbol) = symbol_get (char_name ((yyvsp[(1) - (1)].character)), (yylsp[(1) - (1)])); symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false); @@ -2590,14 +2593,14 @@ yyreduce: case 100: /* Line 1456 of yacc.c */ -#line 598 "parse-gram.y" +#line 601 "parse-gram.y" { (yyval.symbol) = symbol_from_uniqstr ((yyvsp[(1) - (1)].uniqstr), (yylsp[(1) - (1)])); } break; case 103: /* Line 1456 of yacc.c */ -#line 610 "parse-gram.y" +#line 613 "parse-gram.y" { (yyval.symbol) = symbol_get (quotearg_style (c_quoting_style, (yyvsp[(1) - (1)].chars)), (yylsp[(1) - (1)])); symbol_class_set ((yyval.symbol), token_sym, (yylsp[(1) - (1)]), false); @@ -2607,7 +2610,7 @@ yyreduce: case 105: /* Line 1456 of yacc.c */ -#line 619 "parse-gram.y" +#line 622 "parse-gram.y" { code_props plain_code; code_props_plain_init (&plain_code, (yyvsp[(2) - (2)].chars), (yylsp[(2) - (2)])); @@ -2621,7 +2624,7 @@ yyreduce: /* Line 1456 of yacc.c */ -#line 2625 "parse-gram.c" +#line 2628 "parse-gram.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2840,7 +2843,7 @@ yyreturn: /* Line 1676 of yacc.c */ -#line 629 "parse-gram.y" +#line 632 "parse-gram.y" diff --git a/src/parse-gram.h b/src/parse-gram.h index a17d93d7..9257e090 100644 --- a/src/parse-gram.h +++ b/src/parse-gram.h @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 2.4.1.57-1d0f-dirty. */ +/* A Bison parser, made by GNU Bison 2.4.1.71-377d. */ /* Skeleton interface for Bison's Yacc-like parsers in C diff --git a/src/parse-gram.y b/src/parse-gram.y index 5af473c7..b05ce2bd 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -227,7 +227,8 @@ prologue_declaration: | "%debug" { debug_flag = true; } | "%define" variable content.opt { - muscle_percent_define_insert ($2, @2, $3); + muscle_percent_define_insert ($2, @2, $3, + MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); } | "%defines" { defines_flag = true; } | "%defines" STRING @@ -270,12 +271,14 @@ prologue_declaration: `%define api.pure' in a backward-compatible manner here. First, don't complain if %pure-parser is specified multiple times. */ if (!muscle_find_const ("percent_define(api.pure)")) - muscle_percent_define_insert ("api.pure", @1, ""); + muscle_percent_define_insert ("api.pure", @1, "", + MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); /* In all cases, use api.pure now so that the backend doesn't complain if the skeleton ignores api.pure, but do warn now if there's a previous conflicting definition from an actual %define. */ if (!muscle_percent_define_flag_if ("api.pure")) - muscle_percent_define_insert ("api.pure", @1, ""); + muscle_percent_define_insert ("api.pure", @1, "", + MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE); } | "%require" STRING { version_check (&@2, $2); } | "%skeleton" STRING diff --git a/tests/input.at b/tests/input.at index 1eaf4821..911f9984 100644 --- a/tests/input.at +++ b/tests/input.at @@ -918,27 +918,49 @@ input.y:5.9-16: warning: %define variable `special2' is not used AT_CLEANUP -## ------------------- ## -## %define, --define. ## -## ------------------- ## +## ----------------------------------- ## +## %define, --define, --force-define. ## +## ----------------------------------- ## -AT_SETUP([%define, --define]) +AT_SETUP([%define, --define, --force-define]) + +AT_DATA([skel.c], +[[m4@&t@_divert_push(0)@ +@output(b4_parser_file_name@)@ +[var-dd: ]b4_percent_define_get([[var-dd]])[ +var-ff: ]b4_percent_define_get([[var-ff]])[ +var-dg: ]b4_percent_define_get([[var-dg]])[ +var-dfg: ]b4_percent_define_get([[var-dfg]])[ +var-fd: ]b4_percent_define_get([[var-fd]]) +m4@&t@_divert_pop(0) +]]) AT_DATA([input.y], -[[%define var "value1" +[[%define var-dg "gram" +%define var-dfg "gram" %% start: ; ]]) -AT_BISON_CHECK([[-DFOO -DFOO -Dvar=value input.y]], [0], [], -[[:3: warning: %define variable `FOO' redefined -:2: warning: previous definition -input.y:1.9-11: warning: %define variable `var' redefined -:4: warning: previous definition -:2: warning: %define variable `FOO' is not used -:3: warning: %define variable `FOO' is not used -:4: warning: %define variable `var' is not used -input.y:1.9-11: warning: %define variable `var' is not used +AT_BISON_CHECK([[-Dvar-dd=cmd-d1 -Dvar-dd=cmd-d2 \ + -Fvar-ff=cmd-f1 -Fvar-ff=cmd-f2 \ + -Dvar-dg=cmd-d \ + -Dvar-dfg=cmd-d -Fvar-dfg=cmd-f \ + -Fvar-fd=cmd-f -Dvar-fd=cmd-d \ + -Dunused-d -Funused-f \ + --skeleton ./skel.c input.y]], [0], [], +[[input.y:1.9-14: warning: %define variable `var-dg' redefined +:6: warning: previous definition +:11: warning: %define variable `unused-d' is not used +:12: warning: %define variable `unused-f' is not used +]]) + +AT_CHECK([[cat input.tab.c]], [[0]], +[[var-dd: cmd-d2 +var-ff: cmd-f2 +var-dg: gram +var-dfg: cmd-f +var-fd: cmd-d ]]) AT_CLEANUP From e3a33f7c23fc9febd1bbff33045c8b455a1972a8 Mon Sep 17 00:00:00 2001 From: "Joel E. Denny" Date: Sat, 23 May 2009 02:25:28 -0400 Subject: [PATCH 091/404] Convert multiple variable definition warnings to complaints. * NEWS (2.5): Add a new entry for that change. * doc/bison.texinfo (Decl Summary): Update %define entry. (Bison Options): Update -D/--define/-F/--force-define entry. * src/muscle_tab.c (muscle_percent_define_insert): Implement. * src/muscle_tab.h (muscle_percent_define_insert): Update comments. * tests/input.at (`%define errors'): Update. (`%define, --define, --force-define'): Update. --- ChangeLog | 12 +++++++++++ NEWS | 2 ++ doc/bison.texinfo | 23 ++++++++++++--------- src/muscle_tab.c | 6 +++--- src/muscle_tab.h | 2 +- tests/input.at | 52 ++++++++++++++++++++++++++++------------------- 6 files changed, 62 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 03c6de13..74e2aea5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2009-05-22 Joel E. Denny + + Convert multiple variable definition warnings to complaints. + * NEWS (2.5): Add a new entry for that change. + * doc/bison.texinfo (Decl Summary): Update %define entry. + (Bison Options): Update -D/--define/-F/--force-define entry. + * src/muscle_tab.c (muscle_percent_define_insert): Implement. + * src/muscle_tab.h (muscle_percent_define_insert): Update + comments. + * tests/input.at (`%define errors'): Update. + (`%define, --define, --force-define'): Update. + 2009-05-22 Joel E. Denny -F/--force-define and relative %define/-D/--define priorities. diff --git a/NEWS b/NEWS index ed8819f0..7d401ad5 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,8 @@ Bison News These features are experimental. More user feedback will help to stabilize them. +** Multiple %define's for any variable is now an error not a warning. + ** %define can now be invoked via the command line. Each of these command-line options diff --git a/doc/bison.texinfo b/doc/bison.texinfo index d377b5c6..3c63a19a 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -4837,8 +4837,8 @@ The possible choices for @var{variable}, as well as their meanings, depend on the selected target language and/or the parser skeleton (@pxref{Decl Summary,,%language}, @pxref{Decl Summary,,%skeleton}). -Bison will warn if a @var{variable} is defined by @code{%define} -multiple times, but @ref{Bison Options,,-D @var{name}[=@var{value}]}. +It is an error if a @var{variable} is defined by @code{%define} multiple +times, but @ref{Bison Options,,-D @var{name}[=@var{value}]}. Omitting @code{"@var{value}"} is always equivalent to specifying it as @code{""}. @@ -7991,16 +7991,19 @@ definitions for the same @var{name} as follows: @itemize @item -Bison processes all command-line definitions in order and then processes -all @code{%define} definitions in order. +Bison quietly ignores all command-line definitions for @var{name} except +the last. @item -Later definitions override earlier definitions except that Bison quietly -ignores all @code{%define} definitions if the last command-line -definition is specified by @code{-F} or @code{--force-define}. +If that command-line definition is specified by a @code{-D} or +@code{--define}, Bison reports an error for any @code{%define} +definition for @var{name}. @item -Bison never warns when a command-line definition overrides another -definition, but Bison always warns when a @code{%define} definition -overrides a command-line or @code{%define} definition. +If that command-line definition is specified by a @code{-F} or +@code{--force-define} instead, Bison quietly ignores all @code{%define} +definitions for @var{name}. +@item +Otherwise, Bison reports an error if there are multiple @code{%define} +definitions for @var{name}. @end itemize You should avoid using @code{-F} and @code{--force-define} in your diff --git a/src/muscle_tab.c b/src/muscle_tab.c index fdb03c29..cfddbcf3 100644 --- a/src/muscle_tab.c +++ b/src/muscle_tab.c @@ -436,9 +436,9 @@ muscle_percent_define_insert (char const *variable, location variable_loc, free (variable_tr); return; } - warn_at (variable_loc, _("%s `%s' redefined"), - "%define variable", variable); - warn_at (muscle_percent_define_get_loc (variable), + complain_at (variable_loc, _("%s `%s' redefined"), + "%define variable", variable); + complain_at (muscle_percent_define_get_loc (variable), _("previous definition")); } diff --git a/src/muscle_tab.h b/src/muscle_tab.h index 6edcbbb1..e06126b3 100644 --- a/src/muscle_tab.h +++ b/src/muscle_tab.h @@ -133,7 +133,7 @@ typedef enum { /* Define the muscles for %define variable VARIABLE with VALUE specified at VARIABLE_LOC in the manner HOW unless it was specified in the grammar file while the previous definition for VARIABLE was specified - with -F/--force-define. Warn if a previous definition is being + with -F/--force-define. Complain if a previous definition is being overridden and the new definition is specified in the grammar file. (These rules support the documented behavior as long as command-line definitions are processed before grammar file definitions.) Record diff --git a/tests/input.at b/tests/input.at index 911f9984..24365e65 100644 --- a/tests/input.at +++ b/tests/input.at @@ -893,7 +893,7 @@ AT_CLEANUP AT_SETUP([%define errors]) -AT_DATA([input.y], +AT_DATA([input-redefined.y], [[%define var "value1" %define var "value1" %define var "value2" @@ -903,16 +903,21 @@ AT_DATA([input.y], start: ; ]]) -AT_BISON_CHECK([[input.y]], [0], [], -[[input.y:2.9-11: warning: %define variable `var' redefined -input.y:1.9-11: warning: previous definition -input.y:3.10-12: warning: %define variable `var' redefined -input.y:2.9-11: warning: previous definition -input.y:1.9-11: warning: %define variable `var' is not used -input.y:2.9-11: warning: %define variable `var' is not used -input.y:3.10-12: warning: %define variable `var' is not used -input.y:4.9-16: warning: %define variable `special1' is not used -input.y:5.9-16: warning: %define variable `special2' is not used +AT_BISON_CHECK([[input-redefined.y]], [[1]], [], +[[input-redefined.y:2.9-11: %define variable `var' redefined +input-redefined.y:1.9-11: previous definition +input-redefined.y:3.10-12: %define variable `var' redefined +input-redefined.y:2.9-11: previous definition +]]) + +AT_DATA([input-unused.y], +[[%define var "value" +%% +start: ; +]]) + +AT_BISON_CHECK([[input-unused.y]], [[0]], [], +[[input-unused.y:1.9-11: warning: %define variable `var' is not used ]]) AT_CLEANUP @@ -929,40 +934,45 @@ AT_DATA([skel.c], @output(b4_parser_file_name@)@ [var-dd: ]b4_percent_define_get([[var-dd]])[ var-ff: ]b4_percent_define_get([[var-ff]])[ -var-dg: ]b4_percent_define_get([[var-dg]])[ var-dfg: ]b4_percent_define_get([[var-dfg]])[ var-fd: ]b4_percent_define_get([[var-fd]]) m4@&t@_divert_pop(0) ]]) AT_DATA([input.y], -[[%define var-dg "gram" -%define var-dfg "gram" +[[%define var-dfg "gram" %% start: ; ]]) AT_BISON_CHECK([[-Dvar-dd=cmd-d1 -Dvar-dd=cmd-d2 \ -Fvar-ff=cmd-f1 -Fvar-ff=cmd-f2 \ - -Dvar-dg=cmd-d \ -Dvar-dfg=cmd-d -Fvar-dfg=cmd-f \ -Fvar-fd=cmd-f -Dvar-fd=cmd-d \ -Dunused-d -Funused-f \ - --skeleton ./skel.c input.y]], [0], [], -[[input.y:1.9-14: warning: %define variable `var-dg' redefined -:6: warning: previous definition -:11: warning: %define variable `unused-d' is not used -:12: warning: %define variable `unused-f' is not used + --skeleton ./skel.c input.y]], [[0]], [], +[[:10: warning: %define variable `unused-d' is not used +:11: warning: %define variable `unused-f' is not used ]]) AT_CHECK([[cat input.tab.c]], [[0]], [[var-dd: cmd-d2 var-ff: cmd-f2 -var-dg: gram var-dfg: cmd-f var-fd: cmd-d ]]) +AT_DATA([input-dg.y], +[[%define var "gram" +%% +start: ; +]]) + +AT_BISON_CHECK([[-Dvar=cmd-d input-dg.y]], [[1]], [], +[[input-dg.y:1.9-11: %define variable `var' redefined +:2: previous definition +]]) + AT_CLEANUP ## --------------------------- ## From ed15d907c5beb3a2a344f8cecd06af20bf14d596 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Wed, 10 Jun 2009 10:40:55 +0200 Subject: [PATCH 092/404] gnulib: update. * gnulib: Update to latest. * lib/.cvsignore, lib/.gitignore, m4/.cvsignore, * m4/.gitignore: Regen. * src/symtab.c (symbol_from_uniqstr, semantic_type_from_uniqstr): Call xalloc_die on hash_insert failures. Requested by the new __warn_unused_result__ attribute of hash_insert. --- ChangeLog | 11 +++++++++++ lib/.cvsignore | 1 + lib/.gitignore | 1 + m4/.cvsignore | 1 + m4/.gitignore | 1 + src/symtab.c | 6 ++++-- 6 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74e2aea5..d3fc291c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-06-10 Akim Demaille + + gnulib: update. + * gnulib: Update to latest. + * lib/.cvsignore, lib/.gitignore, m4/.cvsignore, + * m4/.gitignore: Regen. + * src/symtab.c (symbol_from_uniqstr, semantic_type_from_uniqstr): + Call xalloc_die on hash_insert failures. + Requested by the new __warn_unused_result__ attribute of + hash_insert. + 2009-05-22 Joel E. Denny Convert multiple variable definition warnings to complaints. diff --git a/lib/.cvsignore b/lib/.cvsignore index 412882f3..8d2d4d2d 100644 --- a/lib/.cvsignore +++ b/lib/.cvsignore @@ -45,6 +45,7 @@ mbrtowc.c mbsinit.c mbswidth.c mbswidth.h +memchr.c obstack.c obstack.h pipe-safer.c diff --git a/lib/.gitignore b/lib/.gitignore index b647a928..73d272e0 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -48,6 +48,7 @@ /mbsinit.c /mbswidth.c /mbswidth.h +/memchr.c /obstack.c /obstack.h /pipe-safer.c diff --git a/m4/.cvsignore b/m4/.cvsignore index 3cdc569e..310e1efc 100644 --- a/m4/.cvsignore +++ b/m4/.cvsignore @@ -39,6 +39,7 @@ mbrtowc.m4 mbsinit.m4 mbstate_t.m4 mbswidth.m4 +memchr.m4 multiarch.m4 nls.m4 po.m4 diff --git a/m4/.gitignore b/m4/.gitignore index 0755b7d7..0ca03ad3 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -39,6 +39,7 @@ /mbsinit.m4 /mbstate_t.m4 /mbswidth.m4 +/memchr.m4 /multiarch.m4 /nls.m4 /po.m4 diff --git a/src/symtab.c b/src/symtab.c index f9560efa..29ca76ad 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -680,7 +680,8 @@ symbol_from_uniqstr (const uniqstr key, location loc) { /* First insertion in the hash. */ entry = symbol_new (key, loc); - hash_insert (symbol_table, entry); + if (!hash_insert (symbol_table, entry)) + xalloc_die (); } return entry; } @@ -704,7 +705,8 @@ semantic_type_from_uniqstr (const uniqstr key) { /* First insertion in the hash. */ entry = semantic_type_new (key); - hash_insert (semantic_type_table, entry); + if (!hash_insert (semantic_type_table, entry)) + xalloc_die (); } return entry; } From 95d176ffd9f66a01125c366226e1a557b125e0d8 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Wed, 3 Jun 2009 23:15:38 +0200 Subject: [PATCH 093/404] deterministic user-token-number redeclaration errors. Address nondeterminism reported by Joel E. Denny. http://lists.gnu.org/archive/html/bison-patches/2009-05/msg00023.html * src/uniqstr.h: Comment changes. * src/location.h (boundary_cmp, location_cmp): New. * src/symtab.c (user_token_number_redeclaration): New. (symbol_translation): Use it. * tests/input.at (Numbered tokens): Adjust the expected output. --- ChangeLog | 12 ++++++++++++ src/location.h | 24 ++++++++++++++++++++++++ src/symtab.c | 28 ++++++++++++++++++++++++---- src/uniqstr.h | 6 +++++- tests/input.at | 6 ++++-- 5 files changed, 69 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3fc291c..a8c6c588 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2009-06-10 Akim Demaille + deterministic user-token-number redeclaration errors. + Address nondeterminism reported by Joel E. Denny. + http://lists.gnu.org/archive/html/bison-patches/2009-05/msg00023.html + + * src/uniqstr.h: Comment changes. + * src/location.h (boundary_cmp, location_cmp): New. + * src/symtab.c (user_token_number_redeclaration): New. + (symbol_translation): Use it. + * tests/input.at (Numbered tokens): Adjust the expected output. + +2009-05-25 Akim Demaille + gnulib: update. * gnulib: Update to latest. * lib/.cvsignore, lib/.gitignore, m4/.cvsignore, diff --git a/src/location.h b/src/location.h index a99232bd..ec481649 100644 --- a/src/location.h +++ b/src/location.h @@ -55,6 +55,19 @@ boundary_set (boundary *b, const char *f, int l, int c) b->column = c; } +/* Return -1, 0, 1, depending whether a is before, equal, or + after b. */ +static inline int +boundary_cmp (boundary a, boundary b) +{ + int res = strcmp (a.file, b.file); + if (!res) + res = a.line - b.line; + if (!res) + res = a.column - b.column; + return res; +} + /* Return nonzero if A and B are equal boundaries. */ static inline bool equal_boundaries (boundary a, boundary b) @@ -87,6 +100,17 @@ void location_compute (location *loc, void location_print (FILE *out, location loc); +/* Return -1, 0, 1, depending whether a is before, equal, or + after b. */ +static inline int +location_cmp (location a, location b) +{ + int res = boundary_cmp (a.start, b.start); + if (!res) + res = boundary_cmp (a.end, b.end); + return res; +} + /* LOC_STR must be formatted as `file:line.column', it will be modified. */ void boundary_set_from_string (boundary *bound, char *loc_str); diff --git a/src/symtab.c b/src/symtab.c index 29ca76ad..930899ce 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -158,6 +158,7 @@ semantic_type_redeclaration (semantic_type *s, const char *what, location first, } + /*-----------------------------------------------------------------. | Set the TYPE_NAME associated with SYM. Does nothing if passed 0 | | as TYPE_NAME. | @@ -547,7 +548,26 @@ symbol_pack_processor (void *this, void *null ATTRIBUTE_UNUSED) } +static void +user_token_number_redeclaration (int num, symbol *first, symbol *second) +{ + /* User token numbers are not assigned during the parsing, but in a + second step, via a (nondeterministic) traversal of the symbol + hash table. + Make errors deterministic: keep the first declaration first. */ + if (location_cmp (first->location, second->location) > 0) + { + symbol* tmp = first; + first = second; + second = tmp; + } + complain_at (second->location, + _("user token number %d redeclaration for %s"), + num, second->tag); + complain_at (first->location, _("previous declaration for %s"), + first->tag); +} /*--------------------------------------------------. | Put THIS in TOKEN_TRANSLATIONS if it is a token. | @@ -562,10 +582,10 @@ symbol_translation (symbol *this) { /* A token which translation has already been set? */ if (token_translations[this->user_token_number] != undeftoken->number) - complain_at (this->location, - _("tokens %s and %s both assigned number %d"), - symbols[token_translations[this->user_token_number]]->tag, - this->tag, this->user_token_number); + user_token_number_redeclaration + (this->user_token_number, + symbols[token_translations[this->user_token_number]], + this); token_translations[this->user_token_number] = this->number; } diff --git a/src/uniqstr.h b/src/uniqstr.h index 3eb152d3..04600e94 100644 --- a/src/uniqstr.h +++ b/src/uniqstr.h @@ -1,6 +1,6 @@ /* Keeping a unique copy of strings. - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2008, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -32,6 +32,10 @@ uniqstr uniqstr_new (char const *str); /* Two uniqstr values have the same value iff they are the same. */ #define UNIQSTR_EQ(USTR1, USTR2) ((USTR1) == (USTR2)) +/* Compare two uniqstr a la strcmp: negative for <, nul for =, and + positive for >. Undefined order, relies on addresses. */ +#define UNIQSTR_CMP(USTR1, USTR2) ((USTR1) - (USTR2)) + /*--------------------------------------. | Initializing, destroying, debugging. | `--------------------------------------*/ diff --git a/tests/input.at b/tests/input.at index 24365e65..8af1d1fa 100644 --- a/tests/input.at +++ b/tests/input.at @@ -691,8 +691,10 @@ start: HEXADECIMAL_1 HEXADECIMAL_2 ]]) AT_BISON_CHECK([input.y], [1], [], -[[input.y:12.12-20: tokens HEXADECIMAL_2 and DECIMAL_2 both assigned number 16702650 -input.y:9.8-20: tokens DECIMAL_1 and HEXADECIMAL_1 both assigned number 11259375 +[[input.y:10.12-20: user token number 11259375 redeclaration for DECIMAL_1 +input.y:9.8-20: previous declaration for HEXADECIMAL_1 +input.y:12.12-20: user token number 16702650 redeclaration for DECIMAL_2 +input.y:11.8-20: previous declaration for HEXADECIMAL_2 ]]) AT_DATA_GRAMMAR([input.y], From 66ed97537a312d452206984f603cac15209f3c97 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Wed, 10 Jun 2009 20:14:52 +0200 Subject: [PATCH 094/404] deterministic test suite. Some consistency checks on symbols are performed after all the symbols were read, by an iteration over the symbol table. This traversal is nondeterministic, which can be a problem for test cases. Avoid this. Addresses another form of nondeterminism reported by Joel E. Denny. http://lists.gnu.org/archive/html/bison-patches/2009-05/msg00023.html * tests/input.at (Numbered tokens): Split the hexadecimal/decimal test in two. Use different file names for the three tests to make the maintenance easier. --- ChangeLog | 16 ++++++++++++++++ tests/input.at | 41 +++++++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index a8c6c588..ad778488 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2009-06-10 Akim Demaille + + deterministic test suite. + Some consistency checks on symbols are performed after all the + symbols were read, by an iteration over the symbol table. This + traversal is nondeterministic, which can be a problem for test + cases. + Avoid this. + Addresses another form of nondeterminism reported by Joel E. Denny. + http://lists.gnu.org/archive/html/bison-patches/2009-05/msg00023.html + + * tests/input.at (Numbered tokens): Split the hexadecimal/decimal + test in two. + Use different file names for the three tests to make the + maintenance easier. + 2009-06-10 Akim Demaille deterministic user-token-number redeclaration errors. diff --git a/tests/input.at b/tests/input.at index 8af1d1fa..f62a68d3 100644 --- a/tests/input.at +++ b/tests/input.at @@ -680,24 +680,33 @@ AT_CLEANUP AT_SETUP([Numbered tokens]) -AT_DATA_GRAMMAR([input.y], -[[%token HEXADECIMAL_1 0xabcdef - DECIMAL_1 11259375 -%token HEXADECIMAL_2 0XFEDCBA - DECIMAL_2 16702650 -%% -start: HEXADECIMAL_1 HEXADECIMAL_2 +AT_DATA_GRAMMAR([1.y], +[[%token DECIMAL 11259375 + HEXADECIMAL 0xabcdef %% +start: DECIMAL; ]]) -AT_BISON_CHECK([input.y], [1], [], -[[input.y:10.12-20: user token number 11259375 redeclaration for DECIMAL_1 -input.y:9.8-20: previous declaration for HEXADECIMAL_1 -input.y:12.12-20: user token number 16702650 redeclaration for DECIMAL_2 -input.y:11.8-20: previous declaration for HEXADECIMAL_2 +AT_BISON_CHECK([1.y], [1], [], +[[1.y:10.10-20: user token number 11259375 redeclaration for HEXADECIMAL +1.y:9.8-14: previous declaration for DECIMAL ]]) -AT_DATA_GRAMMAR([input.y], + +AT_DATA_GRAMMAR([2.y], +[[%token HEXADECIMAL 0xabcdef + DECIMAL 11259375 +%% +start: HEXADECIMAL; +]]) + +AT_BISON_CHECK([2.y], [1], [], +[[2.y:10.10-16: user token number 11259375 redeclaration for DECIMAL +2.y:9.8-18: previous declaration for HEXADECIMAL +]]) + + +AT_DATA_GRAMMAR([3.y], [[%token TOO_LARGE_DEC 999999999999999999999 TOO_LARGE_HEX 0xFFFFFFFFFFFFFFFFFFF %% @@ -705,9 +714,9 @@ start: TOO_LARGE_DEC TOO_LARGE_HEX %% ]]) -AT_BISON_CHECK([input.y], [1], [], -[[input.y:9.22-42: integer out of range: `999999999999999999999' -input.y:10.24-44: integer out of range: `0xFFFFFFFFFFFFFFFFFFF' +AT_BISON_CHECK([3.y], [1], [], +[[3.y:9.22-42: integer out of range: `999999999999999999999' +3.y:10.24-44: integer out of range: `0xFFFFFFFFFFFFFFFFFFF' ]]) AT_CLEANUP From cc96d8ff98766b22f1612dbd960887a8608e01a8 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 11 Jun 2009 15:24:13 +0200 Subject: [PATCH 095/404] gnulib: update. --- gnulib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnulib b/gnulib index 5a1286a9..7df78375 160000 --- a/gnulib +++ b/gnulib @@ -1 +1 @@ -Subproject commit 5a1286a9f8597c0063a82645b55f3e97433fc521 +Subproject commit 7df783756914870b1aa88754d327b6b62f45f2df From 75c7a52a31b784ec26dc09f54934cf7aaf91c8eb Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 11 Jun 2009 14:42:12 +0200 Subject: [PATCH 096/404] hash: check insertion for memory exhaustion. * src/muscle-tab.c (muscle_insert, muscle_grow) * src/state.c (state_hash_insert): Check the return value of hash_insert. --- ChangeLog | 7 +++++++ src/muscle_tab.c | 6 ++++-- src/state.c | 3 ++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad778488..ebe13d3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-06-11 Akim Demaille + + hash: check insertion for memory exhaustion. + * src/muscle-tab.c (muscle_insert, muscle_grow) + * src/state.c (state_hash_insert): Check the return value of + hash_insert. + 2009-06-10 Akim Demaille deterministic test suite. diff --git a/src/muscle_tab.c b/src/muscle_tab.c index cfddbcf3..c25b519d 100644 --- a/src/muscle_tab.c +++ b/src/muscle_tab.c @@ -120,7 +120,8 @@ muscle_insert (char const *key, char const *value) /* First insertion in the hash. */ entry = xmalloc (sizeof *entry); entry->key = key; - hash_insert (muscle_table, entry); + if (!hash_insert (muscle_table, entry)) + xalloc_die (); } else free (entry->storage); @@ -149,7 +150,8 @@ muscle_grow (const char *key, const char *val, const char *separator) /* First insertion in the hash. */ entry = xmalloc (sizeof *entry); entry->key = key; - hash_insert (muscle_table, entry); + if (!hash_insert (muscle_table, entry)) + xalloc_die (); entry->value = entry->storage = xstrdup (val); } else diff --git a/src/state.c b/src/state.c index a0f5cdb8..b5cd6a32 100644 --- a/src/state.c +++ b/src/state.c @@ -379,7 +379,8 @@ state_hash_free (void) void state_hash_insert (state *s) { - hash_insert (state_table, s); + if (!hash_insert (state_table, s)) + xalloc_die (); } From 517cb0ad9ce09b59b6e41d1a657e8c5aa00e4755 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 11 Jun 2009 14:45:10 +0200 Subject: [PATCH 097/404] xml: beware of user strings used to give a %prec to rules. * tests/conflicts.at (%prec with user strings): New. * src/gram.c (grammar_rules_print_xml): Escape the precedence for XML output. --- ChangeLog | 7 +++++++ src/gram.c | 5 +++-- tests/conflicts.at | 23 ++++++++++++++++++++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index ebe13d3a..68599de6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-06-11 Akim Demaille + + xml: beware of user strings used to give a %prec to rules. + * tests/conflicts.at (%prec with user strings): New. + * src/gram.c (grammar_rules_print_xml): Escape the precedence for + XML output. + 2009-06-11 Akim Demaille hash: check insertion for memory exhaustion. diff --git a/src/gram.c b/src/gram.c index 6b9eda13..243b07f0 100644 --- a/src/gram.c +++ b/src/gram.c @@ -1,7 +1,7 @@ /* Allocate input grammar variables for Bison. Copyright (C) 1984, 1986, 1989, 2001, 2002, 2003, 2005, 2006 - 2007 Free Software Foundation, Inc. + 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -224,7 +224,8 @@ grammar_rules_print_xml (FILE *out, int level) fprintf (out, "tag); + fprintf (out, " percent_prec=\"%s\"", + xml_escape (rules[r].precsym->tag)); fputs (">\n", out); } rule_lhs_print_xml (&rules[r], out, level + 3); diff --git a/tests/conflicts.at b/tests/conflicts.at index 78a90ad0..bf854e8e 100644 --- a/tests/conflicts.at +++ b/tests/conflicts.at @@ -544,9 +544,26 @@ input.y: expected 0 reduce/reduce conflicts AT_CLEANUP -## ------------------------------- ## -## %no-default-prec without %prec ## -## ------------------------------- ## +## ------------------------- ## +## %prec with user strings. ## +## ------------------------- ## + +AT_SETUP([%prec with user string]) + +AT_DATA([[input.y]], +[[%% +exp: + "foo" %prec "foo" +; +]]) + +AT_BISON_CHECK([-o input.c input.y]) +AT_CLEANUP + + +## -------------------------------- ## +## %no-default-prec without %prec. ## +## -------------------------------- ## AT_SETUP([%no-default-prec without %prec]) From 83b66dddb649f9bc5331970c0a1ef82396715e86 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 11 Jun 2009 14:50:25 +0200 Subject: [PATCH 098/404] style changes. * data/xslt/xml2dot.xsl, data/xslt/xml2xhtml.xsl: Space changes. * src/print-xml.c: Style changes. * tests/conflicts.at: Comment changes. --- ChangeLog | 7 +++++++ data/xslt/xml2dot.xsl | 8 ++++---- data/xslt/xml2xhtml.xsl | 8 ++++---- src/print-xml.c | 9 +++++---- tests/conflicts.at | 18 +++++++++--------- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 68599de6..c3333b9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-06-11 Akim Demaille + + style changes. + * data/xslt/xml2dot.xsl, data/xslt/xml2xhtml.xsl: Space changes. + * src/print-xml.c: Style changes. + * tests/conflicts.at: Comment changes. + 2009-06-11 Akim Demaille xml: beware of user strings used to give a %prec to rules. diff --git a/data/xslt/xml2dot.xsl b/data/xslt/xml2dot.xsl index 130692e3..aa9bde0a 100644 --- a/data/xslt/xml2dot.xsl +++ b/data/xslt/xml2dot.xsl @@ -3,7 +3,7 @@