From aea10ef46f726371c21e99d2bfb78c1ab891f73d Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Tue, 26 Aug 2008 20:10:03 +0200 Subject: [PATCH] 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. --- ChangeLog | 20 ++++++++++++++++++++ data/lalr1.cc | 10 +++++----- src/output.c | 34 ++++++++++------------------------ src/symtab.c | 35 +++++++++++++++++++++++++++++++++++ src/symtab.h | 24 ++++++++++++++++++++---- 5 files changed, 90 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index d5d38001..3ea95f18 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2008-11-13 Akim Demaille + + 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 Locations are no longer required by lalr1.cc. diff --git a/data/lalr1.cc b/data/lalr1.cc index fd5e5ec8..01b8166a 100644 --- a/data/lalr1.cc +++ b/data/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 (dnl + b4_parser_class_name::make_symbol (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 (dnl + b4_parser_class_name::make_symbol (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]))); } diff --git a/src/output.c b/src/output.c index afcec949..47591649 100644 --- a/src/output.c +++ b/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); + + // Its identifier. + SET_KEY("id"); + MUSCLE_INSERT_STRING (key, value ? value : ""); - // The inner tag. + // Its tag. Typically for documentation purpose. SET_KEY("tag"); MUSCLE_INSERT_STRING (key, sym->tag); diff --git a/src/symtab.c b/src/symtab.c index 13b75549..b65bdd48 100644 --- a/src/symtab.c +++ b/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. | diff --git a/src/symtab.h b/src/symtab.h index fe37716a..0e521626 100644 --- a/src/symtab.h +++ b/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. */ -- 2.47.2