From 95421df67b21f7a508404b11f51d27e384335ea1 Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Fri, 10 Apr 2020 09:26:31 +0200 Subject: [PATCH] tokens: define the "$undefined" token kind * data/skeletons/bison.m4 (b4_symbol_token_kind): Give a definition to $undefined. (b4_token_visible_if): $undefined has an id. * src/output.c (prepare_symbol_definitions): Stop lying: $undefined _is_ a token. * tests/input.at: Adjust. --- data/skeletons/bison.m4 | 12 +++++------- data/skeletons/c.m4 | 6 ++++++ src/output.c | 3 +-- src/parse-gram.h | 1 + src/symtab.c | 35 +++++++++++++++++++++++++++++------ tests/input.at | 3 ++- 6 files changed, 44 insertions(+), 16 deletions(-) diff --git a/data/skeletons/bison.m4 b/data/skeletons/bison.m4 index 09dc4456..4739f0fb 100644 --- a/data/skeletons/bison.m4 +++ b/data/skeletons/bison.m4 @@ -456,10 +456,6 @@ m4_define([b4_symbol_if], [m4_fatal([$0: field $2 of $1 is not a Boolean:] b4_symbol([$1], [$2]))])]) -# Give the error token a better name. -m4_define([b4_symbol(1, id)], [b4_api_PREFIX[][ERRCODE]]) - - # b4_symbol_tag_comment(SYMBOL-NUM) # --------------------------------- # Issue a comment giving the tag of symbol NUM. @@ -541,9 +537,11 @@ m4_define([b4_symbol_map], # Whether NUM denotes a token that has an exported definition (i.e., # shows in enum yytokentype). m4_define([b4_token_visible_if], -[b4_symbol_if([$1], [is_token], - [b4_symbol_if([$1], [has_id], [$2], [$3])], - [$3])]) +[m4_case(b4_symbol([$1], [tag]), + [$undefined], [$2], + [b4_symbol_if([$1], [is_token], + [b4_symbol_if([$1], [has_id], [$2], [$3])], + [$3])])]) # b4_token_has_definition(NUM) diff --git a/data/skeletons/c.m4 b/data/skeletons/c.m4 index dba9928b..8013141d 100644 --- a/data/skeletons/c.m4 +++ b/data/skeletons/c.m4 @@ -430,6 +430,12 @@ static const b4_int_type_for([$2]) yy$1[[]] = ## Token kinds. ## ## ------------- ## +# Because C enums are not scoped, because tokens are exposed in the +# header, and because these tokens are common to all the parser, we +# need to make sure their names don't collide: use the api.prefix. +m4_define([b4_symbol(1, id)], [b4_api_PREFIX[][ERRCODE]]) +m4_define([b4_symbol(2, id)], [b4_api_PREFIX[][UNDEF]]) + # b4_token_define(TOKEN-NUM) # -------------------------- # Output the definition of this token as #define. diff --git a/src/output.c b/src/output.c index f759fc8f..0f6ee5b5 100644 --- a/src/output.c +++ b/src/output.c @@ -549,8 +549,7 @@ prepare_symbol_definitions (void) MUSCLE_INSERT_INT (key, sym->content->user_token_number); SET_KEY ("is_token"); - MUSCLE_INSERT_INT (key, - i < ntokens && sym != undeftoken); + MUSCLE_INSERT_INT (key, i < ntokens); SET_KEY ("number"); MUSCLE_INSERT_INT (key, sym->content->number); diff --git a/src/parse-gram.h b/src/parse-gram.h index ae498897..ab0f6d80 100644 --- a/src/parse-gram.h +++ b/src/parse-gram.h @@ -79,6 +79,7 @@ extern int gram_debug; { GRAM_EOF = 0, /* "end of file" */ GRAM_ERRCODE = 1, /* error */ + GRAM_UNDEF = 2, /* $undefined */ STRING = 3, /* "string" */ TSTRING = 4, /* "translatable string" */ PERCENT_TOKEN = 5, /* "%token" */ diff --git a/src/symtab.c b/src/symtab.c index a446476c..fd96b827 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -65,6 +65,17 @@ static bool *used_assoc = NULL; bool tag_seen = false; +/* Whether SYM was defined by the user. */ + +static bool +symbol_is_user_defined (symbol *sym) +{ + return sym->tag[0] != '$' + && sym != errtoken && sym->alias != errtoken + && sym != undeftoken && sym->alias != undeftoken; +} + + /*--------------------------. | Create a new sym_content. | `--------------------------*/ @@ -279,6 +290,7 @@ is_identifier (uniqstr s) /*-----------------------------------------------. | Get the identifier associated to this symbol. | `-----------------------------------------------*/ + uniqstr symbol_id_get (symbol const *sym) { @@ -419,6 +431,7 @@ symbol_code_props_set (symbol *sym, code_props_type kind, sym->content->props[kind] = *code; } + /*-----------------------------------------------------. | Set the DESTRUCTOR or PRINTER associated with TYPE. | `-----------------------------------------------------*/ @@ -457,7 +470,7 @@ symbol_code_props_get (symbol *sym, code_props_type kind) } /* Apply default code props's only to user-defined symbols. */ - if (sym->tag[0] != '$' && sym != errtoken) + if (symbol_is_user_defined (sym)) { code_props *code = &semantic_type_get (sym->content->type_name ? "*" : "", NULL)->props[kind]; @@ -831,16 +844,26 @@ symbols_new (void) accept->content->class = nterm_sym; accept->content->number = nvars++; - /* Construct the error token */ - errtoken = symbol_get ("error", empty_loc); + /* Construct the YYERRCODE/"error" token */ + errtoken = symbol_get ("YYERRCODE", empty_loc); errtoken->content->class = token_sym; errtoken->content->number = ntokens++; + { + symbol *alias = symbol_get ("error", empty_loc); + symbol_class_set (alias, token_sym, empty_loc, false); + symbol_make_alias (errtoken, alias, empty_loc); + } - /* Construct a token that represents all undefined literal tokens. - It is always token number 2. */ - undeftoken = symbol_get ("$undefined", empty_loc); + /* Construct the YYUNDEF/"$undefined" token that represents all + undefined literal tokens. It is always symbol number 2. */ + undeftoken = symbol_get ("YYUNDEF", empty_loc); undeftoken->content->class = token_sym; undeftoken->content->number = ntokens++; + { + symbol *alias = symbol_get ("$undefined", empty_loc); + symbol_class_set (alias, token_sym, empty_loc, false); + symbol_make_alias (undeftoken, alias, empty_loc); + } semantic_type_table = hash_xinitialize (HT_INITIAL_CAPACITY, NULL, diff --git a/tests/input.at b/tests/input.at index d9cfc3f7..6d434350 100644 --- a/tests/input.at +++ b/tests/input.at @@ -345,6 +345,7 @@ int main (void) { assert (YYERRCODE == 123); assert (YYTRANSLATE (YYERRCODE) == YYSYMBOL_YYERROR); + assert (YYTRANSLATE (YYUNDEF) == YYSYMBOL_YYUNDEF); return 0; } ]]) @@ -431,7 +432,7 @@ AT_CHECK([cat symbols.csv], [], [[number, class, tag, id, user_number, type, 0, Token, $end, , 0, , 1, Token, error, YYERRCODE, 256, , -2, Nonterminal, $undefined, , 257, , +2, Token, $undefined, YYUNDEF, 257, , 3, Token, 'a', , 97, , 4, Token, "A1", A1, 1, , 5, Token, A2, A2, 258, ,