typedef struct symbol_list
{
struct symbol_list *next;
- bucket *sym;
+ symbol_t *sym;
int line;
/* The action is attached to the LHS of a rule. */
/* The guard is attached to the LHS of a rule. */
const char *guard;
int guard_line;
- bucket *ruleprec;
+ symbol_t *ruleprec;
} symbol_list;
int lineno;
static symbol_list *grammar = NULL;
static int start_flag = 0;
-static bucket *startval = NULL;
+static symbol_t *startval = NULL;
/* Nonzero if components of semantic values are used, implying
they must be unions. */
/* Incremented for each %left, %right or %nonassoc seen */
static int lastprec = 0;
-bucket *errtoken = NULL;
-bucket *undeftoken = NULL;
-bucket *eoftoken = NULL;
-bucket *axiom = NULL;
+symbol_t *errtoken = NULL;
+symbol_t *undeftoken = NULL;
+symbol_t *eoftoken = NULL;
+symbol_t *axiom = NULL;
static symbol_list *
-symbol_list_new (bucket *sym)
+symbol_list_new (symbol_t *sym)
{
symbol_list *res = XMALLOC (symbol_list, 1);
res->next = NULL;
}
/*------------------------.
-| Operations on buckets. |
+| Operations on symbols. |
`------------------------*/
`-----------------------------------------------------------*/
static bool
-bucket_check_defined (bucket *this)
+symbol_check_defined (symbol_t *this)
{
if (this->class == unknown_sym)
{
`-------------------------------------------------------------------*/
static bool
-bucket_make_alias (bucket *symbol, char *typename)
+symbol_make_alias (symbol_t *symbol, char *typename)
{
if (symval->alias)
warn (_("symbol `%s' used more than once as a literal string"),
`---------------------------------------------------------*/
static bool
-bucket_check_alias_consistence (bucket *this)
+symbol_check_alias_consistence (symbol_t *this)
{
/* Check only those who _are_ the aliases. */
if (this->alias && this->user_token_number == SALIAS)
`-------------------------------------------------------------------*/
static bool
-bucket_pack (bucket *this)
+symbol_pack (symbol_t *this)
{
- if (getenv ("DEBUG"))
- fprintf (stderr, "Packing %s, %s, number = %d\n",
- this->tag,
- this->class == nterm_sym ? "nterm" : "TERM",
- this->number);
if (this->class == nterm_sym)
{
this->number += ntokens;
/* 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);
}
- if (getenv ("DEBUG"))
- fprintf (stderr, "Setting %d = %s\n", this->number, this->tag);
symbols[this->number] = this;
return TRUE;
}
`--------------------------------------------------*/
static bool
-bucket_translation (bucket *this)
+symbol_translation (symbol_t *this)
{
- if (getenv ("DEBUG"))
- fprintf (stderr, "Considering Setting UserVal %s = %d (val = %d)\n",
- this->tag, this->user_token_number, this->number);
-
/* Non-terminal? */
if (this->class == token_sym
&& 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);
- if (getenv ("DEBUG"))
- fprintf (stderr, "Setting UserVal %s = %d (val = %d)\n",
- this->tag, this->user_token_number, this->number);
token_translations[this->user_token_number] = this->number;
}
complain (_("invalid $ value"));
return NULL;
}
- i++;
+ ++i;
}
return rp->sym->type_name;
obstack_1grow (oout, c);
if (c == '\n')
- lineno++;
+ ++lineno;
}
c = getc (fin);
}
else if (c == '\n')
{
- lineno++;
+ ++lineno;
obstack_1grow (oout, c);
if (cplus_comment)
ended = 1;
{
case '\n':
obstack_1grow (&attrs_obstack, c);
- lineno++;
+ ++lineno;
break;
case '%':
char *typename = NULL;
/* The symbol being defined. */
- struct bucket *symbol = NULL;
+ symbol_t *symbol = NULL;
/* After `%token' and `%nterm', any number of symbols maybe be
defined. */
}
else if (token == tok_identifier && *symval->tag == '\"' && symbol)
{
- bucket_make_alias (symbol, typename);
+ symbol_make_alias (symbol, typename);
symbol = NULL;
}
else if (token == tok_identifier)
symbol->class = what_is;
if (what_is == nterm_sym && oldclass != nterm_sym)
symbol->number = nvars++;
- if (what_is == token_sym && symbol->number == -1)
- {
- symbol->number = ntokens++;
- if (getenv ("DEBUG"))
- fprintf (stderr, "Set %s to %d\n",
- symbol->tag, symbol->number);
- }
+ if (what_is == token_sym && symbol->number == NUMBER_UNDEFINED)
+ symbol->number = ntokens++;
if (typename)
{
char *name = NULL;
int prev = 0;
- lastprec++; /* Assign a new precedence level, never 0. */
+ /* Assign a new precedence level, never 0. */
+ ++lastprec;
for (;;)
{
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;
switch (c)
{
case '\n':
- lineno++;
+ ++lineno;
break;
case '/':
break;
case '{':
- count++;
+ ++count;
break;
case '}':
parse_thong_decl (void)
{
token_t token;
- struct bucket *symbol;
+ symbol_t *symbol;
char *typename = 0;
int usrtoknum = SUNDEF;
{
case '\n':
obstack_1grow (&action_obstack, c);
- lineno++;
+ ++lineno;
break;
case '{':
obstack_1grow (&action_obstack, c);
- count++;
+ ++count;
break;
case '\'':
| with the user's names. |
`-------------------------------------------------------------------*/
-static bucket *
+static symbol_t *
gensym (void)
{
/* Incremented for each generated symbol */
static int gensym_count = 0;
static char buf[256];
- bucket *sym;
+ symbol_t *sym;
sprintf (buf, "@%d", ++gensym_count);
token_buffer = buf;
readgram (void)
{
token_t t;
- bucket *lhs = NULL;
+ symbol_t *lhs = NULL;
symbol_list *p = NULL;
symbol_list *p1 = NULL;
/* Number of symbols in rhs of this rule so far */
int rulelength = 0;
int xactions = 0; /* JF for error checking */
- bucket *first_rhs = 0;
+ symbol_t *first_rhs = 0;
if (t == tok_identifier)
{
}
/* start a new rule and record its lhs. */
- nrules++;
- nitems++;
+ ++nrules;
+ ++nritems;
p = symbol_list_new (lhs);
{
lhs->class = nterm_sym;
lhs->number = nvars;
- nvars++;
+ ++nvars;
}
else if (lhs->class == token_sym)
complain (_("rule given for %s, which is a token"), lhs->tag);
If one does, exit this rule now. */
if (t == tok_identifier)
{
- bucket *ssave;
+ symbol_t *ssave;
token_t t1;
ssave = symval;
inserting the new rule before it. */
/* Make a dummy nonterminal, a gensym. */
- bucket *sdummy = gensym ();
+ symbol_t *sdummy = gensym ();
/* Make a new rule, whose body is empty, before the
current one, so that the action just read can
belong to it. */
- nrules++;
- nitems++;
+ ++nrules;
+ ++nritems;
p = symbol_list_new (sdummy);
/* Attach its lineno to that of the host rule. */
p->line = crule->line;
/* Insert the dummy generated by that rule into this
rule. */
- nitems++;
+ ++nritems;
p = symbol_list_new (sdummy);
p1->next = p;
p1 = p;
if (t == tok_identifier)
{
- nitems++;
+ ++nritems;
p = symbol_list_new (symval);
p1->next = p;
p1 = p;
{
parse_action (crule, rulelength);
action_flag = 1;
- xactions++; /* JF */
+ ++xactions; /* JF */
}
- rulelength++;
+ ++rulelength;
} /* end of read rhs of rule */
/* Put an empty link in the list to mark the end of this rule */
complain (_("two actions at end of one rule"));
parse_action (crule, rulelength);
action_flag = 1;
- xactions++; /* -wjh */
+ ++xactions; /* -wjh */
t = lex ();
}
/* If $$ is being set in default way, report if any type
fatal (_("no rules in the input grammar"));
/* Report any undefined symbols and consider them nonterminals. */
- buckets_do (bucket_check_defined, NULL);
+ symbols_do (symbol_check_defined, NULL);
/* Insert the initial rule, which line is that of the first rule
(not that of the start symbol):
p->next->next->next = symbol_list_new (NULL);
p->next->next->next->next = grammar;
nrules += 1;
- nitems += 3;
+ nritems += 3;
grammar = p;
startval = axiom;
- if (nsyms > MAXSHORT)
+ if (nsyms > SHRT_MAX)
fatal (_("too many symbols (tokens plus nonterminals); maximum %d"),
- MAXSHORT);
+ SHRT_MAX);
- if (getenv ("DEBUG"))
- fprintf (stderr, "nsyms == ntokens + nvars: %d == %d + %d\n",
- nsyms, ntokens, nvars);
assert (nsyms == ntokens + nvars);
}
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)
{
- bucket *this = symbols[i];
- if (getenv ("DEBUG"))
- fprintf (stderr, "UserVal %s = %d (val = %d)\n",
- this->tag, this->user_token_number, this->number);
+ 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;
- if (getenv ("DEBUG"))
- fprintf (stderr, "Now: UserVal %s = %d (val = %d)\n",
- this->tag, this->user_token_number, this->number);
}
- token_translations = XCALLOC (short, max_user_token_number + 1);
+ token_translations = XCALLOC (token_number_t, max_user_token_number + 1);
/* Initialize all entries for literal tokens to 2, the internal
token number for $undefined., which represents all invalid
inputs. */
for (i = 0; i < max_user_token_number + 1; i++)
- token_translations[i] = 2;
-
- buckets_do (bucket_translation, NULL);
+ token_translations[i] = undeftoken->number;
+ symbols_do (symbol_translation, NULL);
}
static void
packsymbols (void)
{
- symbols = XCALLOC (bucket *, nsyms);
+ symbols = XCALLOC (symbol_t *, nsyms);
- buckets_do (bucket_check_alias_consistence, NULL);
- buckets_do (bucket_pack, NULL);
+ symbols_do (symbol_check_alias_consistence, NULL);
+ symbols_do (symbol_pack, 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)
int ruleno;
symbol_list *p;
- /* We use short to index items. */
- if (nitems >= MAXSHORT)
- fatal (_("too many items (max %d)"), MAXSHORT);
-
- ritem = XCALLOC (short, nitems + 1);
+ ritem = XCALLOC (item_number_t, nritems + 1);
rules = XCALLOC (rule_t, nrules) - 1;
itemno = 0;
p = grammar;
while (p)
{
- bucket *ruleprec = p->ruleprec;
+ symbol_t *ruleprec = p->ruleprec;
rules[ruleno].user_number = ruleno;
rules[ruleno].number = ruleno;
rules[ruleno].lhs = p->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)
rules[ruleno].prec = ruleprec;
}
ritem[itemno++] = -ruleno;
- ruleno++;
+ ++ruleno;
if (p)
p = p->next;
}
ritem[itemno] = 0;
- nritems = itemno;
- assert (nritems == nitems);
+ assert (itemno == nritems);
if (trace_flag)
ritem_print (stderr);
obstack_init (&muscle_obstack);
/* Initialize the symbol table. */
- buckets_new ();
+ symbols_new ();
/* Construct the axiom symbol. */
axiom = getsym ("$axiom");
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);
XFREE (ritem);
free (rules + 1);
/* Free the symbol table data structure. */
- buckets_free ();
+ symbols_free ();
}