Define the "identifier" of a symbol.

Symbols may have several string representations, for instance if they
have an alias.  What I call its "id" is a string that can be used as
an identifier.  May not exist.

Currently the symbols which have the "tag_is_id" flag set are those that
don't have an alias.  Look harder for the id.

	* src/output.c (is_identifier): Move to...
	* src/symtab.c (is_identifier): here.
	* src/symtab.h, src/symtab.c (symbol_id_get): New.
	* src/output.c (symbol_definitions_output): Use it to define "id"
	and "has_id".
	Remove the definition of "tag_is_id".
	* data/lalr1.cc: Use the "id" and "has_id" whereever "tag" and
	"tag_is_id" were used to produce code.
	We still use "tag" for documentation.
This commit is contained in:
Akim Demaille
2008-08-26 20:10:03 +02:00
parent 086fd1137d
commit aea10ef46f
5 changed files with 90 additions and 33 deletions

View File

@@ -1,3 +1,23 @@
2008-11-13 Akim Demaille <demaille@gostai.com>
Define the "identifier" of a symbol.
Symbols may have several string representations, for instance if they
have an alias. What I call its "id" is a string that can be used as
an identifier. May not exist.
Currently the symbols which have the "tag_is_id" flag set are those that
don't have an alias. Look harder for the id.
* src/output.c (is_identifier): Move to...
* src/symtab.c (is_identifier): here.
* src/symtab.h, src/symtab.c (symbol_id_get): New.
* src/output.c (symbol_definitions_output): Use it to define "id"
and "has_id".
Remove the definition of "tag_is_id".
* data/lalr1.cc: Use the "id" and "has_id" whereever "tag" and
"tag_is_id" were used to produce code.
We still use "tag" for documentation.
2008-11-11 Akim Demaille <demaille@gostai.com>
Locations are no longer required by lalr1.cc.

View File

@@ -225,11 +225,11 @@ m4_map([b4_symbol_constructor_declaration_], m4_defn([b4_type_names]))])])
# Specializations cannot be declared at class-level, this must be done
# at namespace-level.
m4_define([b4_symbol_constructor_specialization_],
[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [tag_is_id],
[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
[ template <>
inline
b4_parser_class_name::symbol_type
b4_parser_class_name::make_symbol <b4_parser_class_name::token::b4_symbol([$1], [tag])> (dnl
b4_parser_class_name::make_symbol <b4_parser_class_name::token::b4_symbol([$1], [id])> (dnl
b4_args(b4_symbol_if([$1], [has_type_name],
[const b4_symbol([$1], [type_name])& v]),
b4_locations_if([const b4_parser_class_name::location_type& l])));
@@ -251,15 +251,15 @@ m4_map([b4_symbol_constructor_specialization_],
# ------------------------------------------------
# Define make_symbol for this SYMBOL-NUMBER.
m4_define([b4_symbol_constructor_definition_],
[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [tag_is_id],
[b4_symbol_if([$1], [is_token], [b4_symbol_if([$1], [has_id],
[ template <>
b4_parser_class_name::symbol_type
b4_parser_class_name::make_symbol <b4_parser_class_name::token::b4_symbol([$1], [tag])> (dnl
b4_parser_class_name::make_symbol <b4_parser_class_name::token::b4_symbol([$1], [id])> (dnl
b4_args(b4_symbol_if([$1], [has_type_name],
[const b4_symbol([$1], [type_name])& v]),
b4_locations_if([const location_type& l])))
{
return symbol_type (b4_args([yytranslate_ (token::b4_symbol([$1], [tag]))],
return symbol_type (b4_args([yytranslate_ (token::b4_symbol([$1], [id]))],
b4_symbol_if([$1], [has_type_name], [v]),
b4_locations_if([l])));
}

View File

@@ -396,26 +396,6 @@ merger_output (FILE *out)
}
/*----------------------------------.
| Whether S is a valid identifier. |
`----------------------------------*/
static bool
is_identifier (uniqstr s)
{
static char const alphanum[26 + 26 + 1 + 10] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"_"
"0123456789";
if (!s || ! memchr (alphanum, *s, sizeof alphanum - 10))
return false;
for (++s; *s; ++s)
if (! memchr (alphanum, *s, sizeof alphanum))
return false;
return true;
}
/*---------------------------------------.
| Output the symbol definitions to OUT. |
`---------------------------------------*/
@@ -428,17 +408,23 @@ symbol_definitions_output (FILE *out)
{
symbol *sym = symbols[i];
const char *key;
const char *value;
#define SET_KEY(Entry) \
obstack_fgrow2 (&format_obstack, "symbol(%d, %s)", i, Entry); \
obstack_1grow (&format_obstack, 0); \
key = obstack_finish (&format_obstack);
// Whether the tag is a valid identifier.
SET_KEY("tag_is_id");
MUSCLE_INSERT_INT (key, is_identifier(sym->tag));
// Whether the symbol has an identifier.
value = symbol_id_get (sym);
SET_KEY("has_id");
MUSCLE_INSERT_INT (key, !!value);
// The inner tag.
// Its identifier.
SET_KEY("id");
MUSCLE_INSERT_STRING (key, value ? value : "");
// Its tag. Typically for documentation purpose.
SET_KEY("tag");
MUSCLE_INSERT_STRING (key, sym->tag);

View File

@@ -128,6 +128,41 @@ symbol_print (symbol *s, FILE *f)
#undef SYMBOL_ATTR_PRINT
#undef SYMBOL_CODE_PRINT
/*----------------------------------.
| Whether S is a valid identifier. |
`----------------------------------*/
static bool
is_identifier (uniqstr s)
{
static char const alphanum[26 + 26 + 1 + 10] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"_"
"0123456789";
if (!s || ! memchr (alphanum, *s, sizeof alphanum - 10))
return false;
for (++s; *s; ++s)
if (! memchr (alphanum, *s, sizeof alphanum))
return false;
return true;
}
/*-----------------------------------------------.
| Get the identifier associated to this symbol. |
`-----------------------------------------------*/
uniqstr
symbol_id_get (symbol const *sym)
{
aver (sym->user_token_number != USER_NUMBER_ALIAS);
if (sym->alias)
sym = sym->alias;
return is_identifier (sym->tag) ? sym->tag : 0;
}
/*------------------------------------------------------------------.
| Complain that S's WHAT is redeclared at SECOND, and was first set |
| at FIRST. |

View File

@@ -1,6 +1,6 @@
/* Definitions for symtab.c and callers, part of Bison.
Copyright (C) 1984, 1989, 1992, 2000, 2001, 2002, 2004, 2005, 2006, 2007
Copyright (C) 1984, 1989, 1992, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler.
@@ -105,9 +105,6 @@ struct symbol
/* Undefined internal token number. */
#define NUMBER_UNDEFINED (-1)
/** Print a symbol (for debugging). */
void symbol_print (symbol *s, FILE *f);
/** Fetch (or create) the symbol associated to KEY. */
symbol *symbol_from_uniqstr (const uniqstr key, location loc);
@@ -119,9 +116,23 @@ symbol *symbol_get (const char *key, location loc);
Its name cannot conflict with the user's names. */
symbol *dummy_symbol_get (location loc);
/*--------------------.
| Methods on symbol. |
`--------------------*/
/** Print a symbol (for debugging). */
void symbol_print (symbol *s, FILE *f);
/** Is this a dummy nonterminal? */
bool symbol_is_dummy (const symbol *sym);
/** Return the name of the symbol that can be used as an identifier.
** Consider the alias if needed.
** Return 0 if there is none (e.g., the symbol is only defined as
** a string). */
uniqstr symbol_id_get (symbol const *sym);
/** Declare the new symbol \c sym. Make it an alias of \c symval. */
void symbol_make_alias (symbol *sym, symbol *symval, location loc);
@@ -161,6 +172,11 @@ void symbol_class_set (symbol *sym, symbol_class class, location loc,
void symbol_user_token_number_set (symbol *sym, int user_number, location loc);
/*------------------.
| Special symbols. |
`------------------*/
/** The error token. */
extern symbol *errtoken;
/** The token for unknown tokens. */