From da402d1caef3f4a849cefe516780d7a3cf61811f Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Wed, 20 Jun 2012 10:02:11 +0200 Subject: [PATCH 01/11] maint: regen. * Makefile.am (regen): New target. (cherry picked from commit 71bff31edd4ddbfe3c350933652bb0e3a4a7f3e2) --- cfg.mk | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cfg.mk b/cfg.mk index c56e965b..31a2532f 100644 --- a/cfg.mk +++ b/cfg.mk @@ -14,6 +14,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +# Update version, then recompile so that tests/bison --version be +# up-to-date, then compile our parser again with our up-to-date bison. +.PHONY: regen +regen: _version + $(MAKE) $(AM_MAKEFLAGS) + touch $(srcdir)/src/parse-gram.y + $(MAKE) $(AM_MAKEFLAGS) + # Used in maint.mk's web-manual rule manual_title = The Yacc-compatible Parser Generator From 18ad57b384e164c337e735df2f0ed0fe3c51fbf5 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 17 Jun 2012 10:54:15 +0200 Subject: [PATCH 02/11] news: condemn YYPARSE_PARAM and YYLEX_PARAM. * NEWS: here. (Bison 1.875): Add %parse-param and %lex-param. * doc/bison.texinfo: Spello. --- NEWS | 33 +++++++++++++++++++++++++++++++-- doc/bison.texinfo | 2 +- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 9c5d67b7..72e4b6b3 100644 --- a/NEWS +++ b/NEWS @@ -5,8 +5,10 @@ GNU Bison NEWS ** Future changes: The next major release will drop support for generating parsers in K&R C, - and remove the definition of yystype (removal announced since Bison - 1.875). + and remove the definitions of yystype and yyltype (removal announced since + Bison 1.875). YYPARSE_PARAM and YYLEX_PARAM, which were deprecated in + favor of %parse-param and %lex-param (introduced in Bison 1.875 too), will + no longer be supported. ** The generated header is included (yacc.c) @@ -1202,6 +1204,33 @@ GNU Bison NEWS - "parsing stack overflow..." -> "parser stack overflow" GLR parsers now report "parser stack overflow" as per the Bison manual. +** %parse-param and %lex-param + The macros YYPARSE_PARAM and YYLEX_PARAM provide a means to pass + additional context to yyparse and yylex. They suffer from several + shortcomings: + + - a single argument only can be added, + - their types are weak (void *), + - this context is not passed to anciliary functions such as yyerror, + - only yacc.c parsers support them. + + The new %parse-param/%lex-param directives provide a more precise control. + For instance: + + %parse-param {int *nastiness} + %lex-param {int *nastiness} + %parse-param {int *randomness} + + results in the following signatures: + + int yylex (int *nastiness); + int yyparse (int *nastiness, int *randomness); + + or, if both %pure-parser and %locations are used: + + int yylex (YYSTYPE *lvalp, YYLTYPE *llocp, int *nastiness); + int yyparse (int *nastiness, int *randomness); + ** 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. diff --git a/doc/bison.texinfo b/doc/bison.texinfo index 97b32734..4f2e1c62 100644 --- a/doc/bison.texinfo +++ b/doc/bison.texinfo @@ -6011,7 +6011,7 @@ For instance: @end example @noindent -results in the following signature: +results in the following signatures: @example int yylex (int *nastiness); From 756257ee865621a8ddce34900043aee1da27d242 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 17 Jun 2012 12:10:44 +0200 Subject: [PATCH 03/11] c skeletons: factor the declaration of yylloc and yylval. There is one difference: now, even without --defines, we generate extern declarations for these variables. The factoring is worth it. * data/c.m4 (b4_declare_yylstype): Declare them. * data/glr.c, data/yacc.c: Adjust. --- data/c.m4 | 7 +++++-- data/glr.c | 2 -- data/yacc.c | 2 -- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/data/c.m4 b/data/c.m4 index 78b12325..8c6c4979 100644 --- a/data/c.m4 +++ b/data/c.m4 @@ -537,8 +537,8 @@ b4_locations_if([, yylocationp])[]b4_user_args[); # b4_declare_yylstype # ------------------ -# Declaration that might either go into the header (if --defines) -# or open coded in the parser body. Declare YYSTYPE and YYLTYPE. +# Declarations that might either go into the header (if --defines) or +# in the parser body. Declare YYSTYPE/YYLTYPE, and yylval/yylloc. m4_define([b4_declare_yylstype], [[#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED ]m4_ifdef([b4_stype], @@ -566,6 +566,9 @@ typedef struct YYLTYPE # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif]]) + +b4_pure_if([], [[extern YYSTYPE ]b4_prefix[lval; +]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])[]dnl ]) # b4_declare_yydebug diff --git a/data/glr.c b/data/glr.c index 9bbf9a72..100a5f2e 100644 --- a/data/glr.c +++ b/data/glr.c @@ -2635,8 +2635,6 @@ b4_copyright([Skeleton interface for Bison GLR parsers in C], ]b4_cpp_guard_open([b4_spec_defines_file])[ ]b4_shared_declarations[ -]b4_pure_if([], [[extern YYSTYPE ]b4_prefix[lval; -]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])[ ]b4_cpp_guard_close([b4_spec_defines_file])[ ]])]) m4_divert_pop(0) diff --git a/data/yacc.c b/data/yacc.c index 30c5f672..bd1a4b79 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -2067,8 +2067,6 @@ b4_copyright([Bison interface for Yacc-like parsers in C], ]b4_cpp_guard_open([b4_spec_defines_file])[ ]b4_shared_declarations[ -]b4_pure_if([], [[extern YYSTYPE ]b4_prefix[lval; -]b4_locations_if([[extern YYLTYPE ]b4_prefix[lloc;]])])[ ]b4_cpp_guard_close([b4_spec_defines_file])[ ]])dnl b4_defines_if m4_divert_pop(0) From 2d40532bf5d7867229bbe3f1052dcc0469745e00 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 17 Jun 2012 20:39:17 +0200 Subject: [PATCH 04/11] tests: AT_LANG. * tests/local.at (AT_BISON_OPTION_PUSHDEFS, AT_BISON_OPTION_POPDEFS): Define/undefine AT_LANGE (AT_LANG_COMPILE): New. (AT_FULL_COMPILE): Use AT_LANG. --- tests/local.at | 63 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/tests/local.at b/tests/local.at index 6d3ff18f..6936d914 100644 --- a/tests/local.at +++ b/tests/local.at @@ -108,6 +108,10 @@ m4_pushdef([AT_SKEL_CC_IF], [m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])]) m4_pushdef([AT_SKEL_JAVA_IF], [m4_bmatch([$3], [%language "[Jj][Aa][Vv][Aa]"\|%skeleton "[a-z0-9]+\.java"], [$1], [$2])]) +m4_pushdef([AT_LANG], +[AT_SKEL_JAVA_IF([java], + [AT_SKEL_CC_IF([cxx], + [c])])]) m4_pushdef([AT_GLR_IF], [m4_bmatch([$3], [%glr-parser\|%skeleton "glr\..*"], [$1], [$2])]) m4_pushdef([AT_LALR1_CC_IF], @@ -217,6 +221,7 @@ m4_popdef([AT_LEXPARAM_IF]) m4_popdef([AT_YACC_IF]) m4_popdef([AT_GLR_IF]) m4_popdef([AT_SKEL_CC_IF]) +m4_popdef([AT_LANG]) m4_popdef([AT_SKEL_JAVA_IF]) m4_popdef([AT_GLR_CC_IF]) m4_popdef([AT_LALR1_CC_IF]) @@ -519,6 +524,16 @@ AT_CHECK([[test -n "$CONF_JAVA" || exit 77 AT_CHECK([[$SHELL ../../../javacomp.sh ]$1], [[0]], [ignore], [ignore])]) +# AT_LANG_COMPILE(OUTPUT, [SOURCES = OUTPUT.c] +# -------------------------------------------- +m4_define([AT_LANG_COMPILE], +[m4_case(AT_LANG, +[c], [AT_COMPILE([$1], [$2])], +[cxx], [AT_COMPILE_CXX([$1], [$2])], +[java], [AT_JAVA_COMPILE([$1.java], [$2])], + [m4_fatal([unknown language: ]m4_defn([AT_LANG]))])[]dnl +]) + # AT_FULL_COMPILE(OUTPUT, [OTHER1], [OTHER2]) # ------------------------------------------- # Compile OUTPUT.y to OUTPUT.c, OUTPUT.cc, or OUTPUT.java, and then @@ -526,31 +541,29 @@ AT_CHECK([[$SHELL ../../../javacomp.sh ]$1], # OUTPUT-OTHER.c, OUTPUT-OTHER.cc, or OUTPUT-OTHER.java to OUTPUT or # OUTPUT.java along with it. Relies on AT_SKEL_CC_IF and # AT_SKEL_JAVA_IF. -m4_define([AT_FULL_COMPILE], [ - AT_SKEL_JAVA_IF([ - AT_BISON_CHECK([-o $1.java $1.y]) - AT_JAVA_COMPILE([$1.java], - m4_join([ ], - [$1.java], - m4_ifval($2, [[$1-$2.java]]), - m4_ifval($3, [[$1-$3.java]]))) - ], [ - AT_SKEL_CC_IF([ - AT_BISON_CHECK([-o $1.cc $1.y]) - AT_COMPILE_CXX([$1], - m4_join([ ], - [$1.cc], - m4_ifval($2, [[$1-$2.cc]]), - m4_ifval($3, [[$1-$3.cc]]))) - ], [ - AT_BISON_CHECK([-o $1.c $1.y]) - AT_COMPILE([$1], - m4_join([ ], - [$1.c], - m4_ifval($2, [[$1-$2.c]]), - m4_ifval($3, [[$1-$3.c]]))) - ]) - ]) +m4_define([AT_FULL_COMPILE], +[m4_case(AT_LANG, +[java], + [AT_BISON_CHECK([-o $1.java $1.y]) + AT_LANG_COMPILE([$1], + m4_join([ ], + [$1.java], + m4_ifval($2, [[$1-$2.java]]), + m4_ifval($3, [[$1-$3.java]])))], +[cxx], + [AT_BISON_CHECK([-o $1.cc $1.y]) + AT_LANG_COMPILE([$1], + m4_join([ ], + [$1.cc], + m4_ifval($2, [[$1-$2.cc]]), + m4_ifval($3, [[$1-$3.cc]])))], +[c], + [AT_BISON_CHECK([-o $1.c $1.y]) + AT_LANG_COMPILE([$1], + m4_join([ ], + [$1.c], + m4_ifval($2, [[$1-$2.c]]), + m4_ifval($3, [[$1-$3.c]])))]) ]) From 6e2d7b0974f44053d4425baf5195a84013292262 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sun, 17 Jun 2012 12:12:52 +0200 Subject: [PATCH 05/11] skeletons: minor style changes * data/glr.c, data/yacc.c: here. --- data/glr.c | 22 +++++++++++----------- data/yacc.c | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/data/glr.c b/data/glr.c index 100a5f2e..4d0a1bcb 100644 --- a/data/glr.c +++ b/data/glr.c @@ -187,17 +187,17 @@ b4_copyright([Skeleton implementation for Bison GLR parsers in C], ]b4_identification -b4_percent_code_get([[top]])[]dnl -m4_if(b4_prefix, [yy], [], -[/* Substitute the variable and function names. */ -#define yyparse b4_prefix[]parse -#define yylex b4_prefix[]lex -#define yyerror b4_prefix[]error -#define yylval b4_prefix[]lval -#define yychar b4_prefix[]char -#define yydebug b4_prefix[]debug -#define yynerrs b4_prefix[]nerrs -#define yylloc b4_prefix[]lloc])[ +b4_percent_code_get([[top]])[ +]m4_if(b4_prefix, [yy], [], +[[/* Substitute the variable and function names. */ +#define yyparse ]b4_prefix[parse +#define yylex ]b4_prefix[lex +#define yyerror ]b4_prefix[error +#define yylval ]b4_prefix[lval +#define yychar ]b4_prefix[char +#define yydebug ]b4_prefix[debug +#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[ +#define yylloc ]b4_prefix[lloc]])])[ /* Copy the first part of user declarations. */ ]b4_user_pre_prologue[ diff --git a/data/yacc.c b/data/yacc.c index bd1a4b79..400c68ce 100644 --- a/data/yacc.c +++ b/data/yacc.c @@ -316,8 +316,8 @@ m4_if(b4_prefix, [yy], [], #define yylval ]b4_prefix[lval #define yychar ]b4_prefix[char #define yydebug ]b4_prefix[debug -#define yynerrs ]b4_prefix[nerrs -]b4_locations_if([[#define yylloc ]b4_prefix[lloc]])])[ +#define yynerrs ]b4_prefix[nerrs]b4_locations_if([[ +#define yylloc ]b4_prefix[lloc]])])[ /* Copy the first part of user declarations. */ ]b4_user_pre_prologue[ From 290a8ff2c09fba654b6746caab26a1b6e1c866b1 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 21 Jun 2012 18:26:44 +0200 Subject: [PATCH 06/11] tests: factor. * tests/glr-regression.at, tests/output.at, tests/push.at, * tests/regression.at, tests/torture.at, tests/actions.at: Use AT_YYLEX_* and AT_YYERROR_*. --- tests/actions.at | 8 +------- tests/glr-regression.at | 40 ++++++------------------------------- tests/output.at | 8 +++++--- tests/push.at | 40 ++++++++++++++----------------------- tests/regression.at | 25 +++++------------------ tests/torture.at | 44 +++++++++++++---------------------------- 6 files changed, 46 insertions(+), 119 deletions(-) diff --git a/tests/actions.at b/tests/actions.at index cfac2992..5efc043d 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -150,14 +150,8 @@ two: { $$.val = 2; } ; sum: { printf ("%d\n", $0.val + $-1.val + $-2.val); } ; %% - -static int -yylex (void) -{ - return 0; -} - ]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE()[ int main (void) { diff --git a/tests/glr-regression.at b/tests/glr-regression.at index 9c534631..479303df 100644 --- a/tests/glr-regression.at +++ b/tests/glr-regression.at @@ -35,8 +35,8 @@ AT_DATA_GRAMMAR([glr-regr1.y], #define YYSTYPE int static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1); -]AT_YYLEX_DECLARE[ ]AT_YYERROR_DECLARE[ +]AT_YYLEX_DECLARE[ %} @@ -128,8 +128,8 @@ AT_DATA_GRAMMAR([glr-regr2a.y], #include #include #include - ]AT_YYLEX_DECLARE[ ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ %} %glr-parser @@ -519,18 +519,8 @@ AT_DATA_GRAMMAR([glr-regr6.y], start: 'a' | 'a' ; %% - -static int -yylex (void) -{ - static char const input[] = "a"; - static size_t toknum; - if (! (toknum < sizeof input)) - abort (); - return input[toknum++]; -} - ]AT_YYERROR_DEFINE[ +]AT_YYLEX_DEFINE(a)[ int main (void) { @@ -657,7 +647,6 @@ AT_DATA_GRAMMAR([glr-regr8.y], #include ]AT_YYERROR_DECLARE[ ]AT_YYLEX_DECLARE[ - ]AT_YYERROR_DECLARE[ %} %token T_CONSTANT @@ -845,16 +834,8 @@ start: ; %% - ]AT_YYERROR_DEFINE[ -static int -yylex (void) -{ - static int called; - if (called++) - abort (); - return 0; -} +]AT_YYLEX_DEFINE()[ int main (void) @@ -1468,16 +1449,8 @@ ambiguity1: ; ambiguity2: ; %% - ]AT_YYERROR_DEFINE[ -static int -yylex (void) -{ - static int called; - if (called++) - abort (); - return 0; -} +]AT_YYLEX_DEFINE()[ int main (void) @@ -1675,7 +1648,7 @@ AT_DATA_GRAMMAR([glr-regr18.y], %{ #include ]AT_YYERROR_DECLARE[ - static int yylex (); + ]AT_YYLEX_DECLARE[ %} %union { @@ -1695,7 +1668,6 @@ sym3: %merge { $$ = 0; } ; %type sym3; %% - ]AT_YYERROR_DEFINE[ ]AT_YYLEX_DEFINE()[ int diff --git a/tests/output.at b/tests/output.at index 058ae89a..f7a7d8e5 100644 --- a/tests/output.at +++ b/tests/output.at @@ -176,10 +176,11 @@ AT_CHECK_CONFLICTING_OUTPUT([foo.y], [], [-o foo.y], # AT_CHECK_OUTPUT_FILE_NAME(FILE-NAME-PREFIX, [ADDITIONAL-TESTS]) -# ----------------------------------------------------------------------------- +# --------------------------------------------------------------- m4_define([AT_CHECK_OUTPUT_FILE_NAME], [AT_SETUP([Output file name: $1]) +AT_BISON_OPTION_PUSHDEFS # Skip if platform doesn't support file name. For example, Cygwin # doesn't support file names containing ":" or "\". AT_CHECK([[touch "]AS_ESCAPE([$1[.tmp]])[" || exit 77]]) @@ -187,8 +188,8 @@ AT_CHECK([[touch "]AS_ESCAPE([$1[.tmp]])[" || exit 77]]) AT_DATA_GRAMMAR([glr.y], [[%glr-parser %code { - int yylex (void); - void yyerror (const char *); +]AT_YYERROR_DECLARE_EXTERN[ +]AT_YYLEX_DECLARE_EXTERN[ } %% start: {}; @@ -209,6 +210,7 @@ AT_CHECK([ls "AS_ESCAPE([$1.c])" "AS_ESCAPE([$1.h])"], [], [ignore]) AT_COMPILE_CXX([cxx.o], [-c "AS_ESCAPE([$1.c])"]) $2 +AT_BISON_OPTION_POPDEFS AT_CLEANUP ]) diff --git a/tests/push.at b/tests/push.at index 21322f0d..057807dd 100644 --- a/tests/push.at +++ b/tests/push.at @@ -24,17 +24,18 @@ AT_BANNER([[Push Parsing Tests]]) AT_SETUP([[Memory Leak for Early Deletion]]) # Requires Valgrind. - +AT_BISON_OPTION_PUSHDEFS AT_DATA_GRAMMAR([[input.y]], [[ %{ #include #include #define YYINITDEPTH 1 - void yyerror (char const *msg); +]AT_YYERROR_DECLARE[ %} -%define api.pure %define api.push-pull push +%define api.pure +%define api.push-pull push %% @@ -42,11 +43,7 @@ start: 'a' 'b' 'c' ; %% -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} +]AT_YYERROR_DEFINE[ int main (void) @@ -71,6 +68,7 @@ main (void) return 0; } ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[-o input.c input.y]]) AT_COMPILE([[input]]) @@ -85,13 +83,14 @@ AT_CLEANUP AT_SETUP([[Multiple impure instances]]) m4_pushdef([AT_MULTIPLE_IMPURE_INSTANCES_CHECK], [ +AT_BISON_OPTION_PUSHDEFS([%define api.push-pull $1]) AT_DATA_GRAMMAR([[input.y]], [[ %{ #include #include - void yyerror (char const *msg); - int yylex (void); +]AT_YYERROR_DECLARE[ +]m4_if([$1], [[both]], [AT_YYLEX_DECLARE([])])[ %} %define api.push-pull ]$1[ @@ -101,28 +100,16 @@ AT_DATA_GRAMMAR([[input.y]], start: ; %% - -void -yyerror (char const *msg) -{ - fprintf (stderr, "%s\n", msg); -} - -int -yylex (void) -{ - return 0; -} +]AT_YYERROR_DEFINE[ +]m4_if([$1], [[both]], [AT_YYLEX_DEFINE([])])[ int main (void) { - yypstate *ps; int i; - for (i = 0; i < 2; ++i) { - ps = yypstate_new (); + yypstate *ps = yypstate_new (); assert (ps); assert (yypstate_new () == YY_NULL); ]m4_if([$1], [[both]], [[assert (yyparse () == 2)]])[; @@ -140,6 +127,7 @@ main (void) AT_BISON_CHECK([[-o input.c input.y]]) AT_COMPILE([[input]]) AT_PARSER_CHECK([[./input]]) +AT_BISON_OPTION_POPDEFS ]) AT_MULTIPLE_IMPURE_INSTANCES_CHECK([[both]]) @@ -155,12 +143,14 @@ AT_CLEANUP AT_SETUP([[Unsupported Skeletons]]) +AT_BISON_OPTION_PUSHDEFS AT_DATA([[input.y]], [[%glr-parser %define api.push-pull push %% start: ; ]]) +AT_BISON_OPTION_POPDEFS AT_BISON_CHECK([[input.y]], [[1]], [], [[input.y:2.9-21: %define variable 'api.push-pull' is not used diff --git a/tests/regression.at b/tests/regression.at index fa93833c..5c1ad32b 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -462,11 +462,7 @@ AT_DATA_GRAMMAR([input.y], %% exp: "a" "\\\'\?\"\a\b\f\n\r\t\v\001\201\x001\x000081??!"; %% -void -yyerror (char const *s) -{ - fprintf (stderr, "%s\n", s); -} +]AT_YYERROR_DEFINE[ int yylex (void) @@ -901,15 +897,9 @@ member: STRING | INVALID ; %% -AT_LALR1_CC_IF( -[/* A C++ error reporting function. */ -void -yy::parser::error (const location&, const std::string& m) -{ - std::cerr << m << std::endl; -} - -int +AT_YYERROR_DEFINE[ +]AT_LALR1_CC_IF( +[int yyparse () { yy::parser parser; @@ -918,12 +908,7 @@ yyparse () #endif return parser.parse (); } -], -[static void -yyerror (const char *s) -{ - fprintf (stderr, "%s\n", s); -}]) +]) static int yylex (AT_LALR1_CC_IF([int *lval], [void])) diff --git a/tests/torture.at b/tests/torture.at index 313df345..a8837b22 100644 --- a/tests/torture.at +++ b/tests/torture.at @@ -56,7 +56,7 @@ print < #include - +#define MAX $max ]AT_YYLEX_DECLARE[ ]AT_YYERROR_DECLARE[ %} @@ -96,14 +96,15 @@ for my $size (1 .. $max) }; print ";\n"; -print < $max) + if (outer > MAX) return 0; else if (inner > outer) { @@ -113,13 +114,6 @@ yylex (void) } return inner++; } - -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\\n", msg); -} - int main (void) { @@ -173,7 +167,7 @@ print < #include - +#define MAX $max ]AT_YYLEX_DECLARE[ ]AT_YYERROR_DECLARE[ %} @@ -196,25 +190,20 @@ print (map { "\"$_\"" } (1 .. $max)), ";"), "\n"; -print < # include # include - +# define MAX $max ]AT_YYLEX_DECLARE[ ]AT_YYERROR_DECLARE[ %} @@ -329,16 +318,17 @@ for my $count (1 .. $max) print "n$count: token { \$\$ = $count; };\n"; }; -print < $max) + if (counter > MAX) { - if (counter++ != $max + 1) + if (counter++ != MAX + 1) abort (); return 0; } @@ -351,12 +341,6 @@ yylex (void) return counter++; } -static void -yyerror (const char *msg) -{ - fprintf (stderr, "%s\\n", msg); -} - int main (void) { From 05a7b6ec805bea91f99294f631409783a916cbd6 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Thu, 21 Jun 2012 23:05:05 +0200 Subject: [PATCH 07/11] tests: improve infrastructure * tests/local.at (AT_LANG): Use c++ instead of cxx for C++. Adjust dependencies. (AT_YYERROR_DECLARE_EXTERN, AT_YYERROR_DECLARE): Issue nothing for C++/Java. (AT_YYERROR_DEFINE): Use m4_case. (AT_JAVA_COMPILE): Use AT_SKIP_IF. --- tests/local.at | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/tests/local.at b/tests/local.at index 6936d914..4396a980 100644 --- a/tests/local.at +++ b/tests/local.at @@ -17,7 +17,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -# We want a recent Autotest. m4_version_prereq([2.58]) @@ -110,7 +109,7 @@ m4_pushdef([AT_SKEL_JAVA_IF], [m4_bmatch([$3], [%language "[Jj][Aa][Vv][Aa]"\|%skeleton "[a-z0-9]+\.java"], [$1], [$2])]) m4_pushdef([AT_LANG], [AT_SKEL_JAVA_IF([java], - [AT_SKEL_CC_IF([cxx], + [AT_SKEL_CC_IF([c++], [c])])]) m4_pushdef([AT_GLR_IF], [m4_bmatch([$3], [%glr-parser\|%skeleton "glr\..*"], [$1], [$2])]) @@ -314,28 +313,33 @@ static int # Beware that must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS # pair. m4_define([AT_YYERROR_DECLARE_EXTERN], -[void AT_API_PREFIX[]error (const char *msg);dnl +[m4_case(AT_LANG, +[c], [void AT_API_PREFIX[]error (const char *msg);])[]dnl ]) m4_define([AT_YYERROR_DECLARE], -[static AT_YYERROR_DECLARE_EXTERN[]dnl +[m4_case(AT_LANG, +[c], [static AT_YYERROR_DECLARE_EXTERN])[]dnl ]) m4_define([AT_YYERROR_DEFINE], -[AT_SKEL_JAVA_IF([[public void yyerror (String msg) -{ - System.err.println (msg); -}]], [AT_SKEL_CC_IF([[void -yy::parser::error (const yy::location &, std::string const &msg) -{ - std::cerr << msg << std::endl; -}]], [[#include +[m4_case(AT_LANG, +[c], [[#include static void ]AT_API_PREFIX[error (char const *msg) { fprintf (stderr, "%s\n", msg); -}]])])dnl -]) +}]], +[c++], [[void +]AT_NAME_PREFIX[::parser::error (const yy::location &, std::string const &msg) +{ + std::cerr << msg << std::endl; +}]], +[java], [[public void yyerror (String msg) +{ + System.err.println (msg); +}]])]) + ## --------------- ## ## Running Bison. ## @@ -519,8 +523,7 @@ AT_CHECK([$CXX $CXXFLAGS $CPPFLAGS m4_bmatch([$1], [[.]], [], [$LDFLAGS ])-o $1 # is not installed. m4_define([AT_JAVA_COMPILE], [AT_KEYWORDS(java) -AT_CHECK([[test -n "$CONF_JAVA" || exit 77 - test -n "$CONF_JAVAC" || exit 77]]) +AT_SKIP_IF([[test -z "$CONF_JAVA$CONF_JAVAC"]]) AT_CHECK([[$SHELL ../../../javacomp.sh ]$1], [[0]], [ignore], [ignore])]) @@ -529,7 +532,7 @@ AT_CHECK([[$SHELL ../../../javacomp.sh ]$1], m4_define([AT_LANG_COMPILE], [m4_case(AT_LANG, [c], [AT_COMPILE([$1], [$2])], -[cxx], [AT_COMPILE_CXX([$1], [$2])], +[c++], [AT_COMPILE_CXX([$1], [$2])], [java], [AT_JAVA_COMPILE([$1.java], [$2])], [m4_fatal([unknown language: ]m4_defn([AT_LANG]))])[]dnl ]) @@ -550,7 +553,7 @@ m4_define([AT_FULL_COMPILE], [$1.java], m4_ifval($2, [[$1-$2.java]]), m4_ifval($3, [[$1-$3.java]])))], -[cxx], +[c++], [AT_BISON_CHECK([-o $1.cc $1.y]) AT_LANG_COMPILE([$1], m4_join([ ], From eb46d61f4dacd21975156938eb83432dcc4ad720 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Fri, 22 Jun 2012 09:41:36 +0200 Subject: [PATCH 08/11] tests: fix AT_CHECK_CALC. * tests/calc.at (AT_CHECK_CALC): Contrary to its documentation, the test was skipped if given a second argument. Unused feature, remove it. --- tests/calc.at | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/calc.at b/tests/calc.at index 77f70cd3..bd52d7cb 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -518,16 +518,15 @@ AT_CHECK([cat stderr], 0, [expout]) ]) -# AT_CHECK_CALC([BISON-OPTIONS, [EXPECTED-TO-FAIL]]) -# -------------------------------------------------- +# AT_CHECK_CALC([BISON-OPTIONS]) +# ------------------------------ # Start a testing chunk which compiles `calc' grammar with # BISON-OPTIONS, and performs several tests over the parser. -# However, if EXPECTED-TO-FAIL is nonempty, this test is expected to fail. m4_define([AT_CHECK_CALC], -[# We use integers to avoid dependencies upon the precision of doubles. -AT_SETUP([Calculator $1]) +[m4_ifval([$2], [m4_fatal([$0: expected a single argument])]) -m4_ifval([$2], [AT_CHECK([exit 77])]) +# We use integers to avoid dependencies upon the precision of doubles. +AT_SETUP([Calculator $1]) AT_BISON_OPTION_PUSHDEFS([$1]) From 7490994123d5cae9ae69547f4e121b24412b2760 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Fri, 22 Jun 2012 10:20:28 +0200 Subject: [PATCH 09/11] tests: handle locations in the generic yyerror functions. * tests/local.at (AT_YYERROR_DECLARE_EXTERN, AT_YYERROR_DECLARE) (AT_YYERROR_DEFINE): Handle locations for C and C++. * tests/calc.at: Use it for C++ (as C has extra arguments which are not yet handled by AT_BISON_OPTION_PUSHDEFS). * tests/actions.at: Adjust. --- tests/actions.at | 2 +- tests/calc.at | 10 +--------- tests/local.at | 23 ++++++++++++++++++----- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/tests/actions.at b/tests/actions.at index 5efc043d..afba3f0b 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -674,7 +674,7 @@ Reading a token: Next token is token 'd' (1.4-1.4: <> printer for 'd' @ 4) Shifting token 'd' (1.4-1.4: <> printer for 'd' @ 4) Entering state 6 Reading a token: Now at end of input. -syntax error, unexpected $end, expecting 'e' +1.5-4: syntax error, unexpected $end, expecting 'e' Error: popping token 'd' (1.4-1.4: <> printer for 'd' @ 4) Stack now 0 1 3 5 Error: popping token 'c' (1.3-1.3: 'b'/'c' printer for 'c' @ 3) diff --git a/tests/calc.at b/tests/calc.at index bd52d7cb..34d2e488 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -376,15 +376,7 @@ power (int base, int exponent) return o; } ]]) - -/* A C++ error reporting function. */ -void -AT_NAME_PREFIX::parser::error (const location_type& l, const std::string& m) -{ - (void) l; - std::cerr << AT_LOCATION_IF([l << ": " << ])m << std::endl; -} -], +AT_YYERROR_DEFINE], [/* A C error reporting function. */ static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ]) diff --git a/tests/local.at b/tests/local.at index 4396a980..b945968e 100644 --- a/tests/local.at +++ b/tests/local.at @@ -314,7 +314,7 @@ static int # pair. m4_define([AT_YYERROR_DECLARE_EXTERN], [m4_case(AT_LANG, -[c], [void AT_API_PREFIX[]error (const char *msg);])[]dnl +[c], [void AT_API_PREFIX[]error (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])[const char *msg);])[]dnl ]) m4_define([AT_YYERROR_DECLARE], @@ -325,15 +325,28 @@ m4_define([AT_YYERROR_DECLARE], m4_define([AT_YYERROR_DEFINE], [m4_case(AT_LANG, [c], [[#include +/* A C error reporting function. */ static void -]AT_API_PREFIX[error (char const *msg) +yyerror (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])[const char *msg) { +]AT_YYERROR_SEES_LOC_IF([[ + fprintf (stderr, "%d.%d", + ]AT_LOC_FIRST_LINE[, ]AT_LOC_FIRST_COLUMN[); + if (]AT_LOC_FIRST_LINE[ != ]AT_LOC_LAST_LINE[) + fprintf (stderr, "-%d.%d", + ]AT_LOC_LAST_LINE[, ]AT_LOC_LAST_COLUMN[ - 1); + else if (]AT_LOC_FIRST_COLUMN[ != ]AT_LOC_LAST_COLUMN[ - 1) + fprintf (stderr, "-%d", + ]AT_LOC_LAST_COLUMN[ - 1); + fprintf (stderr, ": ");]])[ fprintf (stderr, "%s\n", msg); }]], -[c++], [[void -]AT_NAME_PREFIX[::parser::error (const yy::location &, std::string const &msg) +[c++], [[/* A C++ error reporting function. */ +void +]AT_NAME_PREFIX[::parser::error (const location_type& l, const std::string& m) { - std::cerr << msg << std::endl; + (void) l; + std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl; }]], [java], [[public void yyerror (String msg) { From 6d55954743c7243ba46680f368c76ee70b1112f8 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Fri, 22 Jun 2012 11:34:37 +0200 Subject: [PATCH 10/11] tests: handle locations in a more generic way. * tests/local.at (AT_YYERROR_PROTOTYPE): New. Use it. * tests/cxx-type.at: Extensive revamp to use a more traditional quotation scheme, and to use the generic yyerror implementation. Prefer Autotest macros to CPP macros. * tests/java.at: . --- tests/cxx-type.at | 110 ++++++++++++++++++++-------------------------- tests/java.at | 20 +++------ tests/local.at | 36 ++++++++++----- 3 files changed, 77 insertions(+), 89 deletions(-) diff --git a/tests/cxx-type.at b/tests/cxx-type.at index 746d05a4..e6fd8a85 100644 --- a/tests/cxx-type.at +++ b/tests/cxx-type.at @@ -23,15 +23,15 @@ AT_BANNER([[C++ Type Syntax (GLR).]]) # and with RESOLVE1 and RESOLVE2 as annotations on the conflicted rule for # stmt. Then compile the result. m4_define([_AT_TEST_GLR_CXXTYPES], -[ -AT_BISON_OPTION_PUSHDEFS([$1]) +[AT_BISON_OPTION_PUSHDEFS([%glr-parser $1]) AT_DATA_GRAMMAR([types.y], [[/* Simplified C++ Type and Expression Grammar. */ $1 -%{ +%code requires +{ #include union Node { struct { @@ -51,33 +51,22 @@ $1 } term; }; typedef union Node Node; + #define YYSTYPE Node * +} + +%code +{ static Node *new_nterm (char const *, Node *, Node *, Node *); static Node *new_term (char *); static void free_node (Node *); static char *node_to_string (Node *); - #define YYSTYPE Node * ]m4_bmatch([$2], [stmtMerge], [ static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1);])[ #define YYINITDEPTH 10 #define YYSTACKEXPANDABLE 1 - struct YYLTYPE; -#if YYPURE -# if YYLSP_NEEDED -# define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp -# define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s -# else -# define LEX_PARAMETERS YYSTYPE *lvalp -# endif -#endif -#ifndef LEX_PARAMETERS -# define LEX_PARAMETERS void -#endif -#ifndef ERROR_PARAMETERS -# define ERROR_PARAMETERS char const *s -#endif - int yylex (LEX_PARAMETERS); - void yyerror (ERROR_PARAMETERS); -%} + ]AT_YYERROR_DECLARE[ + ]AT_YYLEX_DECLARE[ +} %token TYPENAME ID @@ -144,8 +133,10 @@ main (int argc, char **argv) return yyparse (); } +]AT_YYERROR_DEFINE[ + int -yylex (LEX_PARAMETERS) +yylex (]AT_LEX_FORMALS[) { char buffer[256]; int c; @@ -181,11 +172,9 @@ yylex (LEX_PARAMETERS) break; default: { - int tok; -#if YYLSP_NEEDED + int tok;]AT_LOCATION_IF([[ yylloc.first_line = yylloc.last_line = lineNum; - yylloc.first_column = colNum; -#endif + yylloc.first_column = colNum;]])[ if (isalpha (c)) { i = 0; @@ -210,27 +199,14 @@ yylex (LEX_PARAMETERS) colNum += 1; tok = c; yylval = YY_NULL; - } -#if YYLSP_NEEDED - yylloc.last_column = colNum-1; -#endif + }]AT_LOCATION_IF([[ + yylloc.last_column = colNum-1;]])[ return tok; } } } } -void -yyerror (ERROR_PARAMETERS) -{ -#if YYPURE && YYLSP_NEEDED - /* Pacify GCC by using llocp. */ - if (! llocp) - abort (); -#endif - fprintf (stderr, "%s\n", s); -} - static Node * new_nterm (char const *form, Node *child0, Node *child1, Node *child2) { @@ -351,7 +327,7 @@ AT_BISON_OPTION_POPDEFS ]) m4_define([_AT_RESOLVED_GLR_OUTPUT], -[[[+(z,q) +[[+(z,q) (T,x) (T,x,y) =(x,y) @@ -360,10 +336,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 +348,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 +360,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 +372,23 @@ 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_GLR_STDERR_WITH_LOC], +[[17.5-4: syntax error +]]) m4_define([_AT_VERBOSE_GLR_STDERR], -[[[syntax error, unexpected ID, expecting '=' or '+' or ')' -]]]) +[[syntax error, unexpected ID, expecting '=' or '+' or ')' +]]) + +m4_define([_AT_VERBOSE_GLR_STDERR_WITH_LOC], +[[17.5-4: syntax error, unexpected ID, expecting '=' or '+' or ')' +]]) ## ---------------------------------------------------- ## ## Compile the grammar described in the documentation. ## @@ -414,59 +398,59 @@ AT_SETUP([GLR: Resolve ambiguity, impure, no locations]) _AT_TEST_GLR_CXXTYPES([], [%dprec 1], [%dprec 2]) AT_PARSER_CHECK([[./types test-input]], 0, - _AT_RESOLVED_GLR_OUTPUT, _AT_GLR_STDERR) + [_AT_RESOLVED_GLR_OUTPUT], [_AT_GLR_STDERR]) AT_CLEANUP AT_SETUP([GLR: Resolve ambiguity, impure, locations]) _AT_TEST_GLR_CXXTYPES([%locations],[%dprec 1],[%dprec 2]) AT_PARSER_CHECK([[./types test-input]], 0, - _AT_RESOLVED_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR) + [_AT_RESOLVED_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC]) AT_CLEANUP AT_SETUP([GLR: Resolve ambiguity, pure, no locations]) _AT_TEST_GLR_CXXTYPES([%define api.pure], [%dprec 1], [%dprec 2]) AT_PARSER_CHECK([[./types test-input]], 0, - _AT_RESOLVED_GLR_OUTPUT, _AT_GLR_STDERR) + [_AT_RESOLVED_GLR_OUTPUT], [_AT_GLR_STDERR]) AT_CLEANUP AT_SETUP([GLR: Resolve ambiguity, pure, locations]) _AT_TEST_GLR_CXXTYPES([%define api.pure %locations], [%dprec 1], [%dprec 2]) AT_PARSER_CHECK([[./types test-input]], 0, - _AT_RESOLVED_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR) + [_AT_RESOLVED_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC]) AT_CLEANUP AT_SETUP([GLR: Merge conflicting parses, impure, no locations]) _AT_TEST_GLR_CXXTYPES([], [%merge ], [%merge ]) AT_PARSER_CHECK([[./types test-input]], 0, - _AT_AMBIG_GLR_OUTPUT, _AT_GLR_STDERR) + [_AT_AMBIG_GLR_OUTPUT], [_AT_GLR_STDERR]) AT_CLEANUP AT_SETUP([GLR: Merge conflicting parses, impure, locations]) _AT_TEST_GLR_CXXTYPES([%locations], [%merge ], [%merge ]) AT_PARSER_CHECK([[./types test-input]], 0, - _AT_AMBIG_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR) + [_AT_AMBIG_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC]) AT_CLEANUP AT_SETUP([GLR: Merge conflicting parses, pure, no locations]) _AT_TEST_GLR_CXXTYPES([%define api.pure], [%merge ], [%merge ]) AT_PARSER_CHECK([[./types test-input]], 0, - _AT_AMBIG_GLR_OUTPUT, _AT_GLR_STDERR) + [_AT_AMBIG_GLR_OUTPUT], [_AT_GLR_STDERR]) AT_CLEANUP AT_SETUP([GLR: Merge conflicting parses, pure, locations]) _AT_TEST_GLR_CXXTYPES([%define api.pure %locations], [%merge ],[%merge ]) AT_PARSER_CHECK([[./types test-input]], 0, - _AT_AMBIG_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR) + [_AT_AMBIG_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC]) AT_CLEANUP AT_SETUP([GLR: Verbose messages, resolve ambiguity, impure, no locations]) _AT_TEST_GLR_CXXTYPES([%error-verbose], [%merge ], [%merge ]) AT_PARSER_CHECK([[./types test-input]], 0, - _AT_AMBIG_GLR_OUTPUT, _AT_VERBOSE_GLR_STDERR) + [_AT_AMBIG_GLR_OUTPUT], [_AT_VERBOSE_GLR_STDERR]) AT_CLEANUP diff --git a/tests/java.at b/tests/java.at index b9e9deee..f822ec6e 100644 --- a/tests/java.at +++ b/tests/java.at @@ -32,6 +32,7 @@ AT_BANNER([[Java Calculator.]]) m4_define([_AT_DATA_JAVA_CALC_Y], [m4_if([$1$2$3], $[1]$[2]$[3], [], [m4_fatal([$0: Invalid arguments: $@])])dnl +AT_BISON_OPTION_PUSHDEFS([%language "Java" $4]) AT_DATA([Calc.y], [[/* Infix notation calculator--calc */ %language "Java" @@ -122,20 +123,8 @@ AT_LOCATION_IF([[ public Position getEndPos() { return yypos; } - - public void yyerror (Calc.Location l, String s) - { - if (l == null) - System.err.println (s); - else - System.err.println (l + ": " + s); - } -]], [[ - public void yyerror (String s) - { - System.err.println (s); - } ]])[ + ]AT_YYERROR_DEFINE[ Integer yylval; @@ -211,11 +200,12 @@ class Position { } ]]) +AT_BISON_OPTION_POPDEFS ])# _AT_DATA_JAVA_CALC_Y # AT_DATA_CALC_Y([BISON-OPTIONS]) -# ------------------------------------------------- +# ------------------------------- # Produce `calc.y'. m4_define([AT_DATA_JAVA_CALC_Y], [_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1]) @@ -224,7 +214,7 @@ m4_define([AT_DATA_JAVA_CALC_Y], # _AT_CHECK_JAVA_CALC_ERROR(BISON-OPTIONS, INPUT, # [VERBOSE-AND-LOCATED-ERROR-MESSAGE]) -# --------------------------------------------------------- +# -------------------------------------------------------------- # Run `calc' on INPUT, and expect a `syntax error' message. # # If INPUT starts with a slash, it is used as absolute input file name, diff --git a/tests/local.at b/tests/local.at index b945968e..02093938 100644 --- a/tests/local.at +++ b/tests/local.at @@ -281,7 +281,7 @@ $2]) # AT_YYLEX_DEFINE(INPUT-STRING, [ACTION]) # --------------------------------------- m4_define([AT_YYLEX_DECLARE_EXTERN], -[int AT_API_PREFIX[]lex (void);dnl +[int AT_API_PREFIX[]lex (]AT_LEX_FORMALS[);dnl ]) m4_define([AT_YYLEX_DECLARE], @@ -291,7 +291,7 @@ m4_define([AT_YYLEX_DECLARE], m4_define([AT_YYLEX_DEFINE], [[#include /* abort */ static int -]AT_API_PREFIX[lex (void) +]AT_API_PREFIX[lex (]AT_LEX_FORMALS[) { static char const input[] = "$1"; static size_t toknum = 0; @@ -306,15 +306,20 @@ static int }]dnl ]) +# AT_YYERROR_PROTOTYPE # AT_YYERROR_DECLARE_EXTERN # AT_YYERROR_DECLARE # AT_YYERROR_DEFINE # ------------------------- -# Beware that must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS -# pair. +# Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair. +m4_define([AT_YYERROR_PROTOTYPE], +[m4_case(AT_LANG, +[c], [[void ]AT_API_PREFIX[error (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])[const char *msg)]])[]dnl +]) + m4_define([AT_YYERROR_DECLARE_EXTERN], [m4_case(AT_LANG, -[c], [void AT_API_PREFIX[]error (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])[const char *msg);])[]dnl +[c], [AT_YYERROR_PROTOTYPE;])[]dnl ]) m4_define([AT_YYERROR_DECLARE], @@ -326,8 +331,8 @@ m4_define([AT_YYERROR_DEFINE], [m4_case(AT_LANG, [c], [[#include /* A C error reporting function. */ -static void -yyerror (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])[const char *msg) +static +]AT_YYERROR_PROTOTYPE[ { ]AT_YYERROR_SEES_LOC_IF([[ fprintf (stderr, "%d.%d", @@ -348,10 +353,19 @@ void (void) l; std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl; }]], -[java], [[public void yyerror (String msg) -{ - System.err.println (msg); -}]])]) +[java], [AT_LOCATION_IF([[public void yyerror (Calc.Location l, String s) + { + if (l == null) + System.err.println (s); + else + System.err.println (l + ": " + s); + } +]], [[ + public void yyerror (String s) + { + System.err.println (s); + }]])])dnl +]) ## --------------- ## From 230a3db428622bb964807111b46812879b7ee726 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Fri, 22 Jun 2012 12:08:02 +0200 Subject: [PATCH 11/11] tests: more uniformity. * tests/local.at (AT_LEX_FORMALS, AT_LEX_ARGS, AT_LEX_PRE_FORMALS) (AT_LEX_PRE_ARGS): Rename as... (AT_YYLEX_FORMALS, AT_YYLEX_ARGS, AT_YYLEX_PRE_FORMALS) (AT_YYLEX_PRE_ARGS): these, for consistency. (AT_API_PREFIX): Take %name-prefix into account. (AT_YYLEX_PROTOTYPE): New. Use it. * tests/actions.at, tests/calc.at, tests/cxx-type.at: Adjust to use them. --- tests/actions.at | 8 ++++---- tests/calc.at | 36 +++++++++++++++----------------- tests/cxx-type.at | 3 +-- tests/local.at | 52 ++++++++++++++++++++++++++++------------------- 4 files changed, 52 insertions(+), 47 deletions(-) diff --git a/tests/actions.at b/tests/actions.at index afba3f0b..e5a885dd 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -205,8 +205,8 @@ m4_ifval([$6], [%union }]) AT_LALR1_CC_IF([%define global_tokens_and_yystype]) m4_ifval([$6], [[%code provides {]], [[%code {]]) -AT_LALR1_CC_IF([typedef yy::location YYLTYPE;]) -[static int yylex (]AT_LEX_FORMALS[); +AT_LALR1_CC_IF([typedef yy::location YYLTYPE;])[ +]AT_YYLEX_DECLARE[ ]AT_LALR1_CC_IF([], [AT_YYERROR_DECLARE]) [} @@ -309,8 +309,8 @@ thing: /* Alias to ARGV[1]. */ const char *source = YY_NULL; -static int -yylex (]AT_LEX_FORMALS[) +static +]AT_YYLEX_PROTOTYPE[ { static unsigned int counter = 0; diff --git a/tests/calc.at b/tests/calc.at index 34d2e488..836c3a33 100644 --- a/tests/calc.at +++ b/tests/calc.at @@ -110,15 +110,15 @@ main (int argc, const char **argv) 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_YYLEX_DECLARE_EXTERN[ +static int get_char (]AT_YYLEX_FORMALS[); +static void unget_char (]AT_YYLEX_PRE_FORMALS[ int c); ]AT_LOCATION_IF([ static YYLTYPE last_yylloc; ])[ static int -get_char (]AT_LEX_FORMALS[) +get_char (]AT_YYLEX_FORMALS[) { int res = getc (input); ]AT_USE_LEX_ARGS[; @@ -136,7 +136,7 @@ get_char (]AT_LEX_FORMALS[) } static void -unget_char (]AT_LEX_PRE_FORMALS[ int c) +unget_char (]AT_YYLEX_PRE_FORMALS[ int c) { ]AT_USE_LEX_ARGS[; ]AT_LOCATION_IF([ @@ -147,26 +147,26 @@ unget_char (]AT_LEX_PRE_FORMALS[ int c) } static int -read_signed_integer (]AT_LEX_FORMALS[) +read_signed_integer (]AT_YYLEX_FORMALS[) { - int c = get_char (]AT_LEX_ARGS[); + int c = get_char (]AT_YYLEX_ARGS[); int sign = 1; int n = 0; ]AT_USE_LEX_ARGS[; if (c == '-') { - c = get_char (]AT_LEX_ARGS[); + c = get_char (]AT_YYLEX_ARGS[); sign = -1; } while (isdigit (c)) { n = 10 * n + (c - '0'); - c = get_char (]AT_LEX_ARGS[); + c = get_char (]AT_YYLEX_ARGS[); } - unget_char (]AT_LEX_PRE_ARGS[ c); + unget_char (]AT_YYLEX_PRE_ARGS[ c); return sign * n; } @@ -178,8 +178,7 @@ read_signed_integer (]AT_LEX_FORMALS[) | blanks and tabs, returns 0 for EOF. | `---------------------------------------------------------------*/ -int -]AT_NAME_PREFIX[lex (]AT_LEX_FORMALS[) +]AT_YYLEX_PROTOTYPE[ { static int init = 1; int c; @@ -201,13 +200,13 @@ int AT_LOC_FIRST_LINE = AT_LOC_LAST_LINE; ])[ } - while ((c = get_char (]AT_LEX_ARGS[)) == ' ' || c == '\t'); + while ((c = get_char (]AT_YYLEX_ARGS[)) == ' ' || c == '\t'); /* process numbers */ if (c == '.' || isdigit (c)) { - unget_char (]AT_LEX_PRE_ARGS[ c); - ]AT_VAL[.ival = read_signed_integer (]AT_LEX_ARGS[); + unget_char (]AT_YYLEX_PRE_ARGS[ c); + ]AT_VAL[.ival = read_signed_integer (]AT_YYLEX_ARGS[); return NUM; } @@ -288,14 +287,11 @@ FILE *input; static int power (int base, int exponent); ]AT_SKEL_CC_IF(, -[/* yyerror receives the location if: - - %location & %pure & %glr - - %location & %pure & %yacc & %parse-param. */ -static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ]) +[static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ]) AT_PARAM_IF([semantic_value *result, int *count, ]) const char *s );])[ -int yylex (]AT_LEX_FORMALS[); +]AT_YYLEX_DECLARE_EXTERN[ } ]AT_SKEL_CC_IF([AT_LOCATION_TYPE_IF([], [ diff --git a/tests/cxx-type.at b/tests/cxx-type.at index e6fd8a85..e172033a 100644 --- a/tests/cxx-type.at +++ b/tests/cxx-type.at @@ -135,8 +135,7 @@ main (int argc, char **argv) ]AT_YYERROR_DEFINE[ -int -yylex (]AT_LEX_FORMALS[) +]AT_YYLEX_PROTOTYPE[ { char buffer[256]; int c; diff --git a/tests/local.at b/tests/local.at index 02093938..b0e4ee1a 100644 --- a/tests/local.at +++ b/tests/local.at @@ -138,11 +138,11 @@ m4_pushdef([AT_GLR_OR_PARAM_IF], [m4_bmatch([$3], [%glr-parser\|%parse-param], [$1], [$2])]) m4_pushdef([AT_NAME_PREFIX], [m4_bmatch([$3], [%name-prefix ".*"], - [m4_bregexp([$3], [name-prefix "\([^""]*\)"], [\1])], + [m4_bregexp([$3], [%name-prefix "\([^""]*\)"], [\1])], [yy])]) m4_pushdef([AT_API_PREFIX], -[m4_bmatch([$3], [%define api\.prefix ".*"], - [m4_bregexp([$3], [%define api\.prefix "\([^""]*\)"], [\1])], +[m4_bmatch([$3], [\(%define api\.prefix\|%name-prefix\) ".*"], + [m4_bregexp([$3], [\(%define api\.prefix\|%name-prefix\) "\([^""]*\)"], [\2])], [yy])]) # yyerror receives the location if %location & %pure & (%glr or %parse-param). m4_pushdef([AT_YYERROR_ARG_LOC_IF], @@ -165,24 +165,24 @@ m4_pushdef([AT_PURE_LEX_IF], AT_PURE_LEX_IF( [m4_pushdef([AT_LOC], [(*llocp)]) m4_pushdef([AT_VAL], [(*lvalp)]) - m4_pushdef([AT_LEX_FORMALS], + m4_pushdef([AT_YYLEX_FORMALS], [YYSTYPE *lvalp[]AT_LOCATION_IF([, YYLTYPE *llocp])]) - m4_pushdef([AT_LEX_ARGS], + m4_pushdef([AT_YYLEX_ARGS], [lvalp[]AT_LOCATION_IF([, llocp])]) m4_pushdef([AT_USE_LEX_ARGS], [(void) lvalp;AT_LOCATION_IF([(void) llocp])]) - m4_pushdef([AT_LEX_PRE_FORMALS], - [AT_LEX_FORMALS, ]) - m4_pushdef([AT_LEX_PRE_ARGS], - [AT_LEX_ARGS, ]) + m4_pushdef([AT_YYLEX_PRE_FORMALS], + [AT_YYLEX_FORMALS, ]) + m4_pushdef([AT_YYLEX_PRE_ARGS], + [AT_YYLEX_ARGS, ]) ], [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_YYLEX_FORMALS], [void]) + m4_pushdef([AT_YYLEX_ARGS], []) m4_pushdef([AT_USE_LEX_ARGS], []) - m4_pushdef([AT_LEX_PRE_FORMALS], []) - m4_pushdef([AT_LEX_PRE_ARGS], []) + m4_pushdef([AT_YYLEX_PRE_FORMALS], []) + m4_pushdef([AT_YYLEX_PRE_ARGS], []) ]) # Handle the different types of location components. @@ -199,11 +199,11 @@ AT_SKEL_CC_IF( # AT_BISON_OPTION_POPDEFS # ----------------------- m4_define([AT_BISON_OPTION_POPDEFS], -[m4_popdef([AT_LEX_PRE_ARGS]) -m4_popdef([AT_LEX_PRE_FORMALS]) +[m4_popdef([AT_YYLEX_PRE_ARGS]) +m4_popdef([AT_YYLEX_PRE_FORMALS]) m4_popdef([AT_USE_LEX_ARGS]) -m4_popdef([AT_LEX_ARGS]) -m4_popdef([AT_LEX_FORMALS]) +m4_popdef([AT_YYLEX_ARGS]) +m4_popdef([AT_YYLEX_FORMALS]) m4_popdef([AT_VAL]) m4_popdef([AT_LOC]) m4_popdef([AT_PURE_LEX_IF]) @@ -276,12 +276,17 @@ m4_define([AT_DATA_GRAMMAR], $2]) ]) +# AT_YYLEX_PROTOTYPE # AT_YYLEX_DECLARE_EXTERN # AT_YYLEX_DECLARE # AT_YYLEX_DEFINE(INPUT-STRING, [ACTION]) # --------------------------------------- +m4_define([AT_YYLEX_PROTOTYPE], +[int AT_API_PREFIX[]lex (]AT_YYLEX_FORMALS[)[]dnl +]) + m4_define([AT_YYLEX_DECLARE_EXTERN], -[int AT_API_PREFIX[]lex (]AT_LEX_FORMALS[);dnl +[AT_YYLEX_PROTOTYPE;dnl ]) m4_define([AT_YYLEX_DECLARE], @@ -290,8 +295,8 @@ m4_define([AT_YYLEX_DECLARE], m4_define([AT_YYLEX_DEFINE], [[#include /* abort */ -static int -]AT_API_PREFIX[lex (]AT_LEX_FORMALS[) +static +]AT_YYLEX_PROTOTYPE[ { static char const input[] = "$1"; static size_t toknum = 0; @@ -312,9 +317,14 @@ static int # AT_YYERROR_DEFINE # ------------------------- # Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair. +m4_define([AT_YYERROR_FORMALS], +[m4_case(AT_LANG, +[c], [AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])[const char *msg]])[]dnl +]) + m4_define([AT_YYERROR_PROTOTYPE], [m4_case(AT_LANG, -[c], [[void ]AT_API_PREFIX[error (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])[const char *msg)]])[]dnl +[c], [[void ]AT_API_PREFIX[error (]AT_YYERROR_FORMALS[)]])[]dnl ]) m4_define([AT_YYERROR_DECLARE_EXTERN],