[Top][All Lists]
[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));
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Bison patch for POSIX and Yacc compatibility with %union,
Paul Eggert <=