mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 04:13:03 +00:00
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:
20
ChangeLog
20
ChangeLog
@@ -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.
|
||||
|
||||
@@ -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])));
|
||||
}
|
||||
|
||||
34
src/output.c
34
src/output.c
@@ -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);
|
||||
|
||||
|
||||
35
src/symtab.c
35
src/symtab.c
@@ -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. |
|
||||
|
||||
24
src/symtab.h
24
src/symtab.h
@@ -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. */
|
||||
|
||||
Reference in New Issue
Block a user