X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/4395a9ff4fd518580b9abe9482783e8eba192f34..bf3e44fe46440ebe473798f9d887908b120bb646:/src/scan-code.l diff --git a/src/scan-code.l b/src/scan-code.l index 700488e8..9a08af7a 100644 --- a/src/scan-code.l +++ b/src/scan-code.l @@ -1,6 +1,6 @@ /* Bison Action Scanner -*- C -*- - Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2006-2011 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -47,12 +47,9 @@ YY_DECL; #define YY_USER_ACTION location_compute (loc, &loc->end, yytext, yyleng); -static void handle_action_dollar (symbol_list *rule, char *cp, - location dollar_loc); -static void handle_action_at (symbol_list *rule, char *cp, location at_loc); - -/* A string to be pushed to obstack after dollar/at has been handled. */ -static char *ref_tail_fields; +static void handle_action_dollar (symbol_list *, char *, unsigned, location); +static void handle_action_at (symbol_list const *, char const *, unsigned, + location); static location the_location; static location *loc = &the_location; @@ -82,12 +79,16 @@ tag [^\0\n>]+ white space between the backslash and the newline. */ splice (\\[ \f\t\v]*\n)* -/* C style identifier. Must start with letter. Will be used for - named symbol references. Shall be kept synchronized with - scan-gram.l "letter" and "id". */ +/* A Bison identifier. Keep this synchronized with scan-gram.l "id". */ letter [-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] id {letter}({letter}|[0-9])* -ref -?[0-9]+|{id}|"["{id}"]"|"$" + +/* An identifier that can appear unbracketed in a reference. + This happens to be the same as a C-language identifier. */ +c_letter [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] +c_id {c_letter}({c_letter}|[0-9])* + +ref -?[0-9]+|{c_id}|"["{id}"]"|"$" %% @@ -182,19 +183,11 @@ ref -?[0-9]+|{id}|"["{id}"]"|"$" { "$"("<"{tag}">")?{ref} { - ref_tail_fields = 0; - handle_action_dollar (self->rule, yytext, *loc); - if (ref_tail_fields) { - obstack_sgrow (&obstack_for_string, ref_tail_fields); - } + handle_action_dollar (self->rule, yytext, yyleng, *loc); need_semicolon = true; } "@"{ref} { - ref_tail_fields = 0; - handle_action_at (self->rule, yytext, *loc); - if (ref_tail_fields) { - obstack_sgrow (&obstack_for_string, ref_tail_fields); - } + handle_action_at (self->rule, yytext, yyleng, *loc); need_semicolon = true; } "$" { @@ -338,13 +331,9 @@ typedef struct by an explicit symbol reference. */ #define VARIANT_HIDDEN (1 << 0) -/* Set when the variant refers to a symbol containing - dots or dashes. Will require explicit bracketing. */ -#define VARIANT_BAD_BRACKETING (1 << 1) - /* Set when the variant refers to a symbol which is not visible from current midrule. */ -#define VARIANT_NOT_VISIBLE_FROM_MIDRULE (1 << 2) +#define VARIANT_NOT_VISIBLE_FROM_MIDRULE (1 << 1) static variant *variant_table = 0; static unsigned variant_table_size = 0; @@ -372,31 +361,25 @@ variant_table_free (void) variant_table_size = variant_count = 0; } -static char * -find_prefix_end (const char *prefix, char *begin, char *end) +/* Return TRUE if ID matches the string from CP up to CP_END. + The string does not contain null bytes. */ +static bool +identifier_matches (char const *id, char const *cp, char const *cp_end) { - char *ptr = begin; - - for (; *prefix && ptr != end; ++prefix, ++ptr) - if (*prefix != *ptr) - return 0; - - if (*prefix) - return 0; - - return ptr; + while (cp != cp_end) + if (*id++ != *cp++) + return false; + return !*id; } +/* If scanning ID, return a new variant with that ID, at location + ID_LOC with index SYMBOL_INDEX. Otherwise, return NULL. The + currently scanned identifier starts at CP and ends at CP_END. */ static variant * variant_add (uniqstr id, location id_loc, unsigned symbol_index, - char *cp, char *cp_end, bool explicit_bracketing) + char const *cp, char const *cp_end) { - char *prefix_end; - - prefix_end = find_prefix_end (id, cp, cp_end); - if (prefix_end && - (prefix_end == cp_end || - (!explicit_bracketing && is_dot_or_dash (*prefix_end)))) + if (identifier_matches (id, cp, cp_end)) { variant *r = variant_table_grow (); r->symbol_index = symbol_index; @@ -421,11 +404,15 @@ get_at_spec(unsigned symbol_index) return at_buf; } +/* Show a subsidiary message for a problem with a grammar rule. TEXT + points to the problematic reference. MIDRULE_RHS_INDEX is the rhs + index (1-origin) in the rule. If IS_WARNING, it is a warning, + otherwise a complaint. Indent the message INDENT spaces. */ static void -show_sub_messages (const char* cp, bool explicit_bracketing, - int midrule_rhs_index, char dollar_or_at, +show_sub_messages (char const *text, int midrule_rhs_index, bool is_warning, unsigned indent) { + char dollar_or_at = *text; unsigned i; for (i = 0; i < variant_count; ++i) @@ -445,8 +432,6 @@ show_sub_messages (const char* cp, bool explicit_bracketing, else { static struct obstack msg_buf; - const char *tail = explicit_bracketing ? "" : - cp + strlen (var->id); const char *id = var->hidden_by ? var->hidden_by->id : var->id; location id_loc = var->hidden_by ? var->hidden_by->loc : @@ -460,7 +445,6 @@ show_sub_messages (const char* cp, bool explicit_bracketing, obstack_fgrow1 (&msg_buf, "[%s]", id); else obstack_sgrow (&msg_buf, id); - obstack_sgrow (&msg_buf, tail); if (var->err & VARIANT_HIDDEN) { @@ -469,7 +453,6 @@ show_sub_messages (const char* cp, bool explicit_bracketing, obstack_fgrow1 (&msg_buf, "[%s]", var->id); else obstack_sgrow (&msg_buf, var->id); - obstack_sgrow (&msg_buf, tail); } obstack_fgrow1 (&msg_buf, _(" at %s"), at_spec); @@ -504,16 +487,22 @@ show_sub_messages (const char* cp, bool explicit_bracketing, /* Sub-messages indent. */ #define SUB_INDENT (4) -/* Parse named or positional reference. In case of positional - references, can return negative values for $-n "deep" stack - accesses. */ +/* Return the index of a named or positional reference starting at CP + for a rule RULE of length RULE_LENGTH. If MIDRULE_RHS_INDEX is + nonzero, this is a generated midrule whose rhs index (1-origin) is + MIDRULE_RHS_INDEX in the parent rule. The entire semantic value + containing the reference is TEXT, of length TEXTLEN. Its location + is TEXT_LOC. + + In case of positional references, this can return negative values + for $-n "deep" stack accesses. */ static long int -parse_ref (char *cp, symbol_list *rule, int rule_length, - int midrule_rhs_index, char *text, location text_loc, - char dollar_or_at) +parse_ref (char const *cp, symbol_list const *rule, int rule_length, + int midrule_rhs_index, char const *text, unsigned textlen, + location text_loc) { - symbol_list *l; - char *cp_end; + symbol_list const *l; + char const *cp_end; bool explicit_bracketing; unsigned i; unsigned valid_variants = 0; @@ -522,9 +511,9 @@ parse_ref (char *cp, symbol_list *rule, int rule_length, if ('$' == *cp) return LHS_REF; - if (c_isdigit (*cp) || (*cp == '-' && c_isdigit (* (cp + 1)))) + if (c_isdigit (*cp) || *cp == '-') { - long int num = strtol (cp, &cp, 10); + long int num = strtol (cp, NULL, 10); if (1 - INT_MAX + rule_length <= num && num <= rule_length) return num; else @@ -535,32 +524,9 @@ parse_ref (char *cp, symbol_list *rule, int rule_length, } } - if ('[' == *cp) - { - /* Ignore the brackets. */ - char *p; - for (p = ++cp; *p != ']'; ++p) - continue; - cp_end = p; - - explicit_bracketing = true; - } - else - { - /* Take all characters of the name. */ - char* p; - for (p = cp; *p; ++p) - if (is_dot_or_dash (*p)) - { - ref_tail_fields = p; - break; - } - for (p = cp; *p; ++p) - continue; - cp_end = p; - - explicit_bracketing = false; - } + explicit_bracketing = (*cp == '['); + cp += explicit_bracketing; + cp_end = text + textlen - explicit_bracketing; /* Add all relevant variants. */ { @@ -574,13 +540,13 @@ parse_ref (char *cp, symbol_list *rule, int rule_length, continue; var = variant_add (l->content.sym->tag, l->sym_loc, - symbol_index, cp, cp_end, explicit_bracketing); + symbol_index, cp, cp_end); if (var && l->named_ref) var->hidden_by = l->named_ref; if (l->named_ref) variant_add (l->named_ref->id, l->named_ref->loc, - symbol_index, cp, cp_end, explicit_bracketing); + symbol_index, cp, cp_end); } } @@ -595,10 +561,6 @@ parse_ref (char *cp, symbol_list *rule, int rule_length, && (symbol_index == 0 || midrule_rhs_index < symbol_index)) var->err |= VARIANT_NOT_VISIBLE_FROM_MIDRULE; - /* Check correct bracketing. */ - if (!explicit_bracketing && contains_dot_or_dash (var->id)) - var->err |= VARIANT_BAD_BRACKETING; - /* Check using of hidden symbols. */ if (var->hidden_by) var->err |= VARIANT_HIDDEN; @@ -614,14 +576,23 @@ parse_ref (char *cp, symbol_list *rule, int rule_length, { case 0: { - unsigned len = (explicit_bracketing || !ref_tail_fields) ? - cp_end - cp : ref_tail_fields - cp; + unsigned len = cp_end - cp; unsigned indent = 0; complain_at_indent (text_loc, &indent, _("invalid reference: %s"), quote (text)); indent += SUB_INDENT; - if (midrule_rhs_index) + if (len == 0) + { + location sym_loc = text_loc; + sym_loc.start.column += 1; + sym_loc.end = sym_loc.start; + const char *format = + _("syntax error after `%c', expecting integer, letter," + " `_', `[', or `$'"); + complain_at_indent (sym_loc, &indent, format, *text); + } + else if (midrule_rhs_index) { const char *format = _("symbol not found in production before $%d: %.*s"); @@ -637,8 +608,7 @@ parse_ref (char *cp, symbol_list *rule, int rule_length, } if (variant_count > 0) - show_sub_messages (cp, explicit_bracketing, midrule_rhs_index, - dollar_or_at, false, indent); + show_sub_messages (text, midrule_rhs_index, false, indent); return INVALID_REF; } case 1: @@ -648,8 +618,8 @@ parse_ref (char *cp, symbol_list *rule, int rule_length, { warn_at_indent (text_loc, &indent, _("misleading reference: %s"), quote (text)); - show_sub_messages (cp, explicit_bracketing, midrule_rhs_index, - dollar_or_at, true, indent + SUB_INDENT); + show_sub_messages (text, midrule_rhs_index, true, + indent + SUB_INDENT); } { unsigned symbol_index = @@ -663,8 +633,8 @@ parse_ref (char *cp, symbol_list *rule, int rule_length, unsigned indent = 0; complain_at_indent (text_loc, &indent, _("ambiguous reference: %s"), quote (text)); - show_sub_messages (cp, explicit_bracketing, midrule_rhs_index, - dollar_or_at, false, indent + SUB_INDENT); + show_sub_messages (text, midrule_rhs_index, false, + indent + SUB_INDENT); return INVALID_REF; } } @@ -682,13 +652,14 @@ int max_left_semantic_context = 0; /*------------------------------------------------------------------. | TEXT is pointing to a wannabee semantic value (i.e., a `$'). | | | -| Possible inputs: $[]($|integer) | +| Possible inputs: $(|)($|integer|c_id|[id]) | | | | Output to OBSTACK_FOR_STRING a reference to this semantic value. | `------------------------------------------------------------------*/ static void -handle_action_dollar (symbol_list *rule, char *text, location dollar_loc) +handle_action_dollar (symbol_list *rule, char *text, unsigned textlen, + location dollar_loc) { char const *type_name = NULL; char *cp = text + 1; @@ -725,7 +696,7 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc) } n = parse_ref (cp, effective_rule, effective_rule_length, - rule->midrule_parent_rhs_index, text, dollar_loc, '$'); + rule->midrule_parent_rhs_index, text, textlen, dollar_loc); if (gt_ptr) *gt_ptr = '\0'; @@ -796,10 +767,11 @@ handle_action_dollar (symbol_list *rule, char *text, location dollar_loc) `------------------------------------------------------*/ static void -handle_action_at (symbol_list *rule, char *text, location at_loc) +handle_action_at (symbol_list const *rule, char const *text, unsigned textlen, + location at_loc) { - char *cp = text + 1; - symbol_list *effective_rule; + char const *cp = text + 1; + symbol_list const *effective_rule; int effective_rule_length; int n; @@ -817,7 +789,7 @@ handle_action_at (symbol_list *rule, char *text, location at_loc) muscle_percent_define_ensure("locations", at_loc, true); n = parse_ref (cp, effective_rule, effective_rule_length, - rule->midrule_parent_rhs_index, text, at_loc, '@'); + rule->midrule_parent_rhs_index, text, textlen, at_loc); switch (n) { case INVALID_REF: @@ -901,7 +873,7 @@ code_props_symbol_action_init (code_props *self, char const *code, void code_props_rule_action_init (code_props *self, char const *code, location code_loc, symbol_list *rule, - named_ref *name) + named_ref *name, bool is_predicate) { self->kind = CODE_PROPS_RULE_ACTION; self->code = code; @@ -909,6 +881,7 @@ code_props_rule_action_init (code_props *self, char const *code, self->is_value_used = false; self->rule = rule; self->named_ref = name; + self->is_predicate = is_predicate; } void