* 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>
+
+ 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>
* src/parse-gram.y (YYLLOC_DEFAULT, current_lhs_location): New.
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
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
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
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);
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
#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
/* 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
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. */
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. */
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;
/* This variable is incremented each time `complain' is called. */
extern unsigned int complain_message_count;
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
#endif /* !COMPLAIN_H_ */
case 64:
#line 339 "parse-gram.y"
- { yyval.symbol = getsym (yyvsp[0].string); }
+ { yyval.symbol = getsym (yyvsp[0].string, yylsp[0]); }
break;
case 65:
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;
symbol:
ID { $$ = $1; }
| string_as_id { $$ = $1; }
-| CHARACTER { $$ = getsym ($1); }
+| CHARACTER { $$ = getsym ($1, @1); }
;
action:
string_as_id:
STRING
{
- $$ = getsym ($1);
+ $$ = getsym ($1, @1);
symbol_class_set ($$, token_sym);
}
;
`-------------------------------------------------------------------*/
static symbol_t *
-gensym (void)
+gensym (location_t location)
{
/* Incremented for each generated symbol */
static int gensym_count = 0;
symbol_t *sym;
sprintf (buf, "@%d", ++gensym_count);
- sym = getsym (buf);
+ sym = getsym (buf, location);
sym->class = nterm_sym;
sym->number = nvars++;
return sym;
/* 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
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++;
/* 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. */
YY_RULE_SETUP
#line 156 "scan-gram.l"
{
- yylval->symbol = getsym (yytext);
+ yylval->symbol = getsym (yytext, *yylloc);
return ID;
}
YY_BREAK
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;
{eols} YY_LINES; YY_STEP;
{blanks} YY_STEP;
{id} {
- yylval->symbol = getsym (yytext);
+ yylval->symbol = getsym (yytext, *yylloc);
return ID;
}
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;
`---------------------------------*/
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;
{
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++;
`----------------------------------------------------------------*/
symbol_t *
-getsym (const char *key)
+getsym (const char *key, location_t location)
{
symbol_t probe;
symbol_t *entry;
if (!entry)
{
/* First insertion in the hash. */
- entry = symbol_new (key);
+ entry = symbol_new (key, location);
hash_insert (symbol_table, entry);
}
return entry;
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);
}
/* Its type. */
char *type_name;
+ /* The location of its first occurence. */
+ location_t location;
+
symbol_number_t number;
short prec;
associativity assoc;
/* 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));
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