]> git.saurik.com Git - bison.git/commitdiff
Define the "identifier" of a symbol.
authorAkim Demaille <demaille@gostai.com>
Tue, 26 Aug 2008 18:10:03 +0000 (20:10 +0200)
committerAkim Demaille <demaille@gostai.com>
Thu, 13 Nov 2008 05:17:09 +0000 (06:17 +0100)
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
data/lalr1.cc
src/output.c
src/symtab.c
src/symtab.h

index d5d38001d5cfef3d0044a06bbfbcaf348cf39b57..3ea95f18124d9c8f215f269145f0b062a6f5e4c3 100644 (file)
--- a/ChangeLog
+++ b/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.
 2008-11-11  Akim Demaille  <demaille@gostai.com>
 
        Locations are no longer required by lalr1.cc.
index fd5e5ec8cc25e598faae584df6b945396344ab54..01b8166acb404b43517a179f993742f730079060 100644 (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_],
 # 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
 [  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])));
 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_],
 # ------------------------------------------------
 # 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
 [  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])))
   {
 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])));
   }
                                 b4_symbol_if([$1], [has_type_name], [v]),
                                 b4_locations_if([l])));
   }
index afcec94956b05cce53ea896b3533438c82c5d076..475916495c2102b7752945002b80bff36e793cd1 100644 (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.  |
 `---------------------------------------*/
 /*---------------------------------------.
 | Output the symbol definitions to OUT.  |
 `---------------------------------------*/
@@ -428,17 +408,23 @@ symbol_definitions_output (FILE *out)
     {
       symbol *sym = symbols[i];
       const char *key;
     {
       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);
 
 
 #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);
 
       SET_KEY("tag");
       MUSCLE_INSERT_STRING (key, sym->tag);
 
index 13b755491ce74aba30938379b3e73bff6783265f..b65bdd48ae02a76d9d20335829c3882020ab8d8b 100644 (file)
@@ -128,6 +128,41 @@ symbol_print (symbol *s, FILE *f)
 #undef SYMBOL_ATTR_PRINT
 #undef SYMBOL_CODE_PRINT
 
 #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.                                                         |
 /*------------------------------------------------------------------.
 | Complain that S's WHAT is redeclared at SECOND, and was first set |
 | at FIRST.                                                         |
index fe37716a109f8b59e7c7f07df098622ca8e63dc1..0e521626c7e41b96e6c0e20945c9c0f2c3ceb79a 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions for symtab.c and callers, part of Bison.
 
 /* 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.
    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)
 
 /* 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);
 
 /** 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);
 
    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);
 
 /** 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);
 
 /** 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);
 
 
 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.  */
 /** The error token. */
 extern symbol *errtoken;
 /** The token for unknown tokens.  */