X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/1e9798d5699ca67718fd3b0d6baa9abcf27e6cd3..ef7ddeddaaafb6b648ff04c8126cc94f8ea458b6:/src/reader.c diff --git a/src/reader.c b/src/reader.c index e5aca8c4..cc24af65 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,9 @@ #include "system.h" +#include "obstack.h" +#include "quotearg.h" +#include "quote.h" #include "getargs.h" #include "files.h" #include "xalloc.h" @@ -31,7 +34,6 @@ #include "output.h" #include "reader.h" #include "conflicts.h" -#include "quote.h" /* Number of slots allocated (but not necessarily used yet) in `rline' */ static int rline_allocated; @@ -151,17 +153,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 +182,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,7 +204,10 @@ 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); } @@ -204,16 +220,20 @@ copy_string (FILE *fin, FILE *fout, int match) `----------------------------------------------------------------*/ static inline void -copy_comment2 (FILE *fin, FILE *out1, FILE *out2) +copy_comment2 (FILE *fin, FILE *out1, + struct obstack *oout2, struct obstack *oout) { int cplus_comment; int ended; int c; /* We read a `/', output it. */ - putc ('/', out1); - if (out2) - putc ('/', out2); + if (out1) + putc ('/', out1); + if (oout) + obstack_1grow (oout, '/'); + if (oout2) + obstack_1grow (oout2, '/'); switch ((c = getc (fin))) { @@ -228,9 +248,12 @@ copy_comment2 (FILE *fin, FILE *out1, FILE *out2) return; } - 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); c = getc (fin); ended = 0; @@ -240,26 +263,35 @@ copy_comment2 (FILE *fin, FILE *out1, FILE *out2) { while (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); 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 @@ -269,9 +301,12 @@ copy_comment2 (FILE *fin, FILE *out1, FILE *out2) fatal (_("unterminated comment")); else { - 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); c = getc (fin); } } @@ -284,9 +319,9 @@ copy_comment2 (FILE *fin, FILE *out1, FILE *out2) `-------------------------------------------------------------------*/ static inline void -copy_comment (FILE *fin, FILE *fout) +copy_comment (FILE *fin, FILE *fout, struct obstack *oout) { - copy_comment2 (fin, fout, NULL); + copy_comment2 (fin, fout, NULL, oout); } @@ -298,24 +333,32 @@ copy_comment (FILE *fin, FILE *fout) `-----------------------------------------------------------------*/ 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 @@ -338,7 +381,7 @@ 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); @@ -355,11 +398,20 @@ copy_dollar (FILE *fin, FILE *fout, 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); @@ -373,9 +425,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); @@ -401,7 +462,8 @@ 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, quotearg_style (c_quoting_style, infile)); after_percent = 0; @@ -412,7 +474,7 @@ copy_definition (void) switch (c) { case '\n': - putc (c, fattrs); + obstack_1grow (&attrs_obstack, c); lineno++; break; @@ -422,18 +484,18 @@ copy_definition (void) case '\'': case '"': - copy_string (finput, fattrs, c); + copy_string (finput, 0, &attrs_obstack, c); break; case '/': - copy_comment (finput, fattrs); + 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); @@ -442,12 +504,10 @@ copy_definition (void) { if (c == '}') return; - putc ('%', fattrs); + obstack_1grow (&attrs_obstack, '%'); } after_percent = 0; - } - } @@ -703,11 +763,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) @@ -721,21 +781,22 @@ 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, quotearg_style (c_quoting_style, 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_1grow (&defines_obstack, c); switch (c) { @@ -744,7 +805,7 @@ parse_union_decl (void) break; case '/': - copy_comment2 (finput, fattrs, fdefines); + copy_comment2 (finput, 0, &defines_obstack, &attrs_obstack); break; case '{': @@ -757,9 +818,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 != ';') @@ -875,7 +936,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 @@ -941,11 +1002,9 @@ read_declarations (void) break; case SEMANTIC_PARSER: - if (semantic_parser == 0) - { - semantic_parser = 1; - open_extra_files (); - } + if (!semantic_parser) + fguard = xfopen (guardfile, "w"); + semantic_parser = 1; break; case PURE_PARSER: @@ -984,15 +1043,22 @@ 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, quotearg_style (c_quoting_style, infile)); + obstack_grow (&action_obstack, buf, strlen (buf)); + } + obstack_1grow (&action_obstack, '{'); count = 1; c = getc (finput); @@ -1004,37 +1070,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 '/': - copy_comment (finput, faction); + 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); @@ -1044,12 +1112,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;}"); } /*-------------------------------------------------------------------. @@ -1074,7 +1143,8 @@ copy_guard (symbol_list *rule, int stack_offset) fprintf (fguard, "\ncase %d:\n", nrules); if (!no_lines_flag) - fprintf (fguard, "#line %d \"%s\"\n", lineno, infile); + fprintf (fguard, "#line %d %s\n", + lineno, quotearg_style (c_quoting_style, infile)); putc ('{', fguard); count = 0; @@ -1108,19 +1178,19 @@ copy_guard (symbol_list *rule, int stack_offset) case '\'': case '"': - copy_string (finput, fguard, c); + copy_string (finput, fguard, 0, c); break; case '/': - copy_comment (finput, fguard); + 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: @@ -1527,9 +1597,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. */ @@ -1553,7 +1627,7 @@ readgram (void) `--------------------------------------------------------------*/ static void -output_token_defines (FILE *file) +output_token_defines (struct obstack *oout) { bucket *bp; char *cp, *symbol; @@ -1586,14 +1660,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'); } @@ -1716,7 +1791,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); @@ -1727,15 +1802,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) @@ -1743,7 +1819,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 @@ -1823,9 +1900,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 @@ -1875,16 +1952,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 (); @@ -1893,12 +1973,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 1\n\n"); /* Assign the symbols their symbol numbers. Write #defines for the token symbols into FDEFINES if requested. */ packsymbols (); @@ -1910,26 +1990,28 @@ reader (void) } +/*------------------------------------------------------------------. +| Define YYLTYPE. Cannot be in the skeleton since we might have to | +| output it in the headers if --defines is used. | +`------------------------------------------------------------------*/ + 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\ {\n\ - int timestamp;\n\ int first_line;\n\ - int first_column;\ + int first_column;\n\ \n\ int last_line;\n\ int last_column;\n\ - char *text;\n\ } yyltype;\n\ \n\ # define YYLTYPE yyltype\n\ #endif\n\ -\n", - f); +\n"); }