+2001-12-15 Akim Demaille <akim@epita.fr>
+
+ The header can also be produced directly, without any obstack!
+ Yahoo!
+
+ * src/files.c, src/files.h (defines_obstack): Remove.
+ (compute_header_macro): Global.
+ (defines_obstack_save): Remove.
+ * src/reader.c (parse_union_decl): No longer output to
+ defines_obstack: its content can be found in the `stype' muscle
+ anyway.
+ (output_token_translations): Merge into...
+ (symbols_output): this.
+ Rename as...
+ (symbols_save): this.
+ (reader): Adjust.
+ * src/output.c (header_output): New.
+ (output): Call it.
+
2001-12-15 Akim Demaille <akim@epita.fr>
* src/reader.c (parse_union_decl): Instead of handling two obstack
struct obstack action_obstack;
struct obstack attrs_obstack;
-struct obstack defines_obstack;
struct obstack guard_obstack;
struct obstack output_obstack;
| alphanumerical + underscore). |
`-----------------------------------------------------------------*/
-static char *
+char *
compute_header_macro (void)
{
const char *prefix = "BISON_";
xfclose (out);
}
-/*---------------------------------------------------------------------.
-| Output double inclusion protection macros and saves defines_obstack |
-`---------------------------------------------------------------------*/
-
-static void
-defines_obstack_save (const char *filename)
-{
- FILE *out = xfopen (filename, "w");
- size_t size = obstack_object_size (&defines_obstack);
- char *macro_name = compute_header_macro ();
-
- fprintf (out, "#ifndef %s\n", macro_name);
- fprintf (out, "# define %s\n\n", macro_name);
- fwrite (obstack_finish (&defines_obstack), 1, size, out);
- fprintf (out, "\n#endif /* not %s */\n", macro_name);
-
- free (macro_name);
- xfclose (out);
-}
-
/*------------------------------------------------------------------.
| Return the path to the skeleton which locaction might be given in |
| ENVVAR, otherwise return SKELETON_NAME. |
/* Initialize the obstacks. */
obstack_init (&action_obstack);
obstack_init (&attrs_obstack);
- obstack_init (&defines_obstack);
obstack_init (&guard_obstack);
obstack_init (&output_obstack);
}
void
output_files (void)
{
- /* Output the header file if wanted. */
- if (defines_flag)
- defines_obstack_save (spec_defines_file);
- obstack_free (&defines_obstack, NULL);
-
#if 0
/* Seems to be invalid now --akim. */
/* Output all the action code; precise form depends on which parser. */
extern struct obstack action_obstack;
-/* optionally output #define's for token numbers. */
-extern struct obstack defines_obstack;
-
/* If semantic parser, output a .h file that defines YYSTYPE... */
extern struct obstack attrs_obstack;
FILE *xfopen PARAMS ((const char *name, const char *mode));
int xfclose PARAMS ((FILE *ptr));
+/* Compute the double inclusion guard's name. */
+char * compute_header_macro PARAMS ((void));
+
const char *skeleton_find PARAMS ((const char *envvar,
const char *skeleton_name));
#endif /* !FILES_H_ */
*/
#include "system.h"
-#include "obstack.h"
#include "quotearg.h"
#include "getargs.h"
#include "files.h"
MUSCLE_INSERT_INT ("locations-flag", locations_flag);
}
+
+/*-------------------------.
+| Output the header file. |
+`-------------------------*/
+
+static void
+header_output (void)
+{
+ FILE *out = xfopen (spec_defines_file, "w");
+ char *macro_name = compute_header_macro ();
+
+ fprintf (out, "#ifndef %s\n", macro_name);
+ fprintf (out, "# define %s\n\n", macro_name);
+
+ fputs (muscle_find ("tokendef"), out);
+ fprintf (out, "\
+#ifndef YYSTYPE\n\
+typedef %s
+yystype;\n\
+# define YYSTYPE yystype\n\
+#endif\n",
+ muscle_find ("stype"));
+
+ if (!pure_parser)
+ fprintf (out, "\nextern YYSTYPE %slval;\n",
+ spec_name_prefix);
+ if (semantic_parser)
+ {
+ int i;
+
+ for (i = ntokens; i < nsyms; i++)
+ /* don't make these for dummy nonterminals made by gensym. */
+ if (*tags[i] != '@')
+ fprintf (out, "# define\tNT%s\t%d\n", tags[i], i);
+ }
+
+ fprintf (out, "\n#endif /* not %s */\n", macro_name);
+ free (macro_name);
+ xfclose (out);
+}
+
+
/*----------------------------------------------------------.
| Output the parsing tables and the parser code to ftable. |
`----------------------------------------------------------*/
obstack_1grow (&attrs_obstack, 0);
muscle_insert ("prologue", obstack_finish (&attrs_obstack));
+ /* Output the parser. */
output_master_parser ();
+ /* Output the header if needed. */
+ if (defines_flag)
+ header_output ();
free (rule_table + 1);
obstack_free (&muscle_obstack, 0);
#include "system.h"
-#include "obstack.h"
#include "quotearg.h"
#include "quote.h"
#include "getargs.h"
ungetc (c, finput);
obstack_1grow (&union_obstack, 0);
muscle_insert ("stype", obstack_finish (&union_obstack));
-
- if (defines_flag)
- obstack_fgrow1 (&defines_obstack, "\
-#ifndef YYSTYPE\n\
-typedef %s
-yystype;\n\
-# define YYSTYPE yystype\n\
-#endif\n",
- muscle_find ("stype"));
}
}
\f
-/*--------------------------------------------------------------.
-| For named tokens, but not literal ones, define the name. The |
-| value is the user token number. |
-`--------------------------------------------------------------*/
-
-static void
-output_token_defines (struct obstack *oout)
-{
- bucket *bp;
- char *cp, *symbol;
- char c;
-
- for (bp = firstsymbol; bp; bp = bp->next)
- {
- symbol = bp->tag; /* get symbol */
-
- if (bp->value >= ntokens)
- continue;
- if (bp->user_token_number == SALIAS)
- continue;
- if ('\'' == *symbol)
- continue; /* skip literal character */
- if (bp == errtoken)
- continue; /* skip error token */
- if ('\"' == *symbol)
- {
- /* use literal string only if given a symbol with an alias */
- if (bp->alias)
- symbol = bp->alias->tag;
- else
- continue;
- }
-
- /* Don't #define nonliteral tokens whose names contain periods. */
- cp = symbol;
- while ((c = *cp++) && c != '.');
- if (c != '\0')
- continue;
-
- obstack_fgrow2 (oout, "# define\t%s\t%d\n",
- symbol, bp->user_token_number);
- if (semantic_parser)
- /* FIXME: This is certainly dead wrong, and should be just as
- above. --akim. */
- obstack_fgrow2 (oout, "# define\tT%s\t%d\n", symbol, bp->value);
- }
-}
-
-
/*------------------------------------------------------------------.
| Set TOKEN_TRANSLATIONS. Check that no two symbols share the same |
| number. |
}
-/*-----------------------------------.
-| Output definition of token names. |
-`-----------------------------------*/
+/*---------------------------------------------------------------.
+| Save the definition of token names in the `TOKENDEFS' muscle. |
+`---------------------------------------------------------------*/
static void
-symbols_output (void)
+symbols_save (void)
{
- {
- struct obstack tokendefs;
- obstack_init (&tokendefs);
- output_token_defines (&tokendefs);
- obstack_1grow (&tokendefs, 0);
- muscle_insert ("tokendef", xstrdup (obstack_finish (&tokendefs)));
- obstack_free (&tokendefs, NULL);
- }
-
- if (defines_flag)
+ struct obstack tokendefs;
+ bucket *bp;
+ char *cp, *symbol;
+ char c;
+ obstack_init (&tokendefs);
+
+ for (bp = firstsymbol; bp; bp = bp->next)
{
- output_token_defines (&defines_obstack);
+ symbol = bp->tag; /* get symbol */
- if (!pure_parser)
- obstack_fgrow1 (&defines_obstack, "\nextern YYSTYPE %slval;\n",
- spec_name_prefix);
- if (semantic_parser)
+ if (bp->value >= ntokens)
+ continue;
+ if (bp->user_token_number == SALIAS)
+ continue;
+ if ('\'' == *symbol)
+ continue; /* skip literal character */
+ if (bp == errtoken)
+ continue; /* skip error token */
+ if ('\"' == *symbol)
{
- int i;
-
- for (i = ntokens; i < nsyms; i++)
- {
- /* don't make these for dummy nonterminals made by gensym. */
- if (*tags[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
- contents in `done', so we can't close it here. */
- fclose (fdefines);
- fdefines = NULL;
-#endif
+ /* use literal string only if given a symbol with an alias */
+ if (bp->alias)
+ symbol = bp->alias->tag;
+ else
+ continue;
}
+
+ /* Don't #define nonliteral tokens whose names contain periods. */
+ cp = symbol;
+ while ((c = *cp++) && c != '.');
+ if (c != '\0')
+ continue;
+
+ obstack_fgrow2 (&tokendefs, "# define\t%s\t%d\n",
+ symbol, bp->user_token_number);
+ if (semantic_parser)
+ /* FIXME: This is probably wrong, and should be just as
+ above. --akim. */
+ obstack_fgrow2 (&tokendefs, "# define\tT%s\t%d\n", symbol, bp->value);
}
+
+ obstack_1grow (&tokendefs, 0);
+ muscle_insert ("tokendef", xstrdup (obstack_finish (&tokendefs)));
+ obstack_free (&tokendefs, NULL);
}
/* Some C code is given at the end of the grammar file. */
read_additionnal_code ();
- /* Now we know whether we need the line-number stack. If we do,
- write its type into the .tab.h file.
- This is no longer need with header skeleton. */
-
/* Assign the symbols their symbol numbers. Write #defines for the
token symbols into FDEFINES if requested. */
packsymbols ();
+ /* Save them. */
+ symbols_save ();
+
/* Convert the grammar into the format described in gram.h. */
packgram ();
- /* Output the headers. */
- symbols_output ();
}