X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/79282c5ad0ccfa2fa3ed22681a982974aabbdad2..d8880f69ff2e5c0a88007c48a5142db388426868:/src/reader.c diff --git a/src/reader.c b/src/reader.c index e35e4f38..3ef59350 100644 --- a/src/reader.c +++ b/src/reader.c @@ -1,5 +1,5 @@ /* Input parser for bison - Copyright (C) 1984, 1986, 1989, 1992, 1998, 2000 + Copyright 1984, 1986, 1989, 1992, 1998, 2000 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -21,6 +21,7 @@ #include "system.h" +#include "obstack.h" #include "getargs.h" #include "files.h" #include "xalloc.h" @@ -151,17 +152,21 @@ get_type_name (int n, symbol_list * rule) return rp->sym->type_name; } -/*-------------------------------------------------------------------. -| Dump the string from FINPUT to FOUTPUT. MATCH is the delimiter of | -| the string (either ' or "). | -`-------------------------------------------------------------------*/ +/*-----------------------------------------------------------------. +| Dump the string from FIN to FOUT and OOUT if non null. MATCH is | +| the delimiter of the string (either ' or "). | +`-----------------------------------------------------------------*/ static inline void -copy_string (FILE *fin, FILE *fout, int match) +copy_string (FILE *fin, FILE *fout, struct obstack *oout, int match) { int c; - putc (match, fout); + if (fout) + putc (match, fout); + if (oout) + obstack_1grow (oout, match); + c = getc (fin); while (c != match) @@ -176,14 +181,21 @@ copy_string (FILE *fin, FILE *fout, int match) continue; } - putc (c, fout); + if (fout) + putc (c, fout); + if (oout) + obstack_1grow (oout, c); if (c == '\\') { c = getc (fin); if (c == EOF) fatal (_("unterminated string at end of file")); - putc (c, fout); + if (fout) + putc (c, fout); + if (oout) + obstack_1grow (oout, c); + if (c == '\n') lineno++; } @@ -191,27 +203,57 @@ copy_string (FILE *fin, FILE *fout, int match) c = getc (fin); } - putc (c, fout); + if (fout) + putc (c, fout); + if (oout) + obstack_1grow (oout, c); } -/*---------------------------------------------------------------. -| Dump the comment from IN to OUT1 and OUT2. C is either `*' or | -| `/', depending upon the type of comments used. OUT2 might be | -| NULL. | -`---------------------------------------------------------------*/ +/*----------------------------------------------------------------. +| Dump the wannabee comment from IN to OUT1 and OUT2. In fact we | +| just saw a `/', which might or might not be a comment. In any | +| case, copy what we saw. | +| | +| OUT2 might be NULL. | +`----------------------------------------------------------------*/ static inline void -copy_comment2 (FILE *in, FILE *out1, FILE *out2, int c) +copy_comment2 (FILE *fin, FILE *out1, + struct obstack *oout2, struct obstack *oout) { int cplus_comment; int ended; + int c; + + /* We read a `/', output it. */ + if (out1) + putc ('/', out1); + if (oout) + obstack_1grow (oout, '/'); + if (oout2) + obstack_1grow (oout2, '/'); + + switch ((c = getc (fin))) + { + case '/': + cplus_comment = 1; + break; + case '*': + cplus_comment = 0; + break; + default: + ungetc (c, fin); + return; + } - cplus_comment = (c == '/'); - putc (c, out1); - if (out2) - putc (c, out2); - c = getc (in); + if (out1) + putc (c, out1); + if (oout) + obstack_1grow (oout, c); + if (oout2) + obstack_1grow (oout2, c); + c = getc (fin); ended = 0; while (!ended) @@ -220,53 +262,65 @@ copy_comment2 (FILE *in, FILE *out1, FILE *out2, int c) { while (c == '*') { - putc (c, out1); - if (out2) - putc (c, out2); - c = getc (in); + if (out1) + putc (c, out1); + if (oout) + obstack_1grow (oout, c); + if (oout2) + obstack_1grow (oout2, c); + c = getc (fin); } if (c == '/') { - putc (c, out1); - if (out2) - putc (c, out2); + if (out1) + putc (c, out1); + if (oout) + obstack_1grow (oout, c); + if (oout2) + obstack_1grow (oout2, c); ended = 1; } } else if (c == '\n') { lineno++; - putc (c, out1); - if (out2) - putc (c, out2); + if (out1) + putc (c, out1); + if (oout) + obstack_1grow (oout, c); + if (oout2) + obstack_1grow (oout2, c); if (cplus_comment) ended = 1; else - c = getc (in); + c = getc (fin); } else if (c == EOF) fatal (_("unterminated comment")); else { - putc (c, out1); - if (out2) - putc (c, out2); - c = getc (in); + if (out1) + putc (c, out1); + if (oout) + obstack_1grow (oout, c); + if (oout2) + obstack_1grow (oout2, c); + c = getc (fin); } } } -/*------------------------------------------------------------. -| Dump the comment from FIN to FOUT. C is either `*' or `/', | -| depending upon the type of comments used. | -`------------------------------------------------------------*/ +/*-------------------------------------------------------------------. +| Dump the comment (actually the current string starting with a `/') | +| from FIN to FOUT. | +`-------------------------------------------------------------------*/ static inline void -copy_comment (FILE *fin, FILE *fout, int c) +copy_comment (FILE *fin, FILE *fout, struct obstack *oout) { - copy_comment2 (fin, fout, NULL, c); + copy_comment2 (fin, fout, NULL, oout); } @@ -278,24 +332,32 @@ copy_comment (FILE *fin, FILE *fout, int c) `-----------------------------------------------------------------*/ static inline void -copy_at (FILE *fin, FILE *fout, int stack_offset) +copy_at (FILE *fin, FILE *fout, struct obstack *oout, int stack_offset) { int c; c = getc (fin); if (c == '$') { - fprintf (fout, "yyloc"); + if (fout) + fprintf (fout, "yyloc"); + if (oout) + obstack_grow_literal_string (oout, "yyloc"); locations_flag = 1; } else if (isdigit (c) || c == '-') { int n; + char buf[4096]; ungetc (c, fin); n = read_signed_integer (fin); - fprintf (fout, "yylsp[%d]", n - stack_offset); + sprintf (buf, "yylsp[%d]", n - stack_offset); + if (fout) + fputs (buf, fout); + if (oout) + obstack_grow (oout, buf, strlen (buf)); locations_flag = 1; } else @@ -318,38 +380,37 @@ copy_at (FILE *fin, FILE *fout, int stack_offset) `-------------------------------------------------------------------*/ static inline void -copy_dollar (FILE *fin, FILE *fout, +copy_dollar (FILE *fin, FILE *fout, struct obstack *oout, symbol_list *rule, int stack_offset) { int c = getc (fin); char *type_name = NULL; - /* Get the typename if explicit. */ + /* Get the type name if explicit. */ if (c == '<') { - char *cp = token_buffer; - - while ((c = getc (fin)) != '>' && c > 0) - { - if (cp == token_buffer + maxtoken) - cp = grow_token_buffer (cp); - - *cp++ = c; - } - *cp = 0; + read_type_name (fin); type_name = token_buffer; value_components_used = 1; - c = getc (fin); } if (c == '$') { - fprintf (fout, "yyval"); + if (fout) + fputs ("yyval", fout); + if (oout) + obstack_grow_literal_string (oout, "yyval"); + if (!type_name) type_name = get_type_name (0, rule); if (type_name) - fprintf (fout, ".%s", type_name); + { + if (fout) + fprintf (fout, ".%s", type_name); + if (oout) + obstack_fgrow1 (oout, ".%s", type_name); + } if (!type_name && typed) complain (_("$$ of `%s' has no declared type"), rule->sym->tag); @@ -363,9 +424,18 @@ copy_dollar (FILE *fin, FILE *fout, if (!type_name && n > 0) type_name = get_type_name (n, rule); - fprintf (fout, "yyvsp[%d]", n - stack_offset); + if (fout) + fprintf (fout, "yyvsp[%d]", n - stack_offset); + if (oout) + obstack_fgrow1 (oout, "yyvsp[%d]", n - stack_offset); + if (type_name) - fprintf (fout, ".%s", type_name); + { + if (fout) + fprintf (fout, ".%s", type_name); + if (oout) + obstack_fgrow1 (oout, ".%s", type_name); + } if (!type_name && typed) complain (_("$%d of `%s' has no declared type"), n, rule->sym->tag); @@ -391,7 +461,7 @@ copy_definition (void) int after_percent; if (!no_lines_flag) - fprintf (fattrs, "#line %d \"%s\"\n", lineno, infile); + obstack_fgrow2 (&attrs_obstack, "#line %d \"%s\"\n", lineno, infile); after_percent = 0; @@ -402,7 +472,7 @@ copy_definition (void) switch (c) { case '\n': - putc (c, fattrs); + obstack_1grow (&attrs_obstack, c); lineno++; break; @@ -412,22 +482,18 @@ copy_definition (void) case '\'': case '"': - copy_string (finput, fattrs, c); + copy_string (finput, 0, &attrs_obstack, c); break; case '/': - putc (c, fattrs); - c = getc (finput); - if (c != '*' && c != '/') - continue; - copy_comment (finput, fattrs, c); + copy_comment (finput, 0, &attrs_obstack); break; case EOF: fatal ("%s", _("unterminated `%{' definition")); default: - putc (c, fattrs); + obstack_1grow (&attrs_obstack, c); } c = getc (finput); @@ -436,12 +502,10 @@ copy_definition (void) { if (c == '}') return; - putc ('%', fattrs); + obstack_1grow (&attrs_obstack, '%'); } after_percent = 0; - } - } @@ -456,12 +520,18 @@ parse_token_decl (symbol_class what_is, symbol_class what_is_not) { int token = 0; char *typename = 0; - struct bucket *symbol = NULL; /* pts to symbol being defined */ + /* The symbol being defined. */ + struct bucket *symbol = NULL; + + /* After `%token' and `%nterm', any number of symbols maybe be + defined. */ for (;;) { int tmp_char = ungetc (skip_white_space (), finput); + /* `%' (for instance from `%token', or from `%%' etc.) is the + only valid means to end this declaration. */ if (tmp_char == '%') return; if (tmp_char == EOF) @@ -691,11 +761,11 @@ token_buffer); -/*-------------------------------------------------------------------. -| Copy the union declaration into fattrs (and fdefines), where it is | -| made into the definition of YYSTYPE, the type of elements of the | -| parser value stack. | -`-------------------------------------------------------------------*/ +/*--------------------------------------------------------------. +| Copy the union declaration into ATTRS_OBSTACK (and fdefines), | +| where it is made into the definition of YYSTYPE, the type of | +| elements of the parser value stack. | +`--------------------------------------------------------------*/ static void parse_union_decl (void) @@ -709,21 +779,21 @@ parse_union_decl (void) typed = 1; if (!no_lines_flag) - fprintf (fattrs, "\n#line %d \"%s\"\n", lineno, infile); + obstack_fgrow2 (&attrs_obstack, "\n#line %d \"%s\"\n", lineno, infile); else - fprintf (fattrs, "\n"); + obstack_1grow (&attrs_obstack, '\n'); - fprintf (fattrs, "typedef union"); - if (fdefines) - fprintf (fdefines, "typedef union"); + obstack_grow_literal_string (&attrs_obstack, "typedef union"); + if (defines_flag) + obstack_grow_literal_string (&defines_obstack, "typedef union"); c = getc (finput); while (c != EOF) { - putc (c, fattrs); - if (fdefines) - putc (c, fdefines); + obstack_1grow (&attrs_obstack, c); + if (defines_flag) + obstack_grow_literal_string (&defines_obstack, c); switch (c) { @@ -732,13 +802,9 @@ parse_union_decl (void) break; case '/': - c = getc (finput); - if (c != '*' && c != '/') - continue; - copy_comment2 (finput, fattrs, fdefines, c); + copy_comment2 (finput, 0, &defines_obstack, &attrs_obstack); break; - case '{': count++; break; @@ -749,9 +815,9 @@ parse_union_decl (void) count--; if (count <= 0) { - fprintf (fattrs, " YYSTYPE;\n"); - if (fdefines) - fprintf (fdefines, " YYSTYPE;\n"); + obstack_grow_literal_string (&attrs_obstack, " YYSTYPE;\n"); + if (defines_flag) + obstack_grow_literal_string (&defines_obstack, " YYSTYPE;\n"); /* JF don't choke on trailing semi */ c = skip_white_space (); if (c != ';') @@ -773,28 +839,13 @@ parse_union_decl (void) static void parse_expect_decl (void) { - int c; - size_t count; - char buffer[20]; - - c = getc (finput); - while (c == ' ' || c == '\t') - c = getc (finput); - - count = 0; - while (c >= '0' && c <= '9') - { - if (count < sizeof(buffer) - 1) - buffer[count++] = c; - c = getc (finput); - } - buffer[count] = 0; - + int c = skip_white_space (); ungetc (c, finput); - if (count <= 0 || count > 10) + if (!isdigit (c)) complain (_("argument of %%expect is not an integer")); - expected_conflicts = atoi (buffer); + else + expected_conflicts = read_signed_integer (finput); } @@ -882,7 +933,7 @@ parse_thong_decl (void) /*----------------------------------------------------------------. | Read from finput until `%%' is seen. Discard the `%%'. Handle | | any `%' declarations, and copy the contents of any `%{ ... %}' | -| groups to fattrs. | +| groups to ATTRS_OBSTACK. | `----------------------------------------------------------------*/ static void @@ -991,15 +1042,21 @@ copy_action (symbol_list *rule, int stack_offset) { int c; int count; + char buf[4096]; /* offset is always 0 if parser has already popped the stack pointer */ if (semantic_parser) stack_offset = 0; - fprintf (faction, "\ncase %d:\n", nrules); + sprintf (buf, "\ncase %d:\n", nrules); + obstack_grow (&action_obstack, buf, strlen (buf)); + if (!no_lines_flag) - fprintf (faction, "#line %d \"%s\"\n", lineno, infile); - putc ('{', faction); + { + sprintf (buf, "#line %d \"%s\"\n", lineno, infile); + obstack_grow (&action_obstack, buf, strlen (buf)); + } + obstack_1grow (&action_obstack, '{'); count = 1; c = getc (finput); @@ -1011,41 +1068,39 @@ copy_action (symbol_list *rule, int stack_offset) switch (c) { case '\n': - putc (c, faction); + obstack_1grow (&action_obstack, c); lineno++; break; case '{': - putc (c, faction); + obstack_1grow (&action_obstack, c); count++; break; case '\'': case '"': - copy_string (finput, faction, c); + copy_string (finput, 0, &action_obstack, c); break; case '/': - putc (c, faction); - c = getc (finput); - if (c != '*' && c != '/') - continue; - copy_comment (finput, faction, c); + copy_comment (finput, 0, &action_obstack); break; case '$': - copy_dollar (finput, faction, rule, stack_offset); + copy_dollar (finput, 0, &action_obstack, + rule, stack_offset); break; case '@': - copy_at (finput, faction, stack_offset); + copy_at (finput, 0, &action_obstack, + stack_offset); break; case EOF: fatal (_("unmatched %s"), "`{'"); default: - putc (c, faction); + obstack_1grow (&action_obstack, c); } c = getc (finput); @@ -1055,12 +1110,13 @@ copy_action (symbol_list *rule, int stack_offset) if (--count) { - putc (c, faction); + obstack_1grow (&action_obstack, c); c = getc (finput); } } - fprintf (faction, ";\n break;}"); + obstack_grow_literal_string (&action_obstack, + ";\n break;}"); } /*-------------------------------------------------------------------. @@ -1119,23 +1175,19 @@ copy_guard (symbol_list *rule, int stack_offset) case '\'': case '"': - copy_string (finput, fguard, c); + copy_string (finput, fguard, 0, c); break; case '/': - putc (c, fguard); - c = getc (finput); - if (c != '*' && c != '/') - continue; - copy_comment (finput, fguard, c); + copy_comment (finput, fguard, 0); break; case '$': - copy_dollar (finput, fguard, rule, stack_offset); + copy_dollar (finput, fguard, 0, rule, stack_offset); break; case '@': - copy_at (finput, fguard, stack_offset); + copy_at (finput, fguard, 0, stack_offset); break; case EOF: @@ -1383,9 +1435,9 @@ readgram (void) { bucket *sdummy; - /* Since the action was written out with this rule's */ - /* number, we must give the new rule this number */ - /* by inserting the new rule before it. */ + /* Since the action was written out with this rule's + number, we must give the new rule this number by + inserting the new rule before it. */ /* Make a dummy nonterminal, a gensym. */ sdummy = gensym (); @@ -1406,7 +1458,8 @@ readgram (void) p->next = crule1; crule1->next = crule; - /* insert the dummy generated by that rule into this rule. */ + /* Insert the dummy generated by that rule into this + rule. */ nitems++; p = XCALLOC (symbol_list, 1); p->sym = sdummy; @@ -1541,9 +1594,13 @@ readgram (void) /* We used to use `unsigned long' as YYSTYPE on MSDOS, but it seems better to be consistent. Most programs should declare their own type anyway. */ - fprintf (fattrs, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n"); - if (fdefines) - fprintf (fdefines, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n"); + obstack_grow_literal_string (&attrs_obstack, + "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n"); + if (defines_flag) + obstack_grow_literal_string (&defines_obstack, "\ +#ifndef YYSTYPE\n\ +# define YYSTYPE int\n\ +#endif\n"); } /* Report any undefined symbols and consider them nonterminals. */ @@ -1567,7 +1624,7 @@ readgram (void) `--------------------------------------------------------------*/ static void -output_token_defines (FILE *file) +output_token_defines (struct obstack *oout) { bucket *bp; char *cp, *symbol; @@ -1600,14 +1657,15 @@ output_token_defines (FILE *file) if (c != '\0') continue; - fprintf (file, "#define\t%s\t%d\n", symbol, - ((translations && !raw_flag) - ? bp->user_token_number : bp->value)); + obstack_fgrow2 (oout, "#define\t%s\t%d\n", + symbol, + ((translations && !raw_flag) + ? bp->user_token_number : bp->value)); if (semantic_parser) - fprintf (file, "#define\tT%s\t%d\n", symbol, bp->value); + obstack_fgrow2 (oout, "#define\tT%s\t%d\n", symbol, bp->value); } - putc ('\n', file); + obstack_1grow (oout, '\n'); } @@ -1730,7 +1788,7 @@ packsymbols (void) error_token_number = errtoken->value; if (!no_parser_flag) - output_token_defines (ftable); + output_token_defines (&table_obstack); if (startval->class == unknown_sym) fatal (_("the start symbol %s is undefined"), startval->tag); @@ -1741,15 +1799,16 @@ packsymbols (void) if (defines_flag) { - output_token_defines (fdefines); + output_token_defines (&defines_obstack); if (!pure_parser) { if (spec_name_prefix) - fprintf (fdefines, "\nextern YYSTYPE %slval;\n", - spec_name_prefix); + obstack_fgrow1 (&defines_obstack, "\nextern YYSTYPE %slval;\n", + spec_name_prefix); else - fprintf (fdefines, "\nextern YYSTYPE yylval;\n"); + obstack_grow_literal_string (&defines_obstack, + "\nextern YYSTYPE yylval;\n"); } if (semantic_parser) @@ -1757,7 +1816,8 @@ packsymbols (void) { /* don't make these for dummy nonterminals made by gensym. */ if (*tags[i] != '@') - fprintf (fdefines, "#define\tNT%s\t%d\n", tags[i], i); + obstack_fgrow2 (&defines_obstack, + "#define\tNT%s\t%d\n", tags[i], i); } #if 0 /* `fdefines' is now a temporary file, so we need to copy its @@ -1837,9 +1897,9 @@ packgram (void) /*-------------------------------------------------------------------. | Read in the grammar specification and record it in the format | | described in gram.h. All guards are copied into the FGUARD file | -| and all actions into FACTION, in each case forming the body of a C | -| function (YYGUARD or YYACTION) which contains a switch statement | -| to decide which guard or action to execute. | +| and all actions into ACTION_OBSTACK, in each case forming the body | +| of a C function (YYGUARD or YYACTION) which contains a switch | +| statement to decide which guard or action to execute. | `-------------------------------------------------------------------*/ void @@ -1889,16 +1949,19 @@ reader (void) undeftoken->class = token_sym; undeftoken->user_token_number = 2; - /* Read the declaration section. Copy %{ ... %} groups to FTABLE - and FDEFINES file. Also notice any %token, %left, etc. found - there. */ - putc ('\n', ftable); - fprintf (ftable, "\ + /* Read the declaration section. Copy %{ ... %} groups to + TABLE_OBSTACK and FDEFINES file. Also notice any %token, %left, + etc. found there. */ + obstack_1grow (&table_obstack, '\n'); + obstack_fgrow3 (&table_obstack, "\ /* %s, made from %s\n\ by GNU bison %s. */\n\ -\n", no_parser_flag ? "Bison-generated parse tables" : "A Bison parser", infile, VERSION); +\n", + no_parser_flag ? "Bison-generated parse tables" : "A Bison parser", + infile, VERSION); - fputs ("#define YYBISON 1 /* Identify Bison output. */\n\n", ftable); + obstack_grow_literal_string (&table_obstack, + "#define YYBISON 1 /* Identify Bison output. */\n\n"); read_declarations (); /* Start writing the guard and action files, if they are needed. */ output_headers (); @@ -1907,12 +1970,12 @@ reader (void) readgram (); /* Now we know whether we need the line-number stack. If we do, write its type into the .tab.h file. */ - if (fdefines) - reader_output_yylsp (fdefines); + if (defines_flag) + reader_output_yylsp (&defines_obstack); /* Write closing delimiters for actions and guards. */ output_trailers (); if (locations_flag) - fputs ("#define YYLSP_NEEDED\n\n", ftable); + obstack_grow_literal_string (&table_obstack, "#define YYLSP_NEEDED\n\n"); /* Assign the symbols their symbol numbers. Write #defines for the token symbols into FDEFINES if requested. */ packsymbols (); @@ -1925,10 +1988,10 @@ reader (void) void -reader_output_yylsp (FILE *f) +reader_output_yylsp (struct obstack *oout) { if (locations_flag) - fputs ("\ + obstack_grow_literal_string (oout, "\ \n\ #ifndef YYLTYPE\n\ typedef struct yyltype\n\ @@ -1944,6 +2007,5 @@ typedef struct yyltype\n\ \n\ # define YYLTYPE yyltype\n\ #endif\n\ -\n", - f); +\n"); }