X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/11e2becaaccf936991dde4c18d0b176255652574..e7b8bef1b1fa6eae346c4a3ee00e897a4d6f9058:/src/reader.c diff --git a/src/reader.c b/src/reader.c index b09b3447..bebbc153 100644 --- a/src/reader.c +++ b/src/reader.c @@ -68,9 +68,10 @@ static int typed; /* Incremented for each %left, %right or %nonassoc seen */ static int lastprec; -static bucket *errtoken; -static bucket *undeftoken; - +static bucket *errtoken = NULL; +static bucket *undeftoken = NULL; +static bucket *eoftoken = NULL; +static bucket *axiom = NULL; static symbol_list * symbol_list_new (bucket *sym) @@ -441,7 +442,7 @@ copy_definition (void) { obstack_fgrow2 (&attrs_obstack, muscle_find ("linef"), lineno, quotearg_style (c_quoting_style, - muscle_find("filename"))); + muscle_find ("filename"))); } after_percent = 0; @@ -573,6 +574,9 @@ parse_token_decl (symbol_class what_is, symbol_class what_is_not) else if (symbol && token == tok_number) { symbol->user_token_number = numval; + /* User defined EOF token? */ + if (numval == 0) + eoftoken = symbol; } else { @@ -902,8 +906,8 @@ static void parse_muscle_decl (void) { int ch = ungetc (skip_white_space (), finput); - char* muscle_key; - char* muscle_value; + char *muscle_key; + char *muscle_value; /* Read key. */ if (!isalpha (ch) && ch != '_') @@ -1447,12 +1451,8 @@ readgram (void) t = lex (); } - /* grammar has been read. Do some checking */ - if (nsyms > MAXSHORT) - fatal (_("too many symbols (tokens plus nonterminals); maximum %d"), - MAXSHORT); if (nrules == 0) fatal (_("no rules in the input grammar")); @@ -1468,6 +1468,25 @@ readgram (void) bp->value = nvars++; } + /* Insert the initial rule, which line is that of the first rule + (not that of the start symbol): + + axiom: %start EOF. */ + p = symbol_list_new (axiom); + p->line = grammar->line; + p->next = symbol_list_new (startval); + p->next->next = symbol_list_new (eoftoken); + p->next->next->next = symbol_list_new (NULL); + p->next->next->next->next = grammar; + nrules += 1; + nitems += 3; + grammar = p; + startval = axiom; + + if (nsyms > MAXSHORT) + fatal (_("too many symbols (tokens plus nonterminals); maximum %d"), + MAXSHORT); + ntokens = nsyms - nvars; } @@ -1486,7 +1505,7 @@ read_additionnal_code (void) { obstack_fgrow2 (&el_obstack, muscle_find ("linef"), lineno, quotearg_style (c_quoting_style, - muscle_find("filename"))); + muscle_find ("filename"))); } while ((c = getc (finput)) != EOF) @@ -1549,7 +1568,6 @@ packsymbols (void) bucket *bp = NULL; int tokno = 1; int last_user_token_number; - static char DOLLAR[] = "$"; tags = XCALLOC (char *, nsyms + 1); user_toknums = XCALLOC (short, nsyms + 1); @@ -1557,10 +1575,6 @@ packsymbols (void) sprec = XCALLOC (short, nsyms); sassoc = XCALLOC (short, nsyms); - /* The EOF token. */ - tags[0] = DOLLAR; - user_toknums[0] = 0; - max_user_token_number = 256; last_user_token_number = 256; @@ -1572,11 +1586,18 @@ packsymbols (void) } else if (bp->alias) { - /* 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 (bp->value == 0) - bp->value = bp->alias->value = tokno++; + /* 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 (bp->value == -1) + { + if (bp == eoftoken || bp->alias == eoftoken) + bp->value = bp->alias->value = 0; + else + { + bp->value = bp->alias->value = tokno++; + } + } if (bp->prec != bp->alias->prec) { @@ -1602,13 +1623,17 @@ packsymbols (void) bp->assoc = bp->alias->assoc; } + /* Do not do processing below for SALIASs. */ if (bp->user_token_number == SALIAS) - continue; /* do not do processing below for SALIASs */ + continue; } - else /* bp->class == token_sym */ + else /* bp->class == token_sym */ { - bp->value = tokno++; + if (bp == eoftoken) + bp->value = 0; + else + bp->value = tokno++; } if (bp->class == token_sym) @@ -1647,13 +1672,11 @@ symbols_save (void) { struct obstack tokendefs; bucket *bp; - char *cp, *symbol; - char c; obstack_init (&tokendefs); for (bp = firstsymbol; bp; bp = bp->next) { - symbol = bp->tag; /* get symbol */ + char *symbol = bp->tag; /* get symbol */ if (bp->value >= ntokens) continue; @@ -1673,9 +1696,7 @@ symbols_save (void) } /* Don't #define nonliteral tokens whose names contain periods. */ - cp = symbol; - while ((c = *cp++) && c != '.'); - if (c != '\0') + if (strchr (symbol, '.')) continue; obstack_fgrow2 (&tokendefs, "# define %s\t%d\n", @@ -1759,6 +1780,8 @@ packgram (void) } ritem[itemno] = 0; + nritems = itemno; + assert (nritems == nitems); if (trace_flag) ritem_print (stderr); @@ -1778,7 +1801,7 @@ reader (void) start_flag = 0; startval = NULL; /* start symbol not specified yet. */ - nsyms = 1; + nsyms = 0; nvars = 0; nrules = 0; nitems = 0; @@ -1800,6 +1823,11 @@ reader (void) /* Initialize the symbol table. */ tabinit (); + /* Construct the axiom symbol. */ + axiom = getsym ("$axiom"); + axiom->class = nterm_sym; + axiom->value = nvars++; + /* Construct the error token */ errtoken = getsym ("error"); errtoken->class = token_sym; @@ -1822,6 +1850,16 @@ reader (void) TABLE_OBSTACK and FDEFINES file. Also notice any %token, %left, etc. found there. */ read_declarations (); + + /* If the user did not define her EOFTOKEN, do it now. */ + if (!eoftoken) + { + eoftoken = getsym ("$"); + eoftoken->class = token_sym; + /* Value specified by POSIX. */ + eoftoken->user_token_number = 0; + } + /* Read in the grammar, build grammar in list form. Write out guards and actions. */ readgram ();