Let symbols have a location.

* src/symtab.h, src/symtab.c (symbol_t): Location is a new member.
(getsym): Adjust.
Adjust all callers.
* src/complain.h, src/complain.c (complain_at, fatal_at, warn_at):
Use location_t, not int.
* src/symtab.c (symbol_check_defined): Take advantage of the
location.
* tests/regression.at (Invalid inputs): Adjust.
This commit is contained in:
Akim Demaille
2002-06-15 18:21:46 +00:00
parent 8efe435c05
commit ee000ba4fc
11 changed files with 74 additions and 60 deletions

View File

@@ -1,3 +1,16 @@
2002-06-15 Akim Demaille <akim@epita.fr>
Let symbols have a location.
* src/symtab.h, src/symtab.c (symbol_t): Location is a new member.
(getsym): Adjust.
Adjust all callers.
* src/complain.h, src/complain.c (complain_at, fatal_at, warn_at):
Use location_t, not int.
* src/symtab.c (symbol_check_defined): Take advantage of the
location.
* tests/regression.at (Invalid inputs): Adjust.
2002-06-15 Akim Demaille <akim@epita.fr> 2002-06-15 Akim Demaille <akim@epita.fr>
* src/parse-gram.y (YYLLOC_DEFAULT, current_lhs_location): New. * src/parse-gram.y (YYLLOC_DEFAULT, current_lhs_location): New.

View File

@@ -116,10 +116,10 @@ unsigned int complain_message_count;
void void
#if defined VA_START && defined __STDC__ #if defined VA_START && defined __STDC__
warn_at (int location, const char *message, ...) warn_at (location_t location, const char *message, ...)
#else #else
warn_at (location, message, va_alist) warn_at (location, message, va_alist)
int location location_t location
char *message; char *message;
va_dcl va_dcl
#endif #endif
@@ -133,21 +133,18 @@ warn_at (location, message, va_alist)
static const char *old_infile; static const char *old_infile;
static int old_lineno; static int old_lineno;
if (old_lineno == location && if (old_lineno == location.first_line &&
(infile == old_infile || !strcmp (old_infile, infile))) (infile == old_infile || !strcmp (old_infile, infile)))
/* Simply return and print nothing. */ /* Simply return and print nothing. */
return; return;
old_infile = infile; old_infile = infile;
old_lineno = location; old_lineno = location.first_line;
} }
fflush (stdout); fflush (stdout);
if (infile != NULL) LOCATION_PRINT (stderr, location);
fprintf (stderr, "%s:%d: ", infile, location); fputs (": ", stderr);
else
fprintf (stderr, "%s:", program_name);
fputs (_("warning: "), stderr); fputs (_("warning: "), stderr);
#ifdef VA_START #ifdef VA_START
@@ -218,10 +215,10 @@ warn (message, va_alist)
void void
#if defined VA_START && defined __STDC__ #if defined VA_START && defined __STDC__
complain_at (int location, const char *message, ...) complain_at (location_t location, const char *message, ...)
#else #else
complain_at (location, message, va_alist) complain_at (location, message, va_alist)
int location; location_t location;
char *message; char *message;
va_dcl va_dcl
#endif #endif
@@ -235,20 +232,18 @@ complain_at (location, message, va_alist)
static const char *old_infile; static const char *old_infile;
static int old_lineno; static int old_lineno;
if (old_lineno == location && if (old_lineno == location.first_line &&
(infile == old_infile || !strcmp (old_infile, infile))) (infile == old_infile || !strcmp (old_infile, infile)))
/* Simply return and print nothing. */ /* Simply return and print nothing. */
return; return;
old_infile = infile; old_infile = infile;
old_lineno = location; old_lineno = location.first_line;
} }
fflush (stdout); fflush (stdout);
if (infile != NULL) LOCATION_PRINT (stderr, location);
fprintf (stderr, "%s:%d: ", infile, location); fputs (": ", stderr);
else
fprintf (stderr, "%s:", program_name);
#ifdef VA_START #ifdef VA_START
VA_START (args, message); VA_START (args, message);
@@ -316,10 +311,10 @@ complain (message, va_alist)
void void
#if defined VA_START && defined __STDC__ #if defined VA_START && defined __STDC__
fatal_at (int location, const char *message, ...) fatal_at (location_t location, const char *message, ...)
#else #else
fatal (location, message, va_alist) fatal (location, message, va_alist)
int location; location_t location;
char *message; char *message;
va_dcl va_dcl
#endif #endif
@@ -329,11 +324,8 @@ fatal (location, message, va_alist)
#endif #endif
fflush (stdout); fflush (stdout);
if (infile != NULL) LOCATION_PRINT (stderr, location);
fprintf (stderr, "%s:%d: ", infile, location); fputs (": ", stderr);
else
fprintf (stderr, "%s:", program_name);
fputs (_("fatal error: "), stderr); fputs (_("fatal error: "), stderr);
#ifdef VA_START #ifdef VA_START

View File

@@ -1,5 +1,5 @@
/* Declaration for error-reporting function for Bison. /* Declaration for error-reporting function for Bison.
Copyright 2000, 2001 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 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 under the terms of the GNU General Public License as published by the
@@ -17,20 +17,22 @@
USA. */ USA. */
#ifndef COMPLAIN_H_ #ifndef COMPLAIN_H_
#define COMPLAIN_H_ 1 # define COMPLAIN_H_ 1
#ifdef __cplusplus # include "location.h"
# ifdef __cplusplus
extern "C" { extern "C" {
#endif # endif
#ifdef __STDC__ # ifdef __STDC__
/* Informative messages, but we proceed. */ /* Informative messages, but we proceed. */
void warn (const char *format, ...) void warn (const char *format, ...)
__attribute__ ((__format__ (__printf__, 1, 2))); __attribute__ ((__format__ (__printf__, 1, 2)));
void warn_at (int location, const char *format, ...) void warn_at (location_t location, const char *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3))); __attribute__ ((__format__ (__printf__, 2, 3)));
/* Something bad happen, but let's continue and die later. */ /* Something bad happen, but let's continue and die later. */
@@ -38,7 +40,7 @@ void warn_at (int location, const char *format, ...)
void complain (const char *format, ...) void complain (const char *format, ...)
__attribute__ ((__format__ (__printf__, 1, 2))); __attribute__ ((__format__ (__printf__, 1, 2)));
void complain_at (int location, const char *format, ...) void complain_at (location_t location, const char *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3))); __attribute__ ((__format__ (__printf__, 2, 3)));
/* Something bad happen and we die now. */ /* Something bad happen and we die now. */
@@ -46,17 +48,17 @@ void complain_at (int location, const char *format, ...)
void fatal (const char *format, ...) void fatal (const char *format, ...)
__attribute__ ((__format__ (__printf__, 1, 2))); __attribute__ ((__format__ (__printf__, 1, 2)));
void fatal_at (int location, const char *format, ...) void fatal_at (location_t location, const char *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3))); __attribute__ ((__format__ (__printf__, 2, 3)));
#else # else
void warn (); void warn ();
void warn_at (); void warn_at ();
void complain (); void complain ();
void complain_at (); void complain_at ();
void fatal (); void fatal ();
void fatal_at (); void fatal_at ();
#endif # endif
/* Position in the current input file. */ /* Position in the current input file. */
extern char *infile; extern char *infile;
@@ -68,8 +70,8 @@ extern unsigned int warn_message_count;
/* This variable is incremented each time `complain' is called. */ /* This variable is incremented each time `complain' is called. */
extern unsigned int complain_message_count; extern unsigned int complain_message_count;
#ifdef __cplusplus # ifdef __cplusplus
} }
#endif # endif
#endif /* !COMPLAIN_H_ */ #endif /* !COMPLAIN_H_ */

View File

@@ -1489,7 +1489,7 @@ yyreduce:
case 64: case 64:
#line 339 "parse-gram.y" #line 339 "parse-gram.y"
{ yyval.symbol = getsym (yyvsp[0].string); } { yyval.symbol = getsym (yyvsp[0].string, yylsp[0]); }
break; break;
case 65: case 65:
@@ -1500,7 +1500,7 @@ yyreduce:
case 66: case 66:
#line 350 "parse-gram.y" #line 350 "parse-gram.y"
{ {
yyval.symbol = getsym (yyvsp[0].string); yyval.symbol = getsym (yyvsp[0].string, yylsp[0]);
symbol_class_set (yyval.symbol, token_sym); symbol_class_set (yyval.symbol, token_sym);
} }
break; break;

View File

@@ -336,7 +336,7 @@ rhs:
symbol: symbol:
ID { $$ = $1; } ID { $$ = $1; }
| string_as_id { $$ = $1; } | string_as_id { $$ = $1; }
| CHARACTER { $$ = getsym ($1); } | CHARACTER { $$ = getsym ($1, @1); }
; ;
action: action:
@@ -348,7 +348,7 @@ action:
string_as_id: string_as_id:
STRING STRING
{ {
$$ = getsym ($1); $$ = getsym ($1, @1);
symbol_class_set ($$, token_sym); symbol_class_set ($$, token_sym);
} }
; ;

View File

@@ -159,7 +159,7 @@ epilogue_set (const char *epilogue, location_t location)
`-------------------------------------------------------------------*/ `-------------------------------------------------------------------*/
static symbol_t * static symbol_t *
gensym (void) gensym (location_t location)
{ {
/* Incremented for each generated symbol */ /* Incremented for each generated symbol */
static int gensym_count = 0; static int gensym_count = 0;
@@ -168,7 +168,7 @@ gensym (void)
symbol_t *sym; symbol_t *sym;
sprintf (buf, "@%d", ++gensym_count); sprintf (buf, "@%d", ++gensym_count);
sym = getsym (buf); sym = getsym (buf, location);
sym->class = nterm_sym; sym->class = nterm_sym;
sym->number = nvars++; sym->number = nvars++;
return sym; return sym;
@@ -313,8 +313,8 @@ grammar_midrule_action (void)
/* Make a DUMMY nonterminal, whose location is that of the midrule /* Make a DUMMY nonterminal, whose location is that of the midrule
action. Create the MIDRULE. */ action. Create the MIDRULE. */
symbol_t *dummy = gensym ();
location_t dummy_location = current_rule->action_location; location_t dummy_location = current_rule->action_location;
symbol_t *dummy = gensym (dummy_location);
symbol_list *midrule = symbol_list_new (dummy, dummy_location); symbol_list *midrule = symbol_list_new (dummy, dummy_location);
/* Make a new rule, whose body is empty, before the current one, so /* Make a new rule, whose body is empty, before the current one, so
@@ -461,18 +461,18 @@ reader (void)
symbols_new (); symbols_new ();
/* Construct the axiom symbol. */ /* Construct the axiom symbol. */
axiom = getsym ("$axiom"); axiom = getsym ("$axiom", empty_location);
axiom->class = nterm_sym; axiom->class = nterm_sym;
axiom->number = nvars++; axiom->number = nvars++;
/* Construct the error token */ /* Construct the error token */
errtoken = getsym ("error"); errtoken = getsym ("error", empty_location);
errtoken->class = token_sym; errtoken->class = token_sym;
errtoken->number = ntokens++; errtoken->number = ntokens++;
/* Construct a token that represents all undefined literal tokens. /* Construct a token that represents all undefined literal tokens.
It is always token number 2. */ It is always token number 2. */
undeftoken = getsym ("$undefined."); undeftoken = getsym ("$undefined.", empty_location);
undeftoken->class = token_sym; undeftoken->class = token_sym;
undeftoken->number = ntokens++; undeftoken->number = ntokens++;
@@ -498,7 +498,7 @@ reader (void)
/* If the user did not define her EOFTOKEN, do it now. */ /* If the user did not define her EOFTOKEN, do it now. */
if (!eoftoken) if (!eoftoken)
{ {
eoftoken = getsym ("$"); eoftoken = getsym ("$", empty_location);
eoftoken->class = token_sym; eoftoken->class = token_sym;
eoftoken->number = 0; eoftoken->number = 0;
/* Value specified by POSIX. */ /* Value specified by POSIX. */

View File

@@ -1259,7 +1259,7 @@ case 34:
YY_RULE_SETUP YY_RULE_SETUP
#line 156 "scan-gram.l" #line 156 "scan-gram.l"
{ {
yylval->symbol = getsym (yytext); yylval->symbol = getsym (yytext, *yylloc);
return ID; return ID;
} }
YY_BREAK YY_BREAK
@@ -1450,7 +1450,7 @@ YY_RULE_SETUP
assert (yy_top_state () == INITIAL); assert (yy_top_state () == INITIAL);
{ {
YY_OBS_FINISH; YY_OBS_FINISH;
yylval->symbol = getsym (last_string); yylval->symbol = getsym (last_string, *yylloc);
symbol_class_set (yylval->symbol, token_sym); symbol_class_set (yylval->symbol, token_sym);
symbol_user_token_number_set (yylval->symbol, last_string[1]); symbol_user_token_number_set (yylval->symbol, last_string[1]);
YY_OBS_FREE; YY_OBS_FREE;

View File

@@ -154,7 +154,7 @@ blanks [ \t\f]+
{eols} YY_LINES; YY_STEP; {eols} YY_LINES; YY_STEP;
{blanks} YY_STEP; {blanks} YY_STEP;
{id} { {id} {
yylval->symbol = getsym (yytext); yylval->symbol = getsym (yytext, *yylloc);
return ID; return ID;
} }
@@ -286,7 +286,7 @@ blanks [ \t\f]+
assert (yy_top_state () == INITIAL); assert (yy_top_state () == INITIAL);
{ {
YY_OBS_FINISH; YY_OBS_FINISH;
yylval->symbol = getsym (last_string); yylval->symbol = getsym (last_string, *yylloc);
symbol_class_set (yylval->symbol, token_sym); symbol_class_set (yylval->symbol, token_sym);
symbol_user_token_number_set (yylval->symbol, last_string[1]); symbol_user_token_number_set (yylval->symbol, last_string[1]);
YY_OBS_FREE; YY_OBS_FREE;

View File

@@ -41,12 +41,13 @@ location_t startsymbol_location;
`---------------------------------*/ `---------------------------------*/
static symbol_t * static symbol_t *
symbol_new (const char *tag) symbol_new (const char *tag, location_t location)
{ {
symbol_t *res = XMALLOC (symbol_t, 1); symbol_t *res = XMALLOC (symbol_t, 1);
res->tag = xstrdup (tag); res->tag = xstrdup (tag);
res->type_name = NULL; res->type_name = NULL;
res->location = location;
res->number = NUMBER_UNDEFINED; res->number = NUMBER_UNDEFINED;
res->prec = 0; res->prec = 0;
res->assoc = right_assoc; res->assoc = right_assoc;
@@ -170,8 +171,9 @@ symbol_check_defined (symbol_t *this)
{ {
if (this->class == unknown_sym) if (this->class == unknown_sym)
{ {
complain complain_at
(_("symbol %s is used, but is not defined as a token and has no rules"), (this->location,
_("symbol %s is used, but is not defined as a token and has no rules"),
this->tag); this->tag);
this->class = nterm_sym; this->class = nterm_sym;
this->number = nvars++; this->number = nvars++;
@@ -363,7 +365,7 @@ symbols_new (void)
`----------------------------------------------------------------*/ `----------------------------------------------------------------*/
symbol_t * symbol_t *
getsym (const char *key) getsym (const char *key, location_t location)
{ {
symbol_t probe; symbol_t probe;
symbol_t *entry; symbol_t *entry;
@@ -374,7 +376,7 @@ getsym (const char *key)
if (!entry) if (!entry)
{ {
/* First insertion in the hash. */ /* First insertion in the hash. */
entry = symbol_new (key); entry = symbol_new (key, location);
hash_insert (symbol_table, entry); hash_insert (symbol_table, entry);
} }
return entry; return entry;
@@ -488,7 +490,9 @@ symbols_pack (void)
symbols_token_translations_init (); symbols_token_translations_init ();
if (startsymbol->class == unknown_sym) if (startsymbol->class == unknown_sym)
fatal (_("the start symbol %s is undefined"), startsymbol->tag); fatal_at (startsymbol_location,
_("the start symbol %s is undefined"), startsymbol->tag);
else if (startsymbol->class == token_sym) else if (startsymbol->class == token_sym)
fatal (_("the start symbol %s is a token"), startsymbol->tag); fatal_at (startsymbol_location,
_("the start symbol %s is a token"), startsymbol->tag);
} }

View File

@@ -59,6 +59,9 @@ struct symbol_s
/* Its type. */ /* Its type. */
char *type_name; char *type_name;
/* The location of its first occurence. */
location_t location;
symbol_number_t number; symbol_number_t number;
short prec; short prec;
associativity assoc; associativity assoc;
@@ -85,7 +88,7 @@ struct symbol_s
/* Fetch (or create) the symbol associated to KEY. */ /* Fetch (or create) the symbol associated to KEY. */
symbol_t *getsym PARAMS ((const char *key)); symbol_t *getsym PARAMS ((const char *key, location_t location));
/* Declare the new SYMBOL. Make it an alias of SYMVAL. */ /* Declare the new SYMBOL. Make it an alias of SYMVAL. */
void symbol_make_alias PARAMS ((symbol_t *symbol, symbol_t *symval)); void symbol_make_alias PARAMS ((symbol_t *symbol, symbol_t *symval));

View File

@@ -303,7 +303,7 @@ input.y:6.1: invalid character: `%'
input.y:6.2: invalid character: `-' input.y:6.2: invalid character: `-'
input.y:7.1-8.0: unexpected end of file in a prologue input.y:7.1-8.0: unexpected end of file in a prologue
input.y:7.1-8.0: parse error, unexpected PROLOGUE, expecting ";" or "|" input.y:7.1-8.0: parse error, unexpected PROLOGUE, expecting ";" or "|"
input.y:8: symbol a is used, but is not defined as a token and has no rules input.y:5.2: symbol a is used, but is not defined as a token and has no rules
]]) ]])
AT_CLEANUP AT_CLEANUP