Hi Kaz, I guess this example can be used as a basis to discuss of "one feature at a time", as I mentioned in the other thread.
I fully disagree with what you are doing here. You completely discard features that have been designed to address your exact needs: specifying what goes into the headers. That's the point of "%code requires" and "provides", introduced in Bison 2.4 (that's twelve years ago!). These features are so obviously needed that even Byacc features them now. The following commit shows how this example should look like. I've made it available as https://github.com/akimd/bison/tree/kaz if you want an easier access. You can easily replace the hand-written parser.h with the generated header. Cheers! commit 47d1c4f18b3695add59ad7eef70637931ee607e6 Author: Akim Demaille <[email protected]> Date: Sat Sep 19 11:27:45 2020 +0200 examples: fix Kaz's example * examples/c/buildscenario/parser.h: We don't need this file, it should be just the file generated by Bison. But meanwhile, just include the generated header. * examples/c/buildscenario/local.mk: Stop playing workaround, play straight. * examples/c/buildscenario/parser.y: Use %code requires and provides to define the pieces that go into the generated header. examples/c/buildscenario/local.mk | 7 +------ examples/c/buildscenario/main.c | 1 + examples/c/buildscenario/parser.h | 24 +----------------------- examples/c/buildscenario/parser.y | 52 +++++++++++++++++++++++++++++----------------------- 4 files changed, 32 insertions(+), 52 deletions(-) diff --git a/examples/c/buildscenario/local.mk b/examples/c/buildscenario/local.mk index 44d89ce2..c1ae9159 100644 --- a/examples/c/buildscenario/local.mk +++ b/examples/c/buildscenario/local.mk @@ -39,12 +39,7 @@ if COMPILER_IS_GCC endif %D%/y.tab.c: %D%/parser.y - $(BISON) --yacc -Wno-yacc -Wno-deprecated -v -d $< - @# workaround for Bison 3.x: yyparse declared in y.tab.h - sed -e /yyparse/d < y.tab.h > y.tab.h.tmp - mv y.tab.h.tmp %D%/y.tab.h - mv y.tab.c %D%/y.tab.c - mv y.output %D%/y.output + $(BISON) --yacc -Wno-yacc -Wno-deprecated -v -d -o$@ $< %D%/main.o: %D%/parser.h diff --git a/examples/c/buildscenario/parser.h b/examples/c/buildscenario/parser.h index 75fc971f..465326c6 100644 --- a/examples/c/buildscenario/parser.h +++ b/examples/c/buildscenario/parser.h @@ -16,27 +16,5 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -typedef struct yyguts_t scanner_t; -typedef struct parser parser_t; -typedef void *yyscan_t; -#ifdef SPACE /* If y.tab.h has been included ... */ - -struct token { - YYSTYPE yy_lval; -}; - -struct parser { - scanner_t *scanner; - struct token tok; - void *ast; -}; - -int yylex(YYSTYPE *yylval_param, yyscan_t yyscanner); - -#endif - -void yyerror(scanner_t *scanner, parser_t *, const char *s); -void parser_func(scanner_t *s, parser_t *p); -parser_t *parser_create(void); -int parse(parser_t *); +#include "y.tab.h" diff --git a/examples/c/buildscenario/parser.y b/examples/c/buildscenario/parser.y index d4247d08..c74d396a 100644 --- a/examples/c/buildscenario/parser.y +++ b/examples/c/buildscenario/parser.y @@ -17,32 +17,32 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -%{ - -/* - * These headers must be in that order because "parser.h" needs YYSTYPE in - * order to define the parser structure. But parser.h also defines the types - * that are required for Bison's yyparse declaration in y.tab.h to work. - * The solution is the hack in the Makefile to remove the yyparse declaration. - */ -#include "y.tab.h" -#include "parser.h" - -/* - * Byacc doesn't need the following at all. We need to add it for Bison - * because we stripped the yyparse declaration from y.tab.h in the Makefile. - */ -#if YYBISON -int yyparse(scanner_t *, parser_t *); -#endif +%code requires { + + typedef struct yyguts_t scanner_t; + typedef struct parser parser_t; + typedef void *yyscan_t; -void parser_func(scanner_t *s, parser_t *p) -{ - (void) s; - (void) p; } -%} +%code provides { + struct token { + YYSTYPE yy_lval; + }; + + struct parser { + scanner_t *scanner; + struct token tok; + void *ast; + }; + + int yylex(YYSTYPE *yylval_param, yyscan_t yyscanner); + + void yyerror(scanner_t *scanner, parser_t *, const char *s); + void parser_func(scanner_t *s, parser_t *p); + parser_t *parser_create(void); + int parse(parser_t *); +} %pure-parser %parse-param{scanner_t *scnr} @@ -63,6 +63,12 @@ top : SPACE { $$ = $1; parser->ast = 0; } %% +void parser_func(scanner_t *s, parser_t *p) +{ + (void) s; + (void) p; +} + int yylex(YYSTYPE *yyparam, yyscan_t scanner) { yyparam->val = 42;
