/* This symbol and its alias are a single token defn.
Allocate a tokno, and assign to both check agreement of
prec and assoc fields and make both the same */
- if (this->number == -1)
+ if (this->number == NUMBER_UNDEFINED)
{
if (this == eoftoken || this->alias == eoftoken)
this->number = this->alias->number = 0;
else
{
- assert (this->alias->number != -1);
+ assert (this->alias->number != NUMBER_UNDEFINED);
this->number = this->alias->number;
}
}
}
else /* this->class == token_sym */
{
- assert (this->number != -1);
+ assert (this->number != NUMBER_UNDEFINED);
}
symbols[this->number] = this;
&& this->user_token_number != SALIAS)
{
/* A token which translation has already been set? */
- if (token_translations[this->user_token_number] != 2)
+ if (token_translations[this->user_token_number] != undeftoken->number)
complain (_("tokens %s and %s both assigned number %d"),
symbols[token_translations[this->user_token_number]]->tag,
this->tag, this->user_token_number);
return rp->sym->type_name;
}
\f
+/*------------------------------------------------------------------.
+| Copy the character C to OOUT, and insert quadigraphs when needed. |
+`------------------------------------------------------------------*/
+
+static inline void
+copy_character (struct obstack *oout, int c)
+{
+ switch (c)
+ {
+ case '[':
+ obstack_sgrow (oout, "@<:@");
+ break;
+
+ case ']':
+ obstack_sgrow (oout, "@:>@");
+ break;
+
+ default:
+ obstack_1grow (oout, c);
+ }
+}
+
/*------------------------------------------------------------.
| Dump the string from FIN to OOUT if non null. MATCH is the |
| delimiter of the string (either ' or "). |
continue;
}
- obstack_1grow (oout, c);
+ copy_character (oout, c);
if (c == '\\')
{
c = getc (fin);
if (c == EOF)
fatal (_("unterminated string at end of file"));
- obstack_1grow (oout, c);
+ copy_character (oout, c);
if (c == '\n')
++lineno;
fatal (_("unterminated comment"));
else
{
- obstack_1grow (oout, c);
+ copy_character (oout, c);
c = getc (fin);
}
}
`-------------------------------------------------------------------*/
static void
-copy_definition (void)
+copy_definition (struct obstack *oout)
{
int c;
/* -1 while reading a character if prev char was %. */
if (!no_lines_flag)
{
- obstack_fgrow2 (&attrs_obstack, muscle_find ("linef"),
+ obstack_fgrow2 (oout, muscle_find ("linef"),
lineno, quotearg_style (c_quoting_style,
muscle_find ("filename")));
}
switch (c)
{
case '\n':
- obstack_1grow (&attrs_obstack, c);
+ obstack_1grow (oout, c);
++lineno;
break;
case '\'':
case '"':
- copy_string (finput, &attrs_obstack, c);
+ copy_string (finput, oout, c);
break;
case '/':
- copy_comment (finput, &attrs_obstack);
+ copy_comment (finput, oout);
break;
case EOF:
fatal ("%s", _("unterminated `%{' definition"));
default:
- obstack_1grow (&attrs_obstack, c);
+ copy_character (oout, c);
}
c = getc (finput);
{
if (c == '}')
return;
- obstack_1grow (&attrs_obstack, '%');
+ obstack_1grow (oout, '%');
}
after_percent = 0;
}
symbol->class = what_is;
if (what_is == nterm_sym && oldclass != nterm_sym)
symbol->number = nvars++;
- if (what_is == token_sym && symbol->number == -1)
+ if (what_is == token_sym && symbol->number == NUMBER_UNDEFINED)
symbol->number = ntokens++;
if (typename)
symval->assoc = assoc;
if (symval->class == nterm_sym)
complain (_("symbol %s redefined"), symval->tag);
- if (symval->number == -1)
+ if (symval->number == NUMBER_UNDEFINED)
{
symval->number = ntokens++;
symval->class = token_sym;
/*----------------------------------------------------------------.
| Read from finput until `%%' is seen. Discard the `%%'. Handle |
| any `%' declarations, and copy the contents of any `%{ ... %}' |
-| groups to ATTRS_OBSTACK. |
+| groups to PRE_PROLOGUE_OBSTACK or POST_PROLOGUE_OBSTACK. |
`----------------------------------------------------------------*/
static void
return;
case tok_percent_left_curly:
- copy_definition ();
+ if (!typed)
+ copy_definition (&pre_prologue_obstack);
+ else
+ copy_definition (&post_prologue_obstack);
break;
case tok_token:
}
while ((c = getc (finput)) != EOF)
- obstack_1grow (&el_obstack, c);
+ copy_character (&el_obstack, c);
obstack_1grow (&el_obstack, 0);
muscle_insert ("epilogue", obstack_finish (&el_obstack));
static void
token_translations_init (void)
{
- int last_user_token_number = 256;
+ int num_256_available_p = TRUE;
int i;
- /* Set the user numbers. */
+ /* Find the highest user token number, and whether 256, the POSIX
+ preferred user token number for the error token, is used. */
+ max_user_token_number = 0;
+ for (i = 0; i < ntokens; ++i)
+ {
+ symbol_t *this = symbols[i];
+ if (this->user_token_number != SUNDEF)
+ {
+ if (this->user_token_number > max_user_token_number)
+ max_user_token_number = this->user_token_number;
+ if (this->user_token_number == 256)
+ num_256_available_p = FALSE;
+ }
+ }
+
+ /* If 256 is not used, assign it to error, to follow POSIX. */
+ if (num_256_available_p && errtoken->user_token_number == SUNDEF)
+ errtoken->user_token_number = 256;
+
+ /* Set the missing user numbers. */
+ if (max_user_token_number < 256)
+ max_user_token_number = 256;
+
for (i = 0; i < ntokens; ++i)
{
symbol_t *this = symbols[i];
if (this->user_token_number == SUNDEF)
- this->user_token_number = ++last_user_token_number;
+ this->user_token_number = ++max_user_token_number;
if (this->user_token_number > max_user_token_number)
max_user_token_number = this->user_token_number;
}
token number for $undefined., which represents all invalid
inputs. */
for (i = 0; i < max_user_token_number + 1; i++)
- token_translations[i] = 2;
-
+ token_translations[i] = undeftoken->number;
symbols_do (symbol_translation, NULL);
}
token_translations_init ();
- error_token_number = errtoken->number;
-
if (startval->class == unknown_sym)
fatal (_("the start symbol %s is undefined"), startval->tag);
else if (startval->class == token_sym)
p = p->next;
while (p && p->sym)
{
- ritem[itemno++] = p->sym->number;
+ /* item_number_t = token_number_t.
+ But the former needs to contain more: negative rule numbers. */
+ ritem[itemno++] = token_number_as_item_number (p->sym->number);
/* A rule gets by default the precedence and associativity
of the last token in it. */
if (p->sym->class == token_sym)
errtoken = getsym ("error");
errtoken->class = token_sym;
errtoken->number = ntokens++;
- errtoken->user_token_number = 256; /* Value specified by POSIX. */
/* Construct a token that represents all undefined literal tokens.
It is always token number 2. */
undeftoken = getsym ("$undefined.");
undeftoken->class = token_sym;
undeftoken->number = ntokens++;
- undeftoken->user_token_number = 2;
/* Initialize the obstacks. */
obstack_init (&action_obstack);
- obstack_init (&attrs_obstack);
obstack_init (&output_obstack);
+ obstack_init (&pre_prologue_obstack);
+ obstack_init (&post_prologue_obstack);
finput = xfopen (infile, "r");