bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Bison patch for POSIX and Yacc compatibility with %union


From: Paul Eggert
Subject: Bison patch for POSIX and Yacc compatibility with %union
Date: Tue, 24 Dec 2002 00:06:35 -0800 (PST)

I installed the following patch to fix the "%union foo { ... }"
compatibility issue noted by David Durham and others.  While I was at
it, I noticed that Bison does not conform to POSIX with respect to
the YYSTYPE typedef.  The following patch fixes both issues.

2002-12-21  Paul Eggert  <address@hidden>

        If the user does not define YYSTYPE as a macro, Bison now declares it
        using typedef instead of defining it as a macro.  POSIX requires this.
        For consistency, YYLTYPE is also declared instead of defined.

        %union directives can now have a tag before the `{', e.g., the
        directive `%union foo {...}' now generates the C code
        `typedef union foo { ... } YYSTYPE;'; this is for Yacc compatibility.
        The default union tag is `YYSTYPE', for compatibility with Solaris 9
        Yacc.  For consistency, YYLTYPE's struct tag is now `YYLTYPE'
        instead of `yyltype'.

        `yystype' and `yyltype' are now obsolescent macros instead of being
        typedefs or tags; they are no longer documented and will be
        withdrawn in a future release.

        * data/glr.c (b4_location_type): Remove.
        (YYSTYPE): Renamed from yystype.
        (YYSTYPE_IS_DECLARED): New macro, used to prevent double-typedef.
        (struct YYLTYPE): Renamed from struct yyltype.
        (YYLTYPE): Renamed from yyltype.
        (yyltype, yystype): New (and obsolescent) macros,
        for backward compatibility.
        * data/yacc.c: Likewise.

        * data/yacc.c (YYSTYPE): Declare as union YYSTYPE if the user
        does not specify a union tag.  This is for compatibility with
        Solaris 9 yacc.

        * src/parse-gram.y (add_param): 2nd arg is now char * not char
        const *, since it is now modified by stripping surrounding { }.
        (current_braced_code): Remove.
        (PERCENT_DESTRUCTOR, PERCENT_PRINTER, PERCENT_UNION,
        PERCENT_LEX_PARAM, PERCENT_PARSE_PARAM): Change names to include
        trailing " {...}".  Now of type <chars>.
        (grammar_declaration): Adjust to bundled tokens.
        (code_content): Remove; stripping is now done by add_param.
        (print_token_value): Print contents of bundled tokens.
        (token_name): New function.

        * src/reader.h (braced_code, current_braced_code): Remove.
        (token_name): New decl.

        * src/scan-gram.l (handle_dollar, handle_at): Now takes int
        token_type, not braced_code code_kind.  All uses changed.
        (SC_PRE_CODE): New state, for scanning after a keyword that
        has (or usually has) an immediately-following braced code.
        (token_type): New local var, to keep track of which token type
        to return when scanning braced code.
        (<INITIAL>"%destructor", <INITIAL>"%lex-param",
        <INITIAL>"%parse-param", <INITIAL>"%printer,
        <INITIAL>"%union"): Set token type and BEGIN SC_PRE_CODE
        instead of returning a token type immediately.
        (<INITIAL>"{"): Set token type.
        (<SC_BRACED_CODE>"}"): Use it.
        (handle_action_dollar, handle_action_at): Now returns bool
        indicating success.  Fail if ! current_rule; this prevents a core dump.
        (handle_symbol_code_dollar, handle_symbol_code_at):
        Remove; merge body into caller.
        (handle_dollar, handle_at): Complain in invalid contexts.

        * NEWS, doc/bison.texinfo: Document the above.
        * NEWS: Fix years and program names in copyright notice.

--- NEWS.~1.83.~        2002-12-17 16:06:02.000000000 -0800
+++ NEWS        2002-12-23 23:18:39.159721000 -0800
@@ -3,6 +3,20 @@ Bison News
 
 Changes in version 1.75e:
 
+* If the user does not define YYSTYPE as a macro, Bison now declares it
+  using typedef instead of defining it as a macro.  POSIX requires this.
+  For consistency, YYLTYPE is also declared instead of defined.
+
+* %union directives can now have a tag before the `{', e.g., the
+  directive `%union foo {...}' now generates the C code
+  `typedef union foo { ... } YYSTYPE;'; this is for Yacc compatibility.
+  The default union tag is `YYSTYPE', for compatibility with Solaris 9 Yacc.
+  For consistency, YYLTYPE's struct tag is now `YYLTYPE' instead of `yyltype'.
+
+* `yystype' and `yyltype' are now obsolescent macros instead of being
+  typedefs or tags; they are no longer documented and will be
+  withdrawn in a future release.
+
 * References to the experimental %lex-param and %parse-param directives
   have been temporarily removed from the manual, since we don't want
   users to rely upon these features quite yet.
@@ -514,16 +528,17 @@ End:
 
 -----
 
-Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free
+Software Foundation, Inc.
 
-This file is part of GNU Autoconf.
+This file is part of Bison, the GNU Compiler Compiler.
 
-GNU Autoconf is free software; you can redistribute it and/or modify
+Bison 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 2, or (at your option)
 any later version.
 
-GNU Autoconf is distributed in the hope that it will be useful,
+Bison 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.
Index: data/glr.c
===================================================================
RCS file: /cvsroot/bison/bison/data/glr.c,v
retrieving revision 1.44
diff -p -u -r1.44 glr.c
--- data/glr.c  9 Dec 2002 04:48:38 -0000       1.44
+++ data/glr.c  24 Dec 2002 05:23:15 -0000
@@ -28,9 +28,6 @@ m4_include([c.m4])
 m4_define_default([b4_stack_depth_max], [10000])
 m4_define_default([b4_stack_depth_init],  [200])
 
-# Location type.
-m4_define_default([b4_location_type], [yyltype])
-
 
 
 ## ------------------------ ##
@@ -183,26 +180,26 @@ b4_pre_prologue[
 # define YYERROR_VERBOSE ]b4_error_verbose[
 #endif
 
-#ifndef YYSTYPE
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
 ]m4_ifdef([b4_stype],
 [b4_syncline([b4_stype_line], [b4_filename])
-typedef union b4_stype yystype;
+typedef union m4_bregexp(b4_stype, [^{], [YYSTYPE ])b4_stype YYSTYPE;
 /* Line __line__ of glr.c.  */
 b4_syncline(address@hidden@], address@hidden@])],
-[typedef int yystype;])[
-# define YYSTYPE yystype
+[typedef int YYSTYPE;])[
+# define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
 
-#ifndef YYLTYPE
-typedef struct yyltype
+#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
+typedef struct YYLTYPE
 {
   int first_line;
   int first_column;
   int last_line;
   int last_column;
-} yyltype;
-# define YYLTYPE ]b4_location_type[
+} YYLTYPE;
+# define YYLTYPE_IS_DECLARED 1
 # define YYLTYPE_IS_TRIVIAL 1
 #endif
 
@@ -513,8 +510,9 @@ int yydebug;
    properly redirected to new data. */
 #define YYHEADROOM 2
 
-#if ! defined (YYSTACKEXPANDABLE) \
-    && (! defined (__cplusplus) || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))
+#if (! defined (YYSTACKEXPANDABLE) \
+     && (! defined (__cplusplus) \
+        || (]b4_location_if([YYLTYPE_IS_TRIVIAL && ])[YYSTYPE_IS_TRIVIAL)))
 #define YYSTACKEXPANDABLE 1
 #else
 #define YYSTACKEXPANDABLE 0
@@ -1955,14 +1953,14 @@ b4_copyright([Skeleton parser for GLR pa
 
 b4_token_defines(b4_tokens)
 
-#ifndef YYSTYPE
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
 m4_ifdef([b4_stype],
 [b4_syncline([b4_stype_line], [b4_filename])
-typedef union b4_stype yystype;
+typedef union m4_bregexp(b4_stype, [^{], [YYSTYPE ])b4_stype YYSTYPE;
 /* Line __line__ of glr.c.  */
 b4_syncline(address@hidden@], address@hidden@])],
-[typedef int yystype;])
-# define YYSTYPE yystype
+[typedef int YYSTYPE;])
+# define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
 
@@ -1970,15 +1968,16 @@ b4_pure_if([],
 [extern YYSTYPE b4_prefix[]lval;])
 
 b4_location_if(
-[#ifndef YYLTYPE
-typedef struct yyltype
+[#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
+typedef struct YYLTYPE
 {
   int first_line;
   int first_column;
   int last_line;
   int last_column;
-} yyltype;
-# define YYLTYPE yyltype
+} YYLTYPE;
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
 #endif
 
 m4_if(b4_pure, [0],
Index: data/yacc.c
===================================================================
RCS file: /cvsroot/bison/bison/data/yacc.c,v
retrieving revision 1.44
diff -p -u -r1.44 yacc.c
--- data/yacc.c 15 Dec 2002 09:20:24 -0000      1.44
+++ data/yacc.c 24 Dec 2002 05:23:15 -0000
@@ -30,9 +30,6 @@ m4_include([c.m4])
 m4_define_default([b4_stack_depth_max], [10000])
 m4_define_default([b4_stack_depth_init],  [200])
 
-# Location type.
-m4_define_default([b4_location_type], [yyltype])
-
 
 ## ------------------------ ##
 ## Pure/impure interfaces.  ##
@@ -186,26 +183,28 @@ b4_location_if([#define yylloc b4_prefix
 # define YYERROR_VERBOSE ]b4_error_verbose[
 #endif
 
-#ifndef YYSTYPE
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
 ]m4_ifdef([b4_stype],
 [b4_syncline([b4_stype_line], [b4_filename])
-typedef union b4_stype yystype;
+typedef union m4_bregexp(b4_stype, [^{], [YYSTYPE ])b4_stype YYSTYPE;
 /* Line __line__ of yacc.c.  */
 b4_syncline(address@hidden@], address@hidden@])],
-[typedef int yystype;])[
-# define YYSTYPE yystype
+[typedef int YYSTYPE;])[
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
 
-]b4_location_if([#ifndef YYLTYPE
-typedef struct yyltype
+]b4_location_if([#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
+typedef struct YYLTYPE
 {
   int first_line;
   int first_column;
   int last_line;
   int last_column;
-} yyltype;
-# define YYLTYPE ]b4_location_type[
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
 # define YYLTYPE_IS_TRIVIAL 1
 #endif
 ])[
@@ -1194,14 +1193,15 @@ b4_copyright([Skeleton parser for Yacc-l
 
 b4_token_defines(b4_tokens)
 
-#ifndef YYSTYPE
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
 m4_ifdef([b4_stype],
 [b4_syncline([b4_stype_line], [b4_filename])
-typedef union b4_stype yystype;
+typedef union m4_bregexp(b4_stype, [^{], [YYSTYPE ])b4_stype YYSTYPE;
 /* Line __line__ of yacc.c.  */
 b4_syncline(address@hidden@], address@hidden@])],
-[typedef int yystype;])
-# define YYSTYPE yystype
+[typedef int YYSTYPE;])
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
 
@@ -1209,15 +1209,17 @@ b4_pure_if([],
 [extern YYSTYPE b4_prefix[]lval;])
 
 b4_location_if(
-[#ifndef YYLTYPE
-typedef struct yyltype
+[#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
+typedef struct YYLTYPE
 {
   int first_line;
   int first_column;
   int last_line;
   int last_column;
-} yyltype;
-# define YYLTYPE yyltype
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
 #endif
 
 m4_if(b4_pure, [0],
Index: doc/bison.texinfo
===================================================================
RCS file: /cvsroot/bison/bison/doc/bison.texinfo,v
retrieving revision 1.94
diff -p -u -r1.94 bison.texinfo
--- doc/bison.texinfo   21 Dec 2002 12:49:33 -0000      1.94
+++ doc/bison.texinfo   24 Dec 2002 05:23:18 -0000
@@ -3102,13 +3102,13 @@ When @code{YYLTYPE} is not defined, Biso
 four members:
 
 @example
-struct
+typedef struct YYLTYPE
 @{
   int first_line;
   int first_column;
   int last_line;
   int last_column;
address@hidden
address@hidden YYLTYPE;
 @end example
 
 @node Actions and Locations
@@ -3417,7 +3417,23 @@ This says that the two alternative types
 in the @code{%token} and @code{%type} declarations to pick one of the types
 for a terminal or nonterminal symbol (@pxref{Type Decl, ,Nonterminal Symbols}).
 
-Note that, unlike making a @code{union} declaration in C, you do not write
+As an extension to @acronym{POSIX}, a tag is allowed after the
address@hidden  For example:
+
address@hidden
address@hidden
+%union value @{
+  double val;
+  symrec *tptr;
address@hidden
address@hidden group
address@hidden example
+
+specifies the union tag @code{value}, so the corresponding C type is
address@hidden value}.  If you do not specify a tag, it defaults to
address@hidden
+
+Note that, unlike making a @code{union} declaration in C, you need not write
 a semicolon after the closing brace.
 
 @node Type Decl
@@ -6452,15 +6468,11 @@ macro is deprecated, and is supported on
 @xref{Pure Calling,, Calling Conventions for Pure Parsers}.
 @end deffn
 
address@hidden {Macro} YYLTYPE
-Macro for the data type of @code{yylloc}; a structure with four
address@hidden {Type} YYLTYPE
+Data type of @code{yylloc}; by default, a structure with four
 members.  @xref{Location Type, , Data Types of Locations}.
 @end deffn
 
address@hidden {Type} yyltype
-Default value for YYLTYPE.
address@hidden deffn
-
 @deffn {Macro} YYMAXDEPTH
 Macro for specifying the maximum size of the parser stack.  @xref{Stack
 Overflow}.
@@ -6485,8 +6497,8 @@ grow its internal stacks.  Do @emph{not}
 to anything else.
 @end deffn
 
address@hidden {Macro} YYSTYPE
-Macro for the data type of semantic values; @code{int} by default.
address@hidden {Type} YYSTYPE
+Data type of semantic values; @code{int} by default.
 @xref{Value Type, ,Data Types of Semantic Values}.
 @end deffn
 
Index: src/parse-gram.y
===================================================================
RCS file: /cvsroot/bison/bison/src/parse-gram.y,v
retrieving revision 1.35
diff -p -u -r1.35 parse-gram.y
--- src/parse-gram.y    11 Dec 2002 06:40:51 -0000      1.35
+++ src/parse-gram.y    24 Dec 2002 05:23:19 -0000
@@ -58,7 +58,7 @@ static void gram_error (location const *
        print_token_value (File, Type, &Value)
 static void print_token_value (FILE *, int, YYSTYPE const *);
 
-static void add_param (char const *, char const *, location);
+static void add_param (char const *, char *, location);
 
 symbol_class current_class = unknown_sym;
 uniqstr current_type = 0;
@@ -66,7 +66,6 @@ symbol *current_lhs;
 location current_lhs_location;
 assoc current_assoc;
 int current_prec = 0;
-braced_code current_braced_code = action_braced_code;
 %}
 
 
@@ -90,10 +89,10 @@ braced_code current_braced_code = action
 %token PERCENT_NTERM       "%nterm"
 
 %token PERCENT_TYPE        "%type"
-%token PERCENT_DESTRUCTOR  "%destructor"
-%token PERCENT_PRINTER     "%printer"
+%token PERCENT_DESTRUCTOR  "%destructor {...}"
+%token PERCENT_PRINTER     "%printer {...}"
 
-%token PERCENT_UNION       "%union"
+%token PERCENT_UNION       "%union {...}"
 
 %token PERCENT_LEFT        "%left"
 %token PERCENT_RIGHT       "%right"
@@ -116,12 +115,12 @@ braced_code current_braced_code = action
   PERCENT_EXPECT        "%expect"
   PERCENT_FILE_PREFIX   "%file-prefix"
   PERCENT_GLR_PARSER    "%glr-parser"
-  PERCENT_LEX_PARAM     "%lex-param"
+  PERCENT_LEX_PARAM     "%lex-param {...}"
   PERCENT_LOCATIONS     "%locations"
   PERCENT_NAME_PREFIX   "%name-prefix"
   PERCENT_NO_LINES      "%no-lines"
   PERCENT_OUTPUT        "%output"
-  PERCENT_PARSE_PARAM   "%parse-param"
+  PERCENT_PARSE_PARAM   "%parse-param {...}"
   PERCENT_PURE_PARSER   "%pure-parser"
   PERCENT_SKELETON      "%skeleton"
   PERCENT_START         "%start"
@@ -143,7 +142,12 @@ braced_code current_braced_code = action
 
 
 %type <chars> STRING string_content
-             BRACED_CODE code_content action
+             "%destructor {...}"
+             "%lex-param {...}"
+             "%parse-param {...}"
+             "%printer {...}"
+             "%union {...}"
+             BRACED_CODE action
              PROLOGUE EPILOGUE
 %type <uniqstr> TYPE
 %type <integer> INT
@@ -176,12 +180,12 @@ declaration:
 | "%expect" INT                            { expected_conflicts = $2; }
 | "%file-prefix" "=" string_content        { spec_file_prefix = $3; }
 | "%glr-parser"                           { glr_parser = 1; }
-| "%lex-param" code_content               { add_param ("lex_param", $2, @2); }
+| "%lex-param {...}"                      { add_param ("lex_param", $1, @1); }
 | "%locations"                             { locations_flag = 1; }
 | "%name-prefix" "=" string_content        { spec_name_prefix = $3; }
 | "%no-lines"                              { no_lines_flag = 1; }
 | "%output" "=" string_content             { spec_outfile = $3; }
-| "%parse-param" code_content          { add_param ("parse_param", $2, @2); }
+| "%parse-param {...}"                  { add_param ("parse_param", $1, @1); }
 | "%pure-parser"                           { pure_parser = 1; }
 | "%skeleton" string_content               { skeleton = $2; }
 | "%token-table"                           { token_table_flag = 1; }
@@ -197,31 +201,25 @@ grammar_declaration:
     {
       grammar_start_symbol_set ($2, @2);
     }
-| "%union" BRACED_CODE
+| "%union {...}"
     {
       typed = 1;
-      MUSCLE_INSERT_INT ("stype_line", @2.start.line);
-      muscle_insert ("stype", $2);
+      MUSCLE_INSERT_INT ("stype_line", @1.start.line);
+      muscle_insert ("stype", $1);
     }
-| "%destructor"
-    { current_braced_code = destructor_braced_code; }
-  BRACED_CODE symbols.1
+| "%destructor {...}" symbols.1
     {
       symbol_list *list;
-      for (list = $4; list; list = list->next)
-       symbol_destructor_set (list->sym, $3, @3);
-      symbol_list_free ($4);
-      current_braced_code = action_braced_code;
-    }
-| "%printer"
-    { current_braced_code = printer_braced_code; }
-  BRACED_CODE symbols.1
+      for (list = $2; list; list = list->next)
+       symbol_destructor_set (list->sym, $1, @1);
+      symbol_list_free ($2);
+    }
+| "%printer {...}" symbols.1
     {
       symbol_list *list;
-      for (list = $4; list; list = list->next)
-       symbol_printer_set (list->sym, $3, list->location);
-      symbol_list_free ($4);
-      current_braced_code = action_braced_code;
+      for (list = $2; list; list = list->next)
+       symbol_printer_set (list->sym, $1, list->location);
+      symbol_list_free ($2);
     }
 ;
 
@@ -394,15 +392,6 @@ string_content:
     };
 
 
-/* A BRACED_CODE used for its contents.  Strip the braces. */
-code_content:
-  BRACED_CODE
-    {
-      $$ = $1 + 1;
-      $$[strlen ($$) - 1] = '\0';
-    };
-
-
 epilogue.opt:
   /* Nothing.  */
 | "%%" EPILOGUE
@@ -449,7 +438,7 @@ lloc_default (YYLTYPE const *rhs, int n)
    declaration DECL and location LOC.  */
 
 static void
-add_param (char const *type, char const *decl, location loc)
+add_param (char const *type, char *decl, location loc)
 {
   static char const alphanum[] =
     "0123456789"
@@ -458,12 +447,16 @@ add_param (char const *type, char const 
     "_";
   char const *alpha = alphanum + 10;
   char const *name_start = NULL;
-  char const *p;
+  char *p;
 
   for (p = decl; *p; p++)
     if ((p == decl || ! strchr (alphanum, p[-1])) && strchr (alpha, p[0]))
       name_start = p;
 
+  /* Strip the surrounding '{' and '}'.  */
+  decl++;
+  p[-1] = '\0';
+
   if (! name_start)
     complain_at (loc, _("missing identifier in parameter declaration"));
   else
@@ -486,9 +479,9 @@ add_param (char const *type, char const 
   scanner_last_string_free ();
 }
 
-/*------------------------------------------------------------------.
-| When debugging the parser, display tokens' locations and values.  |
-`------------------------------------------------------------------*/
+/*----------------------------------------------------.
+| When debugging the parser, display tokens' values.  |
+`----------------------------------------------------*/
 
 static void
 print_token_value (FILE *file, int type, YYSTYPE const *value)
@@ -513,6 +506,11 @@ print_token_value (FILE *file, int type,
       break;
 
     case BRACED_CODE:
+    case PERCENT_DESTRUCTOR:
+    case PERCENT_LEX_PARAM:
+    case PERCENT_PARSE_PARAM:
+    case PERCENT_PRINTER:
+    case PERCENT_UNION:
     case PROLOGUE:
     case EPILOGUE:
       fprintf (file, " = {{ %s }}", value->chars);
@@ -528,4 +526,10 @@ static void
 gram_error (location const *loc, char const *msg)
 {
   complain_at (*loc, "%s", msg);
+}
+
+char const *
+token_name (int type)
+{
+  return yytname[type];
 }
Index: src/reader.h
===================================================================
RCS file: /cvsroot/bison/bison/src/reader.h,v
retrieving revision 1.35
diff -p -u -r1.35 reader.h
--- src/reader.h        11 Dec 2002 06:44:28 -0000      1.35
+++ src/reader.h        24 Dec 2002 05:23:19 -0000
@@ -48,17 +48,7 @@ YY_DECL;
 /* From the parser.  */
 extern int gram_debug;
 int gram_parse (void);
-
-/* The sort of braced code we are in.  */
-typedef enum
-  {
-    action_braced_code,
-    destructor_braced_code,
-    printer_braced_code
-  } braced_code;
-/* FIXME: This is really a dirty hack which demonstrates that we
-   should probably not try to parse the actions now.  */
-extern braced_code current_braced_code;
+char const *token_name (int);
 
 
 /* From reader.c. */
Index: src/scan-gram.l
===================================================================
RCS file: /cvsroot/bison/bison/src/scan-gram.l,v
retrieving revision 1.50
diff -p -u -r1.50 scan-gram.l
--- src/scan-gram.l     13 Dec 2002 08:35:16 -0000      1.50
+++ src/scan-gram.l     24 Dec 2002 05:23:19 -0000
@@ -97,8 +97,8 @@ scanner_last_string_free (void)
    Outside of well-formed rules, RULE_LENGTH has an undefined value.  */
 static int rule_length;
 
-static void handle_dollar (braced_code code_kind, char *cp, location loc);
-static void handle_at (braced_code code_kind, char *cp, location loc);
+static void handle_dollar (int token_type, char *cp, location loc);
+static void handle_at (int token_type, char *cp, location loc);
 static void handle_syncline (char *args);
 static int convert_ucn_to_byte (char const *hex_text);
 static void unexpected_end_of_file (boundary, char const *);
@@ -108,7 +108,7 @@ static void unexpected_end_of_file (boun
 %x SC_STRING SC_CHARACTER
 %x SC_AFTER_IDENTIFIER
 %x SC_ESCAPED_STRING SC_ESCAPED_CHARACTER
-%x SC_BRACED_CODE SC_PROLOGUE SC_EPILOGUE
+%x SC_PRE_CODE SC_BRACED_CODE SC_PROLOGUE SC_EPILOGUE
 
 letter   [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]
 id       {letter}({letter}|[0-9])*
@@ -132,6 +132,9 @@ splice       (\\[ \f\t\v]*\n)*
   /* Parent context state, when applicable.  */
   int context_state IF_LINT (= 0);
 
+  /* Token type to return, when applicable.  */
+  int token_type IF_LINT (= 0);
+
   /* Location of most recent identifier, when applicable.  */
   location id_loc IF_LINT (= *loc);
 
@@ -148,7 +151,7 @@ splice       (\\[ \f\t\v]*\n)*
   | Scanning white space.  |
   `-----------------------*/
 
-<INITIAL,SC_AFTER_IDENTIFIER>
+<INITIAL,SC_AFTER_IDENTIFIER,SC_PRE_CODE>
 {
   [ \f\n\t\v]  ;
 
@@ -173,7 +176,7 @@ splice       (\\[ \f\t\v]*\n)*
   "%debug"                return PERCENT_DEBUG;
   "%define"               return PERCENT_DEFINE;
   "%defines"              return PERCENT_DEFINES;
-  "%destructor"           return PERCENT_DESTRUCTOR;
+  "%destructor"                  token_type = PERCENT_DESTRUCTOR; BEGIN 
SC_PRE_CODE;
   "%dprec"               return PERCENT_DPREC;
   "%error"[-_]"verbose"   return PERCENT_ERROR_VERBOSE;
   "%expect"               return PERCENT_EXPECT;
@@ -181,6 +184,7 @@ splice       (\\[ \f\t\v]*\n)*
   "%fixed"[-_]"output"[-_]"files"   return PERCENT_YACC;
   "%glr-parser"           return PERCENT_GLR_PARSER;
   "%left"                 return PERCENT_LEFT;
+  "%lex-param"           token_type = PERCENT_LEX_PARAM; BEGIN SC_PRE_CODE;
   "%locations"            return PERCENT_LOCATIONS;
   "%merge"               return PERCENT_MERGE;
   "%name"[-_]"prefix"     return PERCENT_NAME_PREFIX;
@@ -188,19 +192,18 @@ splice     (\\[ \f\t\v]*\n)*
   "%nonassoc"             return PERCENT_NONASSOC;
   "%nterm"                return PERCENT_NTERM;
   "%output"               return PERCENT_OUTPUT;
-  "%parse-param"          return PERCENT_PARSE_PARAM;
+  "%parse-param"         token_type = PERCENT_PARSE_PARAM; BEGIN SC_PRE_CODE;
   "%prec"                 rule_length--; return PERCENT_PREC;
-  "%printer"              return PERCENT_PRINTER;
+  "%printer"              token_type = PERCENT_PRINTER; BEGIN SC_PRE_CODE;
   "%pure"[-_]"parser"     return PERCENT_PURE_PARSER;
   "%right"                return PERCENT_RIGHT;
-  "%lex-param"            return PERCENT_LEX_PARAM;
   "%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;
+  "%union"               token_type = PERCENT_UNION; BEGIN SC_PRE_CODE;
   "%verbose"              return PERCENT_VERBOSE;
   "%yacc"                 return PERCENT_YACC;
 
@@ -248,6 +251,7 @@ splice       (\\[ \f\t\v]*\n)*
   /* Code in between braces.  */
   "{" {
     STRING_GROW;
+    token_type = BRACED_CODE;
     braces_level = 0;
     code_start = loc->start;
     BEGIN SC_BRACED_CODE;
@@ -496,6 +500,39 @@ splice      (\\[ \f\t\v]*\n)*
 
 
   /*---------------------------------------------------------------.
+  | Scanning after %union etc., possibly followed by white space.  |
+  | For %union only, allow arbitrary C code to appear before the   |
+  | following brace, as an extension to POSIX.                    |
+  `---------------------------------------------------------------*/
+
+<SC_PRE_CODE>
+{
+  . {
+    bool valid = yytext[0] == '{' || token_type == PERCENT_UNION;
+    scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0);
+    yyless (0);
+
+    if (valid)
+      {
+       braces_level = -1;
+       code_start = loc->start;
+       BEGIN SC_BRACED_CODE;
+      }
+    else
+      {
+       complain_at (*loc, _("missing `{' in `%s'"),
+                    token_name (token_type));
+       obstack_sgrow (&obstack_for_string, "{}");
+       STRING_FINISH;
+       val->chars = last_string;
+       BEGIN INITIAL;
+       return token_type;
+      }
+  }
+}
+
+
+  /*---------------------------------------------------------------.
   | Scanning some code in braces (%union and actions). The initial |
   | "{" is already eaten.                                          |
   `---------------------------------------------------------------*/
@@ -510,11 +547,11 @@ splice     (\\[ \f\t\v]*\n)*
     if (braces_level < 0)
       {
        STRING_FINISH;
+       rule_length++;
        loc->start = code_start;
        val->chars = last_string;
-       rule_length++;
        BEGIN INITIAL;
-       return BRACED_CODE;
+       return token_type;
       }
   }
 
@@ -522,10 +559,8 @@ splice      (\\[ \f\t\v]*\n)*
      (as `<' `<%').  */
   "<"{splice}"<"  STRING_GROW;
 
-  "$"("<"{tag}">")?(-?[0-9]+|"$") { handle_dollar (current_braced_code,
-                                                  yytext, *loc); }
-  "@"(-?[0-9]+|"$")               { handle_at (current_braced_code,
-                                              yytext, *loc); }
+  "$"("<"{tag}">")?(-?[0-9]+|"$")  handle_dollar (token_type, yytext, *loc);
+  "@"(-?[0-9]+|"$")               handle_at (token_type, yytext, *loc);
 
   <<EOF>>  unexpected_end_of_file (code_start, "}");
 }
@@ -675,12 +710,15 @@ no_cr_read (FILE *fp, char *buf, size_t 
 | Output to OBSTACK_FOR_STRING a reference to this semantic value.  |
 `------------------------------------------------------------------*/
 
-static inline void
+static inline bool
 handle_action_dollar (char *text, location loc)
 {
   const char *type_name = NULL;
   char *cp = text + 1;
 
+  if (! current_rule)
+    return false;
+
   /* Get the type name if explicit. */
   if (*cp == '<')
     {
@@ -726,44 +764,40 @@ handle_action_dollar (char *text, locati
       else
        complain_at (loc, _("integer out of range: %s"), quote (text));
     }
-}
-
 
-/*---------------------------------------------------------------.
-| TEXT is expected to be $$ in some code associated to a symbol: |
-| destructor or printer.                                         |
-`---------------------------------------------------------------*/
-
-static inline void
-handle_symbol_code_dollar (char *text, location loc)
-{
-  char *cp = text + 1;
-  if (*cp == '$')
-    obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar[");
-  else
-    complain_at (loc, _("invalid value: %s"), quote (text));
+  return true;
 }
 
 
 /*-----------------------------------------------------------------.
 | Dispatch onto handle_action_dollar, or handle_destructor_dollar, |
-| depending upon CODE_KIND.                                        |
+| depending upon TOKEN_TYPE.                                       |
 `-----------------------------------------------------------------*/
 
 static void
-handle_dollar (braced_code braced_code_kind, char *text, location loc)
+handle_dollar (int token_type, char *text, location loc)
 {
-  switch (braced_code_kind)
+  switch (token_type)
     {
-    case action_braced_code:
-      handle_action_dollar (text, loc);
+    case BRACED_CODE:
+      if (handle_action_dollar (text, loc))
+       return;
       break;
 
-    case destructor_braced_code:
-    case printer_braced_code:
-      handle_symbol_code_dollar (text, loc);
+    case PERCENT_DESTRUCTOR:
+    case PERCENT_PRINTER:
+      if (text[1] == '$')
+       {
+         obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar[");
+         return;
+       }
+      break;
+
+    default:
       break;
     }
+      
+  complain_at (loc, _("invalid value: %s"), quote (text));
 }
 
 
@@ -772,16 +806,17 @@ handle_dollar (braced_code braced_code_k
 | OBSTACK_FOR_STRING a reference to this location.      |
 `------------------------------------------------------*/
 
-static inline void
+static inline bool
 handle_action_at (char *text, location loc)
 {
   char *cp = text + 1;
   locations_flag = 1;
 
+  if (! current_rule)
+    return false;
+
   if (*cp == '$')
-    {
-      obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
-    }
+    obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
   else
     {
       long num;
@@ -797,22 +832,8 @@ handle_action_at (char *text, location l
       else
        complain_at (loc, _("integer out of range: %s"), quote (text));
     }
-}
-
 
-/*---------------------------------------------------------------.
-| TEXT is expected to be @$ in some code associated to a symbol: |
-| destructor or printer.                                         |
-`---------------------------------------------------------------*/
-
-static inline void
-handle_symbol_code_at (char *text, location loc)
-{
-  char *cp = text + 1;
-  if (*cp == '$')
-    obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
-  else
-    complain_at (loc, _("invalid value: %s"), quote (text));
+  return true;
 }
 
 
@@ -822,19 +843,28 @@ handle_symbol_code_at (char *text, locat
 `-------------------------------------------------------------------*/
 
 static void
-handle_at (braced_code braced_code_kind, char *text, location loc)
+handle_at (int token_type, char *text, location loc)
 {
-  switch (braced_code_kind)
+  switch (token_type)
     {
-    case action_braced_code:
+    case BRACED_CODE:
       handle_action_at (text, loc);
+      return;
+
+    case PERCENT_DESTRUCTOR:
+    case PERCENT_PRINTER:
+      if (text[1] == '$')
+       {
+         obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
+         return;
+       }
       break;
 
-    case destructor_braced_code:
-    case printer_braced_code:
-      handle_symbol_code_at (text, loc);
+    default:
       break;
     }
+
+  complain_at (loc, _("invalid value: %s"), quote (text));
 }
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]