* doc/bison.1 (mandoc): Update.
* src/system.h (EXT_GUARD_C, EXT_STYPE_H): Remove .c and .h.
* src/files.c: Support output files extensions computing.
(src_extension): New static variable.
(header_extension): New static variable.
(tr): New function.
(get_extension_index): New function, gets the index of an extension
filename in a string.
(compute_exts_from_gf): New function, computes extensions from the
grammar file extension.
(compute_exts_from_src): New functions, computes extensions from the
C source file extension, file given by ``-o'' option.
(compute_base_names): Update.
(output_files): Update.
+2001-08-01 Marc Autret <autret_m@epita.fr>
+
+ * doc/bison.texinfo: Update.
+ * doc/bison.1 (mandoc): Update.
+ * src/system.h (EXT_GUARD_C, EXT_STYPE_H): Remove .c and .h.
+ * src/files.c: Support output files extensions computing.
+ (src_extension): New static variable.
+ (header_extension): New static variable.
+ (tr): New function.
+ (get_extension_index): New function, gets the index of an extension
+ filename in a string.
+ (compute_exts_from_gf): New function, computes extensions from the
+ grammar file extension.
+ (compute_exts_from_src): New functions, computes extensions from the
+ C source file extension, file given by ``-o'' option.
+ (compute_base_names): Update.
+ (output_files): Update.
+
2001-08-01 Robert Anisko <anisko_r@epita.fr>
* doc/autoconf.texi: Document @$.
Changes in version 1.28a:
+* the input and the output files has automatically a similar extension.
+
* Russian translation added.
* NLS support updated; should hopefully be less troublesome.
.IR yacc ,
the generated files do not have fixed names, but instead use the prefix
of the input file.
+Moreover, if you need to put
+.IR C++
+code in the input file, you can end his name by a C++-like extension
+(.ypp or .y++), then bison will follow your extension to name the
+output file (.cpp or .c++).
For instance, a grammar description file named
-.B parse.y
+.B parse.yxx
would produce the generated parser in a file named
-.BR parse.tab.c ,
+.BR parse.tab.cxx ,
instead of
.IR yacc 's
-.BR y.tab.c .
+.BR y.tab.c
+or old
+.IR Bison
+versions
+.BR parse.tab.c .
.PP
This description of the options that can be given to
.I bison
Indirect:
bison.info-1: 1307
bison.info-2: 50189
-bison.info-3: 99779
-bison.info-4: 149657
-bison.info-5: 196400
+bison.info-3: 99814
+bison.info-4: 149692
+bison.info-5: 196961
\1f
Tag Table:
(Indirect)
Node: Mfcalc Symtab\7f73661
Node: Exercises\7f80034
Node: Grammar File\7f80540
-Node: Grammar Outline\7f81353
-Node: C Declarations\7f82087
-Node: Bison Declarations\7f82667
-Node: Grammar Rules\7f83079
-Node: C Code\7f83539
-Node: Symbols\7f84469
-Node: Rules\7f89550
-Node: Recursion\7f91189
-Node: Semantics\7f92908
-Node: Value Type\7f94002
-Node: Multiple Types\7f94674
-Node: Actions\7f95691
-Node: Action Types\7f98476
-Node: Mid-Rule Actions\7f99779
-Node: Locations\7f105348
-Node: Location Type\7f106013
-Node: Actions and Locations\7f106571
-Node: Location Default Action\7f107735
-Node: Declarations\7f108942
-Node: Token Decl\7f110261
-Node: Precedence Decl\7f112274
-Node: Union Decl\7f113825
-Node: Type Decl\7f114669
-Node: Expect Decl\7f115575
-Node: Start Decl\7f117121
-Node: Pure Decl\7f117499
-Node: Decl Summary\7f119176
-Node: Multiple Parsers\7f124559
-Node: Interface\7f126053
-Node: Parser Function\7f126925
-Node: Lexical\7f127760
-Node: Calling Convention\7f129166
-Node: Token Values\7f131937
-Node: Token Positions\7f133086
-Node: Pure Calling\7f133971
-Node: Error Reporting\7f136903
-Node: Action Features\7f139025
-Node: Algorithm\7f142320
-Node: Look-Ahead\7f144613
-Node: Shift/Reduce\7f146745
-Node: Precedence\7f149657
-Node: Why Precedence\7f150308
-Node: Using Precedence\7f152173
-Node: Precedence Examples\7f153141
-Node: How Precedence\7f153842
-Node: Contextual Precedence\7f154991
-Node: Parser States\7f156782
-Node: Reduce/Reduce\7f158025
-Node: Mystery Conflicts\7f161586
-Node: Stack Overflow\7f164972
-Node: Error Recovery\7f166345
-Node: Context Dependency\7f171481
-Node: Semantic Tokens\7f172329
-Node: Lexical Tie-ins\7f175346
-Node: Tie-in Recovery\7f176894
-Node: Debugging\7f179066
-Node: Invocation\7f182367
-Node: Bison Options\7f183097
-Node: Environment Variables\7f186531
-Node: Option Cross Key\7f187379
-Node: VMS Invocation\7f188223
-Node: Table of Symbols\7f189007
-Node: Glossary\7f196400
-Node: Index\7f202690
+Node: Grammar Outline\7f81388
+Node: C Declarations\7f82122
+Node: Bison Declarations\7f82702
+Node: Grammar Rules\7f83114
+Node: C Code\7f83574
+Node: Symbols\7f84504
+Node: Rules\7f89585
+Node: Recursion\7f91224
+Node: Semantics\7f92943
+Node: Value Type\7f94037
+Node: Multiple Types\7f94709
+Node: Actions\7f95726
+Node: Action Types\7f98511
+Node: Mid-Rule Actions\7f99814
+Node: Locations\7f105383
+Node: Location Type\7f106048
+Node: Actions and Locations\7f106606
+Node: Location Default Action\7f107770
+Node: Declarations\7f108977
+Node: Token Decl\7f110296
+Node: Precedence Decl\7f112309
+Node: Union Decl\7f113860
+Node: Type Decl\7f114704
+Node: Expect Decl\7f115610
+Node: Start Decl\7f117156
+Node: Pure Decl\7f117534
+Node: Decl Summary\7f119211
+Node: Multiple Parsers\7f124594
+Node: Interface\7f126088
+Node: Parser Function\7f126960
+Node: Lexical\7f127795
+Node: Calling Convention\7f129201
+Node: Token Values\7f131972
+Node: Token Positions\7f133121
+Node: Pure Calling\7f134006
+Node: Error Reporting\7f136938
+Node: Action Features\7f139060
+Node: Algorithm\7f142355
+Node: Look-Ahead\7f144648
+Node: Shift/Reduce\7f146780
+Node: Precedence\7f149692
+Node: Why Precedence\7f150343
+Node: Using Precedence\7f152208
+Node: Precedence Examples\7f153176
+Node: How Precedence\7f153877
+Node: Contextual Precedence\7f155026
+Node: Parser States\7f156817
+Node: Reduce/Reduce\7f158060
+Node: Mystery Conflicts\7f161621
+Node: Stack Overflow\7f165007
+Node: Error Recovery\7f166380
+Node: Context Dependency\7f171516
+Node: Semantic Tokens\7f172364
+Node: Lexical Tie-ins\7f175381
+Node: Tie-in Recovery\7f176929
+Node: Debugging\7f179101
+Node: Invocation\7f182402
+Node: Bison Options\7f183658
+Node: Environment Variables\7f187092
+Node: Option Cross Key\7f187940
+Node: VMS Invocation\7f188784
+Node: Table of Symbols\7f189568
+Node: Glossary\7f196961
+Node: Index\7f203251
\1f
End Tag Table
grammar.
The Bison grammar input file conventionally has a name ending in
-`.y'.
+`.y'. *Note Invoking Bison: Invocation.
* Menu:
Here INFILE is the grammar file name, which usually ends in `.y'.
The parser file's name is made by replacing the `.y' with `.tab.c'.
Thus, the `bison foo.y' filename yields `foo.tab.c', and the `bison
-hack/foo.y' filename yields `hack/foo.tab.c'.
+hack/foo.y' filename yields `hack/foo.tab.c'. It's is also possible, in
+case you are writting C++ code instead of C in your grammar file, to
+name it `foo.ypp' or `foo.y++'. Then, the output files will take an
+extention like the given one as input (repectively `foo.tab.cpp' and
+`foo.tab.c++'). This feature takes effect with all options that
+manipulate filenames like `-o' or `-d'.
+
+ For example :
+
+ bison -d INFILE.YXX
+ will produce `infile.tab.cxx' and `infile.tab.hxx'. and
+
+ bison -d INFILE.Y -o OUTPUT.C++
+ will produce `output.c++' and `outfile.h++'.
* Menu:
C-language function that recognizes correct instances of the grammar.
The Bison grammar input file conventionally has a name ending in @samp{.y}.
+@xref{Invocation, ,Invoking Bison}.
@menu
* Grammar Outline:: Overall layout of the grammar file.
@samp{.y}. The parser file's name is made by replacing the @samp{.y}
with @samp{.tab.c}. Thus, the @samp{bison foo.y} filename yields
@file{foo.tab.c}, and the @samp{bison hack/foo.y} filename yields
-@file{hack/foo.tab.c}.@refill
+@file{hack/foo.tab.c}. It's is also possible, in case you are writting
+C++ code instead of C in your grammar file, to name it @file{foo.ypp}
+or @file{foo.y++}. Then, the output files will take an extention like
+the given one as input (repectively @file{foo.tab.cpp} and @file{foo.tab.c++}).
+This feature takes effect with all options that manipulate filenames like
+@samp{-o} or @samp{-d}.
+
+For example :
+
+@example
+bison -d @var{infile.yxx}
+@end example
+will produce @file{infile.tab.cxx} and @file{infile.tab.hxx}. and
+
+@example
+bison -d @var{infile.y} -o @var{output.c++}
+@end example
+will produce @file{output.c++} and @file{outfile.h++}.
+
+@refill
@menu
* Bison Options:: All the options described in detail,
-@set UPDATED 30 July 2001
+@set UPDATED 1 August 2001
@set EDITION 1.28a
@set VERSION 1.28a
-@set UPDATED 30 July 2001
+@set UPDATED 1 August 2001
@set EDITION 1.28a
@set VERSION 1.28a
static char *base_name;
static char *short_base_name;
+/* C source file extension (the parser source). */
+static char *src_extension;
+/* Header file extension (if option ``-d'' is specified). */
+static char *header_extension;
+
\f
/*--------------------------.
| Is SUFFIX ending STRING? |
}
\f
-/*----------------------------------------.
-| Compute BASE_NAME and SHORT_BASE_NAME. |
-`----------------------------------------*/
+/*----------------------------------------------------------------.
+| Compute BASE_NAME, SHORT_BASE_NAME and output files extensions. |
+`----------------------------------------------------------------*/
+
+/* Replace all characters FROM by TO in the string IN.
+ and returns a new allocated string. */
+static char *
+tr(const char *in, char from, char to)
+{
+ char *temp;
+ char *out;
+
+ out = XMALLOC (char, strlen (in) + 1);
+
+ for (temp = out; *in; in++, out++)
+ if (*in == from)
+ *out = to;
+ else
+ *out = *in;
+ *out = 0;
+ return (temp);
+}
+
+/* Gets the extension index in FILENAME. Returns 0 if fails to
+ find an extension. */
+static int
+get_extension_index(const char *filename)
+{
+ int len;
+
+ len = strlen (filename);
+
+ if (filename[len-- - 1] == '.')
+ return (0);
+
+ while ((len > 0) && (filename[len - 1] != '.'))
+ if (filename[len - 1] == '/')
+ return (0);
+ else
+ len--;
+
+ return (len - 1);
+}
+
+/* Computes extensions from the grammar file extension. */
+static void
+compute_exts_from_gf(const char *ext)
+{
+ src_extension = tr(ext, 'y', 'c');
+ src_extension = tr(src_extension, 'Y', 'C');
+ header_extension = tr(ext, 'y', 'h');
+ header_extension = tr(header_extension, 'Y', 'H');
+}
+
+/* Computes extensions from the given c source file extension. */
+static void
+compute_exts_from_src(const char *ext)
+{
+ src_extension = xstrdup(ext);
+ header_extension = tr(ext, 'c', 'h');
+ header_extension = tr(header_extension, 'C', 'H');
+}
/* FIXME: Should use xstrndup. */
{
size_t base_length;
size_t short_base_length;
+ size_t ext_index;
+
+ /* Set default extensions */
+ src_extension = ".c";
+ header_extension = ".h";
/* If --output=foo.c was specified (SPEC_OUTFILE == foo.c),
BASE_NAME and SHORT_BASE_NAME are `foo'.
#endif /* MSDOS */
/* BASE_LENGTH includes ".tab" but not ".c". */
base_length = strlen (spec_outfile);
- if (strsuffix (spec_outfile, ".c"))
- base_length -= 2;
+
+ ext_index = get_extension_index (spec_outfile);
+ /* if the initial segment of extension contains 'c' or a 'C', I assume
+ that it is a C or C++ source file */
+ if (ext_index)
+ ext_index = (strspn(spec_outfile + ext_index + 1, "cC")) ? ext_index : 0;
+ if (ext_index)
+ {
+ base_length -= strlen (spec_outfile + ext_index);
+ compute_exts_from_src(spec_outfile + ext_index);
+ }
+
base_name = strndup (spec_outfile, base_length);
/* SHORT_BASE_LENGTH includes neither ".tab" nor ".c". */
short_base_length = base_length;
strlwr (spec_file_prefix);
#endif /* MSDOS */
short_base_name = xstrdup (spec_file_prefix);
-
base_name = XMALLOC (char,
strlen (short_base_name) + strlen (EXT_TAB) + 1);
stpcpy (stpcpy (base_name, short_base_name), EXT_TAB);
/* BASE_LENGTH gets length of BASE_NAME, sans ".y" suffix if any. */
base_length = strlen (name_base);
- if (strsuffix (name_base, ".y"))
- base_length -= 2;
+
+ ext_index = get_extension_index (name_base);
+ /* if the initial segment of extension contains a 'y' or a 'Y', I assume
+ that it is a yacc or bison grammar file */
+ if (ext_index)
+ ext_index = (strspn(name_base + ext_index + 1, "yY")) ? ext_index : 0;
+ if (ext_index)
+ {
+ base_length -= strlen (name_base + ext_index);
+ compute_exts_from_gf(name_base + ext_index);
+ }
+
short_base_length = base_length;
short_base_name = strndup (name_base, short_base_length);
xfclose (finput);
compute_base_names ();
+
attrsfile = stringappend (short_base_name, EXT_STYPE_H);
+#ifndef MSDOS
+ stringappend (attrsfile, header_extension);
+#endif /* MSDOS */
/* Output the main file. */
if (spec_outfile)
obstack_save (&table_obstack, spec_outfile);
else
- obstack_save (&table_obstack, stringappend (base_name, ".c"));
+ obstack_save (&table_obstack, stringappend (base_name, src_extension));
/* Output the header file if wanted. */
if (defines_flag)
- obstack_save (&defines_obstack, stringappend (base_name, ".h"));
+ obstack_save (&defines_obstack, stringappend (base_name, header_extension));
/* If we output only the table, dump the actions in ACTFILE. */
if (no_parser_flag)
into its own file, ATTTRSFILE. */
if (semantic_parser)
{
+ char *temp_name;
+
obstack_save (&attrs_obstack, attrsfile);
- obstack_save (&guard_obstack,
- stringappend (short_base_name, EXT_GUARD_C));
+ temp_name = stringappend (short_base_name, EXT_GUARD_C);
+#ifndef MSDOS
+ temp_name = stringappend (temp_name, src_extension);
+#endif /* MSDOS */
+ obstack_save (&guard_obstack, temp_name);
}
if (verbose_flag)
/* VMS. */
# define EXT_TAB "_tab"
# define EXT_OUTPUT ".output"
-# define EXT_STYPE_H "_stype.h"
-# define EXT_GUARD_C "_guard.c"
+# define EXT_STYPE_H "_stype"
+# define EXT_GUARD_C "_guard"
#else /* ! VMS */
# ifdef MSDOS
/* MS DOS. */
/* Standard. */
# define EXT_TAB ".tab"
# define EXT_OUTPUT ".output"
-# define EXT_STYPE_H ".stype.h"
-# define EXT_GUARD_C ".guard.c"
+# define EXT_STYPE_H ".stype"
+# define EXT_GUARD_C ".guard"
# endif /* ! MSDOS */
#endif /* ! VMS */