[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Bison patch to allow rules without trailing semicolon
From: |
Paul Eggert |
Subject: |
Bison patch to allow rules without trailing semicolon |
Date: |
Fri, 6 Dec 2002 22:19:36 -0800 (PST) |
I installed the following patch.
2002-12-06 Paul Eggert <address@hidden>
Add support for rules that do not have trailing semicolons, as
POSIX requires. Improve the quality of locations in Bison
diagnostics.
* src/location.c: Include <quotearg.h>.
(empty_location): Now const.
(location_print): New function. Follow the recommendation of the
GNU Coding Standards for locations that span file boundaries.
* src/location.h: Do not include <quotearg.h>; no longer needed.
(boundary): New type.
(location_t): Use it. This allows locations to span file boundaries.
All member uses changed: file -> start.file or end.file (as needed),
first_line -> start.line, first_column -> start.column,
last_line -> end.line, last_column -> end.column.
(equal_boundaries): New function.
(LOCATION_RESET, LOCATION_STEP): Remove.
(LOCATION_PRINT): Remove. All callers changed to use location_print.
(empty_location): Now const.
(location_print): New decl.
* src/parse-gram.y (lloc_default): New function, which handles
empty locations more accurately.
(YYLLOC_DEFAULT): Use it.
(%token COLON): Remove.
(%token ID_COLON): New token.
(rules): Use it.
(declarations, rules): Remove trailing semicolon.
(declaration, rules_or_grammar_declaration):
Allow empty (";") declaration.
(symbol_def): Remove empty actions; no longer needed.
(rules_or_grammar_declaration): Remove trailing semicolon.
(semi_colon.opt): Remove.
* src/reader.h: Include location.h.
(scanner_cursor): New decl.
* src/reduce.c (nonterminals_reduce): Use warn_at rather than
rolling our own.
* src/scan-gram.l (YY_USER_INIT): Initialize scanner_cursor instead
of *loc.
(STEP): Remove. No longer needed, now that adjust_location does
the work. All uses removed.
(scanner_cursor): New var.
(adjust_location): Renamed from extend_location. It now sets
*loc and adjusts the scanner cursor. All uses changed.
Don't bother testing for CR.
(handle_syncline): Remove location arg; now updates scanner cursor.
All callers changed.
(unexpected_end_of_file): Now accepts start boundary of token or
comment, not location. All callers changed. Update scanner cursor,
not the location.
(SC_AFTER_IDENTIFIER): New state.
(context_state): Renamed from c_context. All uses changed.
(id_loc, code_start, token_start): New local vars.
(<INITIAL,SC_AFTER_IDENTIFIER>): New initial context. Move all
processing of Yacc white space and equivalents here.
(<INITIAL>{id}): Save id_loc. Begin state SC_AFTER_IDENTIFIER
instead of returning ID immediately, since we need to search for
a subsequent colon.
(<INITIAL>"'", "\""): Save token_start.
(<INITIAL>"%{", "{", "%%"): Save code_start.
(<SC_AFTER_IDENTIFIER>): New state, looking for a colon.
(<SC_YACC_COMMENT>, <SC_COMMENT>, <SC_LINE_COMMENT>):
BEGIN context_state at end, not INITIAL.
(<SC_ESCAPED_STRING>"\"", <SC_ESCAPED_CHARACTER>"'",
<SC_BRACED_CODE>"}", <SC_PROLOGUE>"%}", <SC_EPILOGUE><<EOF>>):
Return correct token start.
(<SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>): Save start boundary when
the start of a character, string or multiline comment is found.
* tests/conflicts.at (S/R in initial, Defaulted Conflicted
Reduction): Adjust reported locations to match the more-precise
results now expected.
* tests/input.at (Invalid $n, Invalid @n, Type Clashes): Likewise.
* tests/reduce.at (Useless Rules, Reduced Automaton,
Underivable Rules): Likewise.
* tests/regression.at (Invalid inputs): No longer `expecting ";"
or "|"' now that so many other tokens are allowed by the new grammar.
* src/complain.h (current_file): Remove duplicate decl;
current_file is now owned by files.h.
* src/complain.c, src/scan-gram.l: Include files.h.
Index: src/complain.c
===================================================================
RCS file: /cvsroot/bison/bison/src/complain.c,v
retrieving revision 1.17
diff -p -u -r1.17 complain.c
--- src/complain.c 12 Nov 2002 08:05:59 -0000 1.17
+++ src/complain.c 7 Dec 2002 05:41:57 -0000
@@ -1,5 +1,5 @@
/* Declaration for error-reporting function for Bison.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
@@ -32,6 +32,7 @@
#endif
#include "complain.h"
+#include "files.h"
#ifndef _
# define _(String) String
@@ -98,7 +99,7 @@ warn_at (location_t location, const char
va_list args;
fflush (stdout);
- LOCATION_PRINT (stderr, location);
+ location_print (stderr, location);
fputs (": ", stderr);
fputs (_("warning: "), stderr);
@@ -138,7 +139,7 @@ complain_at (location_t location, const
va_list args;
fflush (stdout);
- LOCATION_PRINT (stderr, location);
+ location_print (stderr, location);
fputs (": ", stderr);
va_start (args, message);
@@ -177,7 +178,7 @@ fatal_at (location_t location, const cha
va_list args;
fflush (stdout);
- LOCATION_PRINT (stderr, location);
+ location_print (stderr, location);
fputs (": ", stderr);
fputs (_("fatal error: "), stderr);
Index: src/complain.h
===================================================================
RCS file: /cvsroot/bison/bison/src/complain.h,v
retrieving revision 1.12
diff -p -u -r1.12 complain.h
--- src/complain.h 12 Nov 2002 08:05:59 -0000 1.12
+++ src/complain.h 7 Dec 2002 05:41:57 -0000
@@ -49,9 +49,6 @@ void fatal (const char *format, ...)
void fatal_at (location_t location, const char *format, ...)
__attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
-/* Position in the current input file. */
-extern const char *current_file;
-
/* This variable is set each time `warn' is called. */
extern bool warning_issued;
Index: src/gram.c
===================================================================
RCS file: /cvsroot/bison/bison/src/gram.c,v
retrieving revision 1.46
diff -p -u -r1.46 gram.c
--- src/gram.c 22 Oct 2002 04:41:25 -0000 1.46
+++ src/gram.c 7 Dec 2002 05:41:57 -0000
@@ -316,7 +316,7 @@ grammar_rules_never_reduced_report (cons
for (r = 0; r < nrules ; ++r)
if (!rules[r].useful)
{
- LOCATION_PRINT (stderr, rules[r].location);
+ location_print (stderr, rules[r].location);
fprintf (stderr, ": %s: %s: ",
_("warning"), message);
rule_print (&rules[r], stderr);
Index: src/location.c
===================================================================
RCS file: /cvsroot/bison/bison/src/location.c,v
retrieving revision 1.2
diff -p -u -r1.2 location.c
--- src/location.c 9 Jul 2002 16:24:57 -0000 1.2
+++ src/location.c 7 Dec 2002 05:41:57 -0000
@@ -1,5 +1,5 @@
/* Locations for Bison
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -20,5 +20,25 @@
#include "system.h"
#include "location.h"
+#include <quotearg.h>
-location_t empty_location = { NULL, 0, 0, 0, 0 };
+location_t const empty_location;
+
+/* Output to OUT the location LOC.
+ Warning: it uses quotearg's slot 3. */
+void
+location_print (FILE *out, location_t loc)
+{
+ fprintf (out, "%s:%d.%d",
+ quotearg_n_style (3, escape_quoting_style, loc.start.file),
+ loc.start.line, loc.start.column);
+
+ if (loc.start.file != loc.end.file)
+ fprintf (out, "-%s:%d.%d",
+ quotearg_n_style (3, escape_quoting_style, loc.end.file),
+ loc.end.line, loc.end.column - 1);
+ else if (loc.start.line < loc.end.line)
+ fprintf (out, "-%d.%d", loc.end.line, loc.end.column - 1);
+ else if (loc.start.column < loc.end.column - 1)
+ fprintf (out, "-%d", loc.end.column - 1);
+}
Index: src/location.h
===================================================================
RCS file: /cvsroot/bison/bison/src/location.h,v
retrieving revision 1.6
diff -p -u -r1.6 location.h
--- src/location.h 12 Nov 2002 08:30:47 -0000 1.6
+++ src/location.h 7 Dec 2002 05:41:57 -0000
@@ -1,5 +1,5 @@
/* Locations for Bison
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -20,56 +20,46 @@
#ifndef LOCATION_H_
# define LOCATION_H_
-# include "quotearg.h"
-typedef struct location_s
+/* A boundary between two characters. */
+typedef struct
{
- const char *file;
- int first_line;
- int first_column;
- int last_line;
- int last_column;
-} location_t;
-#define YYLTYPE location_t
+ /* The name of the file that contains the boundary. */
+ char const *file;
+
+ /* The (origin-1) line that contains the boundary. */
+ int line;
+
+ /* The (origin-1) column just after the boundary. This is neither a
+ byte count, nor a character count; it is a column count. */
+ int column;
+
+} boundary;
+
+/* Return nonzero if A and B are equal boundaries. */
+static inline bool
+equal_boundaries (boundary a, boundary b)
+{
+ return (a.column == b.column
+ && a.line == b.line
+ && a.file == b.file);
+}
-/* Initialize LOC. */
-# define LOCATION_RESET(Loc) \
-do { \
- (Loc).file = NULL; \
- (Loc).first_column = (Loc).first_line = 1; \
- (Loc).last_column = (Loc).last_line = 1; \
-} while (0)
-
-
-/* Restart: move the first cursor to the last position. */
-# define LOCATION_STEP(Loc) \
-do { \
- (Loc).first_column = (Loc).last_column; \
- (Loc).first_line = (Loc).last_line; \
-} while (0)
-
-
-/* Output LOC on the stream OUT.
- Warning: it uses quotearg's slot 3. */
-# define LOCATION_PRINT(Out, Loc) \
-do { \
- fprintf (stderr, "%s:", quotearg_n_style (3, escape_quoting_style, \
- (Loc).file)); \
- if ((Loc).first_line)
\
- { \
- if ((Loc).first_line != (Loc).last_line) \
- fprintf (Out, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column - 1); \
- else if ((Loc).first_column < (Loc).last_column - 1) \
- fprintf (Out, "%d.%d-%d", (Loc).first_line, \
- (Loc).first_column, (Loc).last_column - 1); \
- else \
- fprintf (Out, "%d.%d", (Loc).first_line, (Loc).first_column); \
- } \
-} while (0)
+/* A location, that is, a region of source code. */
+typedef struct
+{
+ /* Boundary just before the location starts. */
+ boundary start;
+
+ /* Boundary just after the location ends. */
+ boundary end;
+
+} location_t;
+
+#define YYLTYPE location_t
+extern location_t const empty_location;
-extern location_t empty_location;
+void location_print (FILE *, location_t);
-#endif /* !LOCATION_H_ */
+#endif /* ! defined LOCATION_H_ */
Index: src/output.c
===================================================================
RCS file: /cvsroot/bison/bison/src/output.c,v
retrieving revision 1.212
diff -p -u -r1.212 output.c
--- src/output.c 21 Nov 2002 05:20:05 -0000 1.212
+++ src/output.c 7 Dec 2002 05:41:58 -0000
@@ -229,7 +229,7 @@ prepare_rules (void)
/* Separator in RHS. */
rhs[i++] = -1;
/* Line where rule was defined. */
- rline[r] = rules[r].location.first_line;
+ rline[r] = rules[r].location.start.line;
/* Dynamic precedence (GLR). */
dprec[r] = rules[r].dprec;
/* Merger-function index (GLR). */
@@ -295,8 +295,8 @@ user_actions_output (FILE *out)
fprintf (out, " case %d:\n", r + 1);
fprintf (out, "]b4_syncline([[%d]], ",
- rules[r].action_location.first_line);
- escaped_file_name_output (out, rules[r].action_location.file);
+ rules[r].action_location.start.line);
+ escaped_file_name_output (out, rules[r].action_location.start.file);
fprintf (out, ")[\n");
fprintf (out, " %s\n break;\n\n",
rules[r].action);
@@ -399,9 +399,9 @@ symbol_destructors_output (FILE *out)
destructor, typename. */
fprintf (out, "%s[",
first ? "" : ",\n");
- escaped_file_name_output (out, symbol->destructor_location.file);
+ escaped_file_name_output (out, symbol->destructor_location.start.file);
fprintf (out, ", [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
- symbol->destructor_location.first_line,
+ symbol->destructor_location.start.line,
symbol->tag,
symbol->number,
symbol->destructor,
@@ -434,9 +434,9 @@ symbol_printers_output (FILE *out)
printer, typename. */
fprintf (out, "%s[",
first ? "" : ",\n");
- escaped_file_name_output (out, symbol->printer_location.file);
+ escaped_file_name_output (out, symbol->printer_location.start.file);
fprintf (out, ", [[%d]], [[%s]], [[%d]], [[%s]], [[%s]]]",
- symbol->printer_location.first_line,
+ symbol->printer_location.start.line,
symbol->tag,
symbol->number,
symbol->printer,
Index: src/parse-gram.y
===================================================================
RCS file: /cvsroot/bison/bison/src/parse-gram.y,v
retrieving revision 1.33
diff -p -u -r1.33 parse-gram.y
--- src/parse-gram.y 30 Nov 2002 09:16:54 -0000 1.33
+++ src/parse-gram.y 7 Dec 2002 05:41:58 -0000
@@ -42,20 +42,9 @@
/* Produce verbose syntax errors. */
#define YYERROR_VERBOSE 1
-#define YYLLOC_DEFAULT(Current, Rhs, N) \
-do { \
- if (N) \
- { \
- Current.first_column = Rhs[1].first_column; \
- Current.first_line = Rhs[1].first_line; \
- Current.last_column = Rhs[N].last_column; \
- Current.last_line = Rhs[N].last_line; \
- } \
- else \
- { \
- Current = Rhs[0]; \
- } \
-} while (0)
+
+#define YYLLOC_DEFAULT(Current, Rhs, N) (Current) = lloc_default (Rhs, N)
+static YYLTYPE lloc_default (YYLTYPE const *, int);
/* Request detailed syntax error messages, and pass them to GRAM_ERROR.
FIXME: depends on the undocumented availability of YYLLOC. */
@@ -143,9 +132,9 @@ braced_code_t current_braced_code = acti
%token TYPE "type"
%token EQUAL "="
%token SEMICOLON ";"
-%token COLON ":"
%token PIPE "|"
%token ID "identifier"
+%token ID_COLON "identifier:"
%token PERCENT_PERCENT "%%"
%token PROLOGUE "%{...%}"
%token EPILOGUE "epilogue"
@@ -157,7 +146,7 @@ braced_code_t current_braced_code = acti
PROLOGUE EPILOGUE
%type <struniq> TYPE
%type <integer> INT
-%type <symbol> ID symbol string_as_id
+%type <symbol> ID ID_COLON symbol string_as_id
%type <assoc> precedence_declarator
%type <list> symbols.1
%%
@@ -173,7 +162,7 @@ input:
declarations:
/* Nothing */
-| declarations declaration semi_colon.opt
+| declarations declaration
;
declaration:
@@ -197,6 +186,7 @@ declaration:
| "%token-table" { token_table_flag = 1; }
| "%verbose" { report_flag = 1; }
| "%yacc" { yacc_flag = 1; }
+| ";"
;
grammar_declaration:
@@ -209,7 +199,7 @@ grammar_declaration:
| "%union" BRACED_CODE
{
typed = 1;
- MUSCLE_INSERT_INT ("stype_line", @2.first_line);
+ MUSCLE_INSERT_INT ("stype_line", @2.start.line);
muscle_insert ("stype", $2);
}
| "%destructor"
@@ -322,9 +312,7 @@ symbol_def:
/* One or more symbol definitions. */
symbol_defs.1:
symbol_def
- {;}
| symbol_defs.1 symbol_def
- {;}
;
@@ -338,11 +326,10 @@ grammar:
;
/* As a Bison extension, one can use the grammar declarations in the
- body of the grammar. But to remain LALR(1), they must be ended
- with a semi-colon. */
+ body of the grammar. */
rules_or_grammar_declaration:
rules
-| grammar_declaration ";"
+| grammar_declaration
{
if (yacc_flag)
complain_at (@$, _("POSIX forbids declarations in the grammar"));
@@ -351,11 +338,11 @@ rules_or_grammar_declaration:
{
yyerrok;
}
+| ";"
;
rules:
- ID ":" { current_lhs = $1; current_lhs_location = @1; } rhses.1 ";"
- {;}
+ ID_COLON { current_lhs = $1; current_lhs_location = @1; } rhses.1
;
rhses.1:
@@ -424,11 +411,42 @@ epilogue.opt:
}
;
-semi_colon.opt:
- /* Nothing. */
-| ";"
-;
%%
+
+
+/* Return the location of the left-hand side of a rule whose
+ right-hand side is RHS[1] ... RHS[N]. Ignore empty nonterminals in
+ the right-hand side, and return an empty location equal to the end
+ boundary of RHS[0] if the right-hand side is empty. */
+
+static YYLTYPE
+lloc_default (YYLTYPE const *rhs, int n)
+{
+ int i;
+ int j;
+ YYLTYPE r;
+ r.start = r.end = rhs[n].end;
+
+ for (i = 1; i <= n; i++)
+ if (! equal_boundaries (rhs[i].start, rhs[i].end))
+ {
+ r.start = rhs[i].start;
+
+ for (j = n; i < j; j--)
+ if (! equal_boundaries (rhs[j].start, rhs[j].end))
+ break;
+ r.end = rhs[j].end;
+
+ break;
+ }
+
+ return r;
+}
+
+
+/* Add a lex-param or a parse-param (depending on TYPE) with
+ declaration DECL and location LOC. */
+
static void
add_param (char const *type, char const *decl, location_t loc)
{
Index: src/reader.c
===================================================================
RCS file: /cvsroot/bison/bison/src/reader.c,v
retrieving revision 1.226
diff -p -u -r1.226 reader.c
--- src/reader.c 30 Nov 2002 09:52:11 -0000 1.226
+++ src/reader.c 7 Dec 2002 05:41:58 -0000
@@ -70,8 +70,9 @@ prologue_augment (const char *prologue,
!typed ? &pre_prologue_obstack : &post_prologue_obstack;
obstack_fgrow1 (oout, "]b4_syncline([[%d]], [[",
- location.first_line);
- MUSCLE_OBSTACK_SGROW (oout, quotearg_style (c_quoting_style, location.file));
+ location.start.line);
+ MUSCLE_OBSTACK_SGROW (oout, quotearg_style (c_quoting_style,
+ location.start.file));
obstack_sgrow (oout, "]])[\n");
obstack_sgrow (oout, prologue);
}
@@ -88,9 +89,9 @@ epilogue_augment (const char *epilogue,
{
char *extension = NULL;
obstack_fgrow1 (&muscle_obstack, "]b4_syncline([[%d]], [[",
- location.first_line);
+ location.start.line);
MUSCLE_OBSTACK_SGROW (&muscle_obstack,
- quotearg_style (c_quoting_style, location.file));
+ quotearg_style (c_quoting_style, location.start.file));
obstack_sgrow (&muscle_obstack, "]])[\n");
obstack_sgrow (&muscle_obstack, epilogue);
obstack_1grow (&muscle_obstack, 0);
Index: src/reader.h
===================================================================
RCS file: /cvsroot/bison/bison/src/reader.h,v
retrieving revision 1.33
retrieving revision 1.34
diff -p -u -r1.33 -r1.34
--- src/reader.h 30 Nov 2002 09:16:32 -0000 1.33
+++ src/reader.h 7 Dec 2002 06:11:11 -0000 1.34
@@ -1,5 +1,5 @@
/* Input parser for bison
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -21,6 +21,7 @@
#ifndef READER_H_
# define READER_H_
+# include "location.h"
# include "symlist.h"
# include "parse-gram.h"
@@ -35,6 +36,7 @@ merger_list;
/* From the scanner. */
extern FILE *gram_in;
extern int gram__flex_debug;
+extern boundary scanner_cursor;
void scanner_initialize (void);
void scanner_free (void);
void scanner_last_string_free (void);
Index: src/reduce.c
===================================================================
RCS file: /cvsroot/bison/bison/src/reduce.c,v
retrieving revision 1.77
diff -p -u -r1.77 reduce.c
--- src/reduce.c 12 Nov 2002 08:05:59 -0000 1.77
+++ src/reduce.c 7 Dec 2002 05:41:59 -0000
@@ -1,5 +1,5 @@
/* Grammar reduction for Bison.
- Copyright (C) 1988, 1989, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1988, 1989, 2000, 2001, 2002 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -297,9 +297,7 @@ nonterminals_reduce (void)
if (!bitset_test (V, i))
{
nontermmap[i] = n++;
- LOCATION_PRINT (stderr, symbols[i]->location);
- fprintf (stderr, ": %s: %s: %s\n",
- _("warning"), _("useless nonterminal"),
+ warn_at (symbols[i]->location, _("useless nonterminal: %s"),
symbols[i]->tag);
}
Index: src/scan-gram.l
===================================================================
RCS file: /cvsroot/bison/bison/src/scan-gram.l,v
retrieving revision 1.47
diff -p -u -r1.47 scan-gram.l
--- src/scan-gram.l 1 Dec 2002 02:37:56 -0000 1.47
+++ src/scan-gram.l 7 Dec 2002 05:41:59 -0000
@@ -26,23 +26,27 @@
#include "system.h"
#include "mbswidth.h"
#include "complain.h"
+#include "files.h"
#include "quote.h"
#include "struniq.h"
#include "getargs.h"
#include "gram.h"
#include "reader.h"
-#define YY_USER_INIT \
-do { \
- LOCATION_RESET (*loc); \
- loc->file = current_file; \
-} while (0)
+#define YY_USER_INIT \
+ do \
+ { \
+ scanner_cursor.file = current_file; \
+ scanner_cursor.line = 1; \
+ scanner_cursor.column = 1; \
+ } \
+ while (0)
-/* Each time we match a string, move the end cursor to its end. */
-#define STEP LOCATION_STEP (*loc)
+/* Location of scanner cursor. */
+boundary scanner_cursor;
-static void extend_location (location_t *, char const *, int);
-#define YY_USER_ACTION extend_location (loc, yytext, yyleng);
+static void adjust_location (location_t *, char const *, size_t);
+#define YY_USER_ACTION adjust_location (loc, yytext, yyleng);
static size_t no_cr_read (FILE *, char *, size_t);
#define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
@@ -93,13 +97,14 @@ static void handle_dollar (braced_code_t
char *cp, location_t location);
static void handle_at (braced_code_t code_kind,
char *cp, location_t location);
-static void handle_syncline (char *args, location_t *location);
+static void handle_syncline (char *args);
static int convert_ucn_to_byte (char const *hex_text);
-static void unexpected_end_of_file (location_t *, char const *);
+static void unexpected_end_of_file (boundary, char const *);
%}
%x SC_COMMENT SC_LINE_COMMENT SC_YACC_COMMENT
%x SC_STRING SC_CHARACTER
+%x SC_AFTER_IDENTIFIER
%x SC_ESCAPED_STRING SC_ESCAPED_CHARACTER
%x SC_BRACED_CODE SC_PROLOGUE SC_EPILOGUE
@@ -122,15 +127,41 @@ splice (\\[ \f\t\v]*\n)*
/* Nesting level of the current code in braces. */
int braces_level IF_LINT (= 0);
- /* Scanner context when scanning C code. */
- int c_context IF_LINT (= 0);
+ /* Parent context state, when applicable. */
+ int context_state IF_LINT (= 0);
- /* At each yylex invocation, mark the current position as the
- start of the next token. */
- STEP;
+ /* Location of most recent identifier, when applicable. */
+ location_t id_loc IF_LINT (= *loc);
+
+ /* Location where containing code started, when applicable. */
+ boundary code_start IF_LINT (= loc->start);
+
+ /* Location where containing comment or string or character literal
+ started, when applicable. */
+ boundary token_start IF_LINT (= loc->start);
%}
+ /*-----------------------.
+ | Scanning white space. |
+ `-----------------------*/
+
+<INITIAL,SC_AFTER_IDENTIFIER>
+{
+ [ \f\n\t\v] ;
+
+ /* Comments. */
+ "/*" token_start = loc->start; context_state = YY_START; BEGIN
SC_YACC_COMMENT;
+ "//".* ;
+
+ /* #line directives are not documented, and may be withdrawn or
+ modified in future versions of Bison. */
+ ^"#line "{int}" \"".*"\"\n" {
+ handle_syncline (yytext + sizeof "#line " - 1);
+ }
+}
+
+
/*----------------------------.
| Scanning Bison directives. |
`----------------------------*/
@@ -171,32 +202,23 @@ splice (\\[ \f\t\v]*\n)*
"%verbose" return PERCENT_VERBOSE;
"%yacc" return PERCENT_YACC;
- {directive} {
+ {directive} {
complain_at (*loc, _("invalid directive: %s"), quote (yytext));
- STEP;
- }
-
- ^"#line "{int}" \"".*"\"\n" {
- handle_syncline (yytext + sizeof "#line " - 1, loc);
- STEP;
}
"=" return EQUAL;
- ":" rule_length = 0; return COLON;
"|" rule_length = 0; return PIPE;
";" return SEMICOLON;
- [ \f\n\t\v] STEP;
-
"," {
warn_at (*loc, _("stray `,' treated as white space"));
- STEP;
}
- {id} {
+ {id} {
val->symbol = symbol_get (yytext, *loc);
+ id_loc = *loc;
rule_length++;
- return ID;
+ BEGIN SC_AFTER_IDENTIFIER;
}
{int} {
@@ -213,20 +235,21 @@ splice (\\[ \f\t\v]*\n)*
}
/* Characters. We don't check there is only one. */
- "'" STRING_GROW; BEGIN SC_ESCAPED_CHARACTER;
+ "'" STRING_GROW; token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
/* Strings. */
- "\"" STRING_GROW; BEGIN SC_ESCAPED_STRING;
-
- /* Comments. */
- "/*" BEGIN SC_YACC_COMMENT;
- "//".* STEP;
+ "\"" STRING_GROW; token_start = loc->start; BEGIN SC_ESCAPED_STRING;
/* Prologue. */
- "%{" BEGIN SC_PROLOGUE;
+ "%{" code_start = loc->start; BEGIN SC_PROLOGUE;
/* Code in between braces. */
- "{" STRING_GROW; braces_level = 0; BEGIN SC_BRACED_CODE;
+ "{" {
+ STRING_GROW;
+ braces_level = 0;
+ code_start = loc->start;
+ BEGIN SC_BRACED_CODE;
+ }
/* A type. */
"<"{tag}">" {
@@ -240,13 +263,42 @@ splice (\\[ \f\t\v]*\n)*
"%%" {
static int percent_percent_count;
if (++percent_percent_count == 2)
- BEGIN SC_EPILOGUE;
+ {
+ code_start = loc->start;
+ BEGIN SC_EPILOGUE;
+ }
return PERCENT_PERCENT;
}
. {
complain_at (*loc, _("invalid character: %s"), quote (yytext));
- STEP;
+ }
+}
+
+
+ /*-----------------------------------------------------------------.
+ | Scanning after an identifier, checking whether a colon is next. |
+ `-----------------------------------------------------------------*/
+
+<SC_AFTER_IDENTIFIER>
+{
+ ":" {
+ rule_length = 0;
+ *loc = id_loc;
+ BEGIN INITIAL;
+ return ID_COLON;
+ }
+ . {
+ scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0);
+ yyless (0);
+ *loc = id_loc;
+ BEGIN INITIAL;
+ return ID;
+ }
+ <<EOF>> {
+ *loc = id_loc;
+ BEGIN INITIAL;
+ return ID;
}
}
@@ -257,13 +309,9 @@ splice (\\[ \f\t\v]*\n)*
<SC_YACC_COMMENT>
{
- "*/" {
- STEP;
- BEGIN INITIAL;
- }
-
+ "*/" BEGIN context_state;
.|\n ;
- <<EOF>> unexpected_end_of_file (loc, "*/");
+ <<EOF>> unexpected_end_of_file (token_start, "*/");
}
@@ -273,8 +321,8 @@ splice (\\[ \f\t\v]*\n)*
<SC_COMMENT>
{
- "*"{splice}"/" STRING_GROW; BEGIN c_context;
- <<EOF>> unexpected_end_of_file (loc, "*/");
+ "*"{splice}"/" STRING_GROW; BEGIN context_state;
+ <<EOF>> unexpected_end_of_file (token_start, "*/");
}
@@ -284,9 +332,9 @@ splice (\\[ \f\t\v]*\n)*
<SC_LINE_COMMENT>
{
- "\n" STRING_GROW; BEGIN c_context;
+ "\n" STRING_GROW; BEGIN context_state;
{splice} STRING_GROW;
- <<EOF>> BEGIN c_context;
+ <<EOF>> BEGIN context_state;
}
@@ -300,6 +348,7 @@ splice (\\[ \f\t\v]*\n)*
"\"" {
STRING_GROW;
STRING_FINISH;
+ loc->start = token_start;
val->string = last_string;
rule_length++;
BEGIN INITIAL;
@@ -307,7 +356,7 @@ splice (\\[ \f\t\v]*\n)*
}
.|\n STRING_GROW;
- <<EOF>> unexpected_end_of_file (loc, "\"");
+ <<EOF>> unexpected_end_of_file (token_start, "\"");
}
/*---------------------------------------------------------------.
@@ -320,6 +369,7 @@ splice (\\[ \f\t\v]*\n)*
"'" {
STRING_GROW;
STRING_FINISH;
+ loc->start = token_start;
val->symbol = symbol_get (last_string, *loc);
symbol_class_set (val->symbol, token_sym, *loc);
symbol_user_token_number_set (val->symbol,
@@ -331,7 +381,7 @@ splice (\\[ \f\t\v]*\n)*
}
.|\n STRING_GROW;
- <<EOF>> unexpected_end_of_file (loc, "'");
+ <<EOF>> unexpected_end_of_file (token_start, "'");
}
@@ -344,11 +394,7 @@ splice (\\[ \f\t\v]*\n)*
\\[0-7]{1,3} {
unsigned long c = strtoul (yytext + 1, 0, 8);
if (UCHAR_MAX < c)
- {
- complain_at (*loc, _("invalid escape sequence: %s"),
- quote (yytext));
- STEP;
- }
+ complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
else
obstack_1grow (&string_obstack, c);
}
@@ -358,11 +404,7 @@ splice (\\[ \f\t\v]*\n)*
errno = 0;
c = strtoul (yytext + 2, 0, 16);
if (UCHAR_MAX < c || errno)
- {
- complain_at (*loc, _("invalid escape sequence: %s"),
- quote (yytext));
- STEP;
- }
+ complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
else
obstack_1grow (&string_obstack, c);
}
@@ -381,17 +423,12 @@ splice (\\[ \f\t\v]*\n)*
\\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
int c = convert_ucn_to_byte (yytext);
if (c < 0)
- {
- complain_at (*loc, _("invalid escape sequence: %s"),
- quote (yytext));
- STEP;
- }
+ complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
else
obstack_1grow (&string_obstack, c);
}
\\(.|\n) {
- complain_at (*loc, _("unrecognized escape sequence: %s"),
- quote (yytext));
+ complain_at (*loc, _("unrecognized escape sequence: %s"), quote (yytext));
STRING_GROW;
}
}
@@ -404,9 +441,9 @@ splice (\\[ \f\t\v]*\n)*
<SC_CHARACTER>
{
- "'" STRING_GROW; BEGIN c_context;
+ "'" STRING_GROW; BEGIN context_state;
address@hidden STRING_GROW;
- <<EOF>> unexpected_end_of_file (loc, "'");
+ <<EOF>> unexpected_end_of_file (token_start, "'");
}
@@ -417,9 +454,9 @@ splice (\\[ \f\t\v]*\n)*
<SC_STRING>
{
- "\"" STRING_GROW; BEGIN c_context;
+ "\"" STRING_GROW; BEGIN context_state;
address@hidden STRING_GROW;
- <<EOF>> unexpected_end_of_file (loc, "\"");
+ <<EOF>> unexpected_end_of_file (token_start, "\"");
}
@@ -429,10 +466,29 @@ splice (\\[ \f\t\v]*\n)*
<SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
{
- "'" STRING_GROW; c_context = YY_START; BEGIN SC_CHARACTER;
- "\"" STRING_GROW; c_context = YY_START; BEGIN SC_STRING;
- "/"{splice}"*" STRING_GROW; c_context = YY_START; BEGIN SC_COMMENT;
- "/"{splice}"/" STRING_GROW; c_context = YY_START; BEGIN SC_LINE_COMMENT;
+ "'" {
+ STRING_GROW;
+ context_state = YY_START;
+ token_start = loc->start;
+ BEGIN SC_CHARACTER;
+ }
+ "\"" {
+ STRING_GROW;
+ context_state = YY_START;
+ token_start = loc->start;
+ BEGIN SC_STRING;
+ }
+ "/"{splice}"*" {
+ STRING_GROW;
+ context_state = YY_START;
+ token_start = loc->start;
+ BEGIN SC_COMMENT;
+ }
+ "/"{splice}"/" {
+ STRING_GROW;
+ context_state = YY_START;
+ BEGIN SC_LINE_COMMENT;
+ }
}
@@ -451,6 +507,7 @@ splice (\\[ \f\t\v]*\n)*
if (braces_level < 0)
{
STRING_FINISH;
+ loc->start = code_start;
val->string = last_string;
rule_length++;
BEGIN INITIAL;
@@ -467,7 +524,7 @@ splice (\\[ \f\t\v]*\n)*
"@"(-?[0-9]+|"$") { handle_at (current_braced_code,
yytext, *loc); }
- <<EOF>> unexpected_end_of_file (loc, "}");
+ <<EOF>> unexpected_end_of_file (code_start, "}");
}
@@ -479,12 +536,13 @@ splice (\\[ \f\t\v]*\n)*
{
"%}" {
STRING_FINISH;
+ loc->start = code_start;
val->string = last_string;
BEGIN INITIAL;
return PROLOGUE;
}
- <<EOF>> unexpected_end_of_file (loc, "%}");
+ <<EOF>> unexpected_end_of_file (code_start, "%}");
}
@@ -497,6 +555,7 @@ splice (\\[ \f\t\v]*\n)*
{
<<EOF>> {
STRING_FINISH;
+ loc->start = code_start;
val->string = last_string;
BEGIN INITIAL;
return EPILOGUE;
@@ -521,24 +580,23 @@ splice (\\[ \f\t\v]*\n)*
%%
-/* Extend *LOC to account for token TOKEN of size SIZE. */
+/* Set *LOC and adjust scanner cursor to account for token TOKEN of
+ size SIZE. */
static void
-extend_location (location_t *loc, char const *token, int size)
+adjust_location (location_t *loc, char const *token, size_t size)
{
- int line = loc->last_line;
- int column = loc->last_column;
+ int line = scanner_cursor.line;
+ int column = scanner_cursor.column;
char const *p0 = token;
char const *p = token;
char const *lim = token + size;
+ loc->start = scanner_cursor;
+
for (p = token; p < lim; p++)
switch (*p)
{
- case '\r':
- /* \r shouldn't survive no_cr_read. */
- abort ();
-
case '\n':
line++;
column = 1;
@@ -552,8 +610,10 @@ extend_location (location_t *loc, char c
break;
}
- loc->last_line = line;
- loc->last_column = column + mbsnwidth (p0, p - p0, 0);
+ scanner_cursor.line = line;
+ scanner_cursor.column = column + mbsnwidth (p0, p - p0, 0);
+
+ loc->end = scanner_cursor;
}
@@ -839,34 +899,37 @@ convert_ucn_to_byte (char const *ucn)
`----------------------------------------------------------------*/
static void
-handle_syncline (char *args, location_t *location)
+handle_syncline (char *args)
{
int lineno = strtol (args, &args, 10);
const char *file = NULL;
file = strchr (args, '"') + 1;
*strchr (file, '"') = 0;
- current_file = xstrdup (file);
- location->file = current_file;
- location->last_line = lineno;
+ scanner_cursor.file = current_file = xstrdup (file);
+ scanner_cursor.line = lineno;
+ scanner_cursor.column = 1;
}
-/*-------------------------------------------------------------.
-| Report an unexpected end of file at LOC. An end of file was |
-| encountered and the expected TOKEN_END was missing. After |
-| reporting the problem, pretend that TOKEN_END was found. |
-`-------------------------------------------------------------*/
+/*------------------------------------------------------------------------.
+| Report an unexpected EOF in a token or comment starting at START. |
+| An end of file was encountered and the expected TOKEN_END was missing. |
+| After reporting the problem, pretend that TOKEN_END was found. |
+`------------------------------------------------------------------------*/
static void
-unexpected_end_of_file (location_t *loc, char const *token_end)
+unexpected_end_of_file (boundary start, char const *token_end)
{
size_t i = strlen (token_end);
- complain_at (*loc, _("missing `%s' at end of file"), token_end);
-
- /* Adjust location's last column so that any later message does not
- mention the characters just inserted. */
- loc->last_column -= i;
+ location_t location;
+ location.start = start;
+ location.end = scanner_cursor;
+ complain_at (location, _("missing `%s' at end of file"), token_end);
+
+ /* Adjust scanner cursor so that any later message does not count
+ the characters about to be inserted. */
+ scanner_cursor.column -= i;
while (i != 0)
unput (token_end[--i]);
Index: tests/conflicts.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/conflicts.at,v
retrieving revision 1.21
diff -p -u -r1.21 conflicts.at
--- tests/conflicts.at 15 Nov 2002 20:32:21 -0000 1.21
+++ tests/conflicts.at 7 Dec 2002 05:41:59 -0000
@@ -38,7 +38,7 @@ e: 'e' | /* Nothing. */;
]])
AT_CHECK([bison -o input.c input.y], 0, [],
-[[input.y:4.8: warning: rule never reduced because of conflicts: e: /* empty */
+[[input.y:4.9: warning: rule never reduced because of conflicts: e: /* empty */
]])
AT_CLEANUP
@@ -370,7 +370,7 @@ id : '0';
AT_CHECK([bison -o input.c --report=all input.y], 0, [],
[[input.y: warning: 1 reduce/reduce conflict
-input.y:4.4-8: warning: rule never reduced because of conflicts: id: '0'
+input.y:4.6-8: warning: rule never reduced because of conflicts: id: '0'
]])
# Check the contents of the report.
Index: tests/input.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/input.at,v
retrieving revision 1.22
diff -p -u -r1.22 input.at
--- tests/input.at 30 Nov 2002 09:51:50 -0000 1.22
+++ tests/input.at 7 Dec 2002 05:41:59 -0000
@@ -33,7 +33,7 @@ exp: { $$ = $1 ; };
]])
AT_CHECK([bison input.y], [1], [],
-[[input.y:2.6-14: integer out of range: `$1'
+[[input.y:2.13-14: integer out of range: `$1'
]])
AT_CLEANUP
@@ -51,7 +51,7 @@ exp: { @$ = @1 ; };
]])
AT_CHECK([bison input.y], [1], [],
-[[input.y:2.6-14: integer out of range: address@hidden'
+[[input.y:2.13-14: integer out of range: address@hidden'
]])
AT_CLEANUP
@@ -74,9 +74,9 @@ exp: foo {} foo
]])
AT_CHECK([bison input.y], [], [],
-[[input.y:4.4-15: warning: type clash on default action: <bar> != <>
-input.y:5.4-8: warning: type clash on default action: <bar> != <>
-input.y:6.4: warning: empty rule for typed nonterminal, and no action
+[[input.y:4.6-15: warning: type clash on default action: <bar> != <>
+input.y:5.6-8: warning: type clash on default action: <bar> != <>
+input.y:6.5: warning: empty rule for typed nonterminal, and no action
]])
AT_CLEANUP
Index: tests/reduce.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/reduce.at,v
retrieving revision 1.12
diff -p -u -r1.12 reduce.at
--- tests/reduce.at 2 Aug 2002 08:05:01 -0000 1.12
+++ tests/reduce.at 7 Dec 2002 05:41:59 -0000
@@ -1,5 +1,5 @@
# Exercising Bison Grammar Reduction. -*- Autotest -*-
-# Copyright 2001 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -154,15 +154,15 @@ input.y:11.1-8: warning: useless nonterm
input.y:12.1-8: warning: useless nonterminal: useless7
input.y:13.1-8: warning: useless nonterminal: useless8
input.y:14.1-8: warning: useless nonterminal: useless9
-input.y:6.9-13: warning: useless rule: useless1: '1'
-input.y:7.9-13: warning: useless rule: useless2: '2'
-input.y:8.9-13: warning: useless rule: useless3: '3'
-input.y:9.9-13: warning: useless rule: useless4: '4'
-input.y:10.9-13: warning: useless rule: useless5: '5'
-input.y:11.9-13: warning: useless rule: useless6: '6'
-input.y:12.9-13: warning: useless rule: useless7: '7'
-input.y:13.9-13: warning: useless rule: useless8: '8'
-input.y:14.9-13: warning: useless rule: useless9: '9'
+input.y:6.11-13: warning: useless rule: useless1: '1'
+input.y:7.11-13: warning: useless rule: useless2: '2'
+input.y:8.11-13: warning: useless rule: useless3: '3'
+input.y:9.11-13: warning: useless rule: useless4: '4'
+input.y:10.11-13: warning: useless rule: useless5: '5'
+input.y:11.11-13: warning: useless rule: useless6: '6'
+input.y:12.11-13: warning: useless rule: useless7: '7'
+input.y:13.11-13: warning: useless rule: useless8: '8'
+input.y:14.11-13: warning: useless rule: useless9: '9'
]])
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
@@ -242,9 +242,9 @@ AT_CHECK([[bison not-reduced.y]], 0, [],
[[not-reduced.y: warning: 2 useless nonterminals and 3 useless rules
not-reduced.y:14.1-13: warning: useless nonterminal: not_reachable
not-reduced.y:11.6-19: warning: useless nonterminal: non_productive
-not-reduced.y:11.4-57: warning: useless rule: exp: non_productive
-not-reduced.y:14.14-56: warning: useless rule: not_reachable: useful
-not-reduced.y:17.15-18.63: warning: useless rule: non_productive:
non_productive useless_token
+not-reduced.y:11.6-57: warning: useless rule: exp: non_productive
+not-reduced.y:14.16-56: warning: useless rule: not_reachable: useful
+not-reduced.y:17.17-18.63: warning: useless rule: non_productive:
non_productive useless_token
]])
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' not-reduced.output]], 0,
@@ -316,9 +316,9 @@ AT_CHECK([[bison input.y]], 0, [],
[[input.y: warning: 2 useless nonterminals and 3 useless rules
input.y:5.15-25: warning: useless nonterminal: underivable
input.y:6.14-24: warning: useless nonterminal: indirection
-input.y:5.13-25: warning: useless rule: exp: underivable
-input.y:6.12-24: warning: useless rule: underivable: indirection
-input.y:7.12-24: warning: useless rule: indirection: underivable
+input.y:5.15-25: warning: useless rule: exp: underivable
+input.y:6.14-24: warning: useless rule: underivable: indirection
+input.y:7.14-24: warning: useless rule: indirection: underivable
]])
AT_CHECK([[sed -n '/^Grammar/q;/^$/!p' input.output]], 0,
Index: tests/regression.at
===================================================================
RCS file: /cvsroot/bison/bison/tests/regression.at,v
retrieving revision 1.76
diff -p -u -r1.76 regression.at
--- tests/regression.at 15 Nov 2002 20:32:21 -0000 1.76
+++ tests/regression.at 7 Dec 2002 05:41:59 -0000
@@ -298,7 +298,7 @@ input.y:5.1-17: invalid directive: `%a-d
input.y:6.1: invalid character: `%'
input.y:6.2: invalid character: `-'
input.y:7.1-8.0: missing `%}' at end of file
-input.y:7.1-8.0: syntax error, unexpected "%{...%}", expecting ";" or "|"
+input.y:7.1-8.0: syntax error, unexpected "%{...%}"
]])
AT_CLEANUP
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Bison patch to allow rules without trailing semicolon,
Paul Eggert <=