From ee000ba4fcd5b051bef4476341a7fdffbddf8ad3 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Sat, 15 Jun 2002 18:21:46 +0000 Subject: [PATCH] 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. --- ChangeLog | 13 +++++++++++++ src/complain.c | 40 ++++++++++++++++------------------------ src/complain.h | 26 ++++++++++++++------------ src/parse-gram.c | 4 ++-- src/parse-gram.y | 4 ++-- src/reader.c | 14 +++++++------- src/scan-gram.c | 4 ++-- src/scan-gram.l | 4 ++-- src/symtab.c | 18 +++++++++++------- src/symtab.h | 5 ++++- tests/regression.at | 2 +- 11 files changed, 74 insertions(+), 60 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1285899f..27a927b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2002-06-15 Akim Demaille + + 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 * src/parse-gram.y (YYLLOC_DEFAULT, current_lhs_location): New. diff --git a/src/complain.c b/src/complain.c index 49c61897..579cdf86 100644 --- a/src/complain.c +++ b/src/complain.c @@ -116,10 +116,10 @@ unsigned int complain_message_count; void #if defined VA_START && defined __STDC__ -warn_at (int location, const char *message, ...) +warn_at (location_t location, const char *message, ...) #else warn_at (location, message, va_alist) - int location + location_t location char *message; va_dcl #endif @@ -133,21 +133,18 @@ warn_at (location, message, va_alist) static const char *old_infile; static int old_lineno; - if (old_lineno == location && + if (old_lineno == location.first_line && (infile == old_infile || !strcmp (old_infile, infile))) /* Simply return and print nothing. */ return; old_infile = infile; - old_lineno = location; + old_lineno = location.first_line; } fflush (stdout); - if (infile != NULL) - fprintf (stderr, "%s:%d: ", infile, location); - else - fprintf (stderr, "%s:", program_name); - + LOCATION_PRINT (stderr, location); + fputs (": ", stderr); fputs (_("warning: "), stderr); #ifdef VA_START @@ -218,10 +215,10 @@ warn (message, va_alist) void #if defined VA_START && defined __STDC__ -complain_at (int location, const char *message, ...) +complain_at (location_t location, const char *message, ...) #else complain_at (location, message, va_alist) - int location; + location_t location; char *message; va_dcl #endif @@ -235,20 +232,18 @@ complain_at (location, message, va_alist) static const char *old_infile; static int old_lineno; - if (old_lineno == location && + if (old_lineno == location.first_line && (infile == old_infile || !strcmp (old_infile, infile))) /* Simply return and print nothing. */ return; old_infile = infile; - old_lineno = location; + old_lineno = location.first_line; } fflush (stdout); - if (infile != NULL) - fprintf (stderr, "%s:%d: ", infile, location); - else - fprintf (stderr, "%s:", program_name); + LOCATION_PRINT (stderr, location); + fputs (": ", stderr); #ifdef VA_START VA_START (args, message); @@ -316,10 +311,10 @@ complain (message, va_alist) void #if defined VA_START && defined __STDC__ -fatal_at (int location, const char *message, ...) +fatal_at (location_t location, const char *message, ...) #else fatal (location, message, va_alist) - int location; + location_t location; char *message; va_dcl #endif @@ -329,11 +324,8 @@ fatal (location, message, va_alist) #endif fflush (stdout); - if (infile != NULL) - fprintf (stderr, "%s:%d: ", infile, location); - else - fprintf (stderr, "%s:", program_name); - + LOCATION_PRINT (stderr, location); + fputs (": ", stderr); fputs (_("fatal error: "), stderr); #ifdef VA_START diff --git a/src/complain.h b/src/complain.h index 79a3e122..34aa70b2 100644 --- a/src/complain.h +++ b/src/complain.h @@ -1,5 +1,5 @@ /* 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 under the terms of the GNU General Public License as published by the @@ -17,20 +17,22 @@ USA. */ #ifndef COMPLAIN_H_ -#define COMPLAIN_H_ 1 +# define COMPLAIN_H_ 1 -#ifdef __cplusplus +# include "location.h" + +# ifdef __cplusplus extern "C" { -#endif +# endif -#ifdef __STDC__ +# ifdef __STDC__ /* Informative messages, but we proceed. */ void warn (const char *format, ...) __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))); /* 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, ...) __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))); /* Something bad happen and we die now. */ @@ -46,17 +48,17 @@ void complain_at (int location, const char *format, ...) void fatal (const char *format, ...) __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))); -#else +# else void warn (); void warn_at (); void complain (); void complain_at (); void fatal (); void fatal_at (); -#endif +# endif /* Position in the current input file. */ extern char *infile; @@ -68,8 +70,8 @@ extern unsigned int warn_message_count; /* This variable is incremented each time `complain' is called. */ extern unsigned int complain_message_count; -#ifdef __cplusplus +# ifdef __cplusplus } -#endif +# endif #endif /* !COMPLAIN_H_ */ diff --git a/src/parse-gram.c b/src/parse-gram.c index a4bb0bcf..842793ed 100644 --- a/src/parse-gram.c +++ b/src/parse-gram.c @@ -1489,7 +1489,7 @@ yyreduce: case 64: #line 339 "parse-gram.y" - { yyval.symbol = getsym (yyvsp[0].string); } + { yyval.symbol = getsym (yyvsp[0].string, yylsp[0]); } break; case 65: @@ -1500,7 +1500,7 @@ yyreduce: case 66: #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); } break; diff --git a/src/parse-gram.y b/src/parse-gram.y index 272d9667..ca344d1c 100644 --- a/src/parse-gram.y +++ b/src/parse-gram.y @@ -336,7 +336,7 @@ rhs: symbol: ID { $$ = $1; } | string_as_id { $$ = $1; } -| CHARACTER { $$ = getsym ($1); } +| CHARACTER { $$ = getsym ($1, @1); } ; action: @@ -348,7 +348,7 @@ action: string_as_id: STRING { - $$ = getsym ($1); + $$ = getsym ($1, @1); symbol_class_set ($$, token_sym); } ; diff --git a/src/reader.c b/src/reader.c index f66a7607..c4883825 100644 --- a/src/reader.c +++ b/src/reader.c @@ -159,7 +159,7 @@ epilogue_set (const char *epilogue, location_t location) `-------------------------------------------------------------------*/ static symbol_t * -gensym (void) +gensym (location_t location) { /* Incremented for each generated symbol */ static int gensym_count = 0; @@ -168,7 +168,7 @@ gensym (void) symbol_t *sym; sprintf (buf, "@%d", ++gensym_count); - sym = getsym (buf); + sym = getsym (buf, location); sym->class = nterm_sym; sym->number = nvars++; return sym; @@ -313,8 +313,8 @@ grammar_midrule_action (void) /* Make a DUMMY nonterminal, whose location is that of the midrule action. Create the MIDRULE. */ - symbol_t *dummy = gensym (); location_t dummy_location = current_rule->action_location; + symbol_t *dummy = gensym (dummy_location); symbol_list *midrule = symbol_list_new (dummy, dummy_location); /* Make a new rule, whose body is empty, before the current one, so @@ -461,18 +461,18 @@ reader (void) symbols_new (); /* Construct the axiom symbol. */ - axiom = getsym ("$axiom"); + axiom = getsym ("$axiom", empty_location); axiom->class = nterm_sym; axiom->number = nvars++; /* Construct the error token */ - errtoken = getsym ("error"); + errtoken = getsym ("error", empty_location); errtoken->class = token_sym; errtoken->number = ntokens++; /* Construct a token that represents all undefined literal tokens. It is always token number 2. */ - undeftoken = getsym ("$undefined."); + undeftoken = getsym ("$undefined.", empty_location); undeftoken->class = token_sym; undeftoken->number = ntokens++; @@ -498,7 +498,7 @@ reader (void) /* If the user did not define her EOFTOKEN, do it now. */ if (!eoftoken) { - eoftoken = getsym ("$"); + eoftoken = getsym ("$", empty_location); eoftoken->class = token_sym; eoftoken->number = 0; /* Value specified by POSIX. */ diff --git a/src/scan-gram.c b/src/scan-gram.c index 85bac479..7d96db7f 100644 --- a/src/scan-gram.c +++ b/src/scan-gram.c @@ -1259,7 +1259,7 @@ case 34: YY_RULE_SETUP #line 156 "scan-gram.l" { - yylval->symbol = getsym (yytext); + yylval->symbol = getsym (yytext, *yylloc); return ID; } YY_BREAK @@ -1450,7 +1450,7 @@ YY_RULE_SETUP assert (yy_top_state () == INITIAL); { YY_OBS_FINISH; - yylval->symbol = getsym (last_string); + yylval->symbol = getsym (last_string, *yylloc); symbol_class_set (yylval->symbol, token_sym); symbol_user_token_number_set (yylval->symbol, last_string[1]); YY_OBS_FREE; diff --git a/src/scan-gram.l b/src/scan-gram.l index 7e9c3673..cd8ca516 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -154,7 +154,7 @@ blanks [ \t\f]+ {eols} YY_LINES; YY_STEP; {blanks} YY_STEP; {id} { - yylval->symbol = getsym (yytext); + yylval->symbol = getsym (yytext, *yylloc); return ID; } @@ -286,7 +286,7 @@ blanks [ \t\f]+ assert (yy_top_state () == INITIAL); { YY_OBS_FINISH; - yylval->symbol = getsym (last_string); + yylval->symbol = getsym (last_string, *yylloc); symbol_class_set (yylval->symbol, token_sym); symbol_user_token_number_set (yylval->symbol, last_string[1]); YY_OBS_FREE; diff --git a/src/symtab.c b/src/symtab.c index 0011006d..fddf15e7 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -41,12 +41,13 @@ location_t startsymbol_location; `---------------------------------*/ static symbol_t * -symbol_new (const char *tag) +symbol_new (const char *tag, location_t location) { symbol_t *res = XMALLOC (symbol_t, 1); res->tag = xstrdup (tag); res->type_name = NULL; + res->location = location; res->number = NUMBER_UNDEFINED; res->prec = 0; res->assoc = right_assoc; @@ -170,8 +171,9 @@ symbol_check_defined (symbol_t *this) { if (this->class == unknown_sym) { - complain - (_("symbol %s is used, but is not defined as a token and has no rules"), + complain_at + (this->location, + _("symbol %s is used, but is not defined as a token and has no rules"), this->tag); this->class = nterm_sym; this->number = nvars++; @@ -363,7 +365,7 @@ symbols_new (void) `----------------------------------------------------------------*/ symbol_t * -getsym (const char *key) +getsym (const char *key, location_t location) { symbol_t probe; symbol_t *entry; @@ -374,7 +376,7 @@ getsym (const char *key) if (!entry) { /* First insertion in the hash. */ - entry = symbol_new (key); + entry = symbol_new (key, location); hash_insert (symbol_table, entry); } return entry; @@ -488,7 +490,9 @@ symbols_pack (void) symbols_token_translations_init (); 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) - fatal (_("the start symbol %s is a token"), startsymbol->tag); + fatal_at (startsymbol_location, + _("the start symbol %s is a token"), startsymbol->tag); } diff --git a/src/symtab.h b/src/symtab.h index 2746643d..2f53c8b8 100644 --- a/src/symtab.h +++ b/src/symtab.h @@ -59,6 +59,9 @@ struct symbol_s /* Its type. */ char *type_name; + /* The location of its first occurence. */ + location_t location; + symbol_number_t number; short prec; associativity assoc; @@ -85,7 +88,7 @@ struct symbol_s /* 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. */ void symbol_make_alias PARAMS ((symbol_t *symbol, symbol_t *symval)); diff --git a/tests/regression.at b/tests/regression.at index 5c051cd8..6d559468 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -303,7 +303,7 @@ input.y:6.1: 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: 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 -- 2.45.2