]> git.saurik.com Git - bison.git/commitdiff
* src/getargs.c (skeleton_arg): Last arg is now location const *.
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 19 Dec 2006 00:34:37 +0000 (00:34 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 19 Dec 2006 00:34:37 +0000 (00:34 +0000)
Rewrite to simplify the logic.
(language_argmatch): Likewise.

* doc/bison.texinfo (Decl Summary, Bison Options): Don't claim
Java is supported.
* src/complain.c (program_name): Remove decl; no longer needed.
* src/main.c (program_name): Remove; now belongs to getargs.

2006-12-18  Paolo Bonzini  <bonzini@gnu.org>

* NEWS: Document %language.

* data/Makefile.am (dist_pkgdata_DATA): Add c-skel.m4, c++-skel.m4.

* data/c-skel.m4, data/c++-skel.m4: New files.
* data/glr.c: Complain on push parsers.

* doc/bison.texinfo (C++ Parser Interface): Prefer %language
over %skeleton.
(Directives): Document %language and %skeleton.
(Command line): Document -L.

* examples/extexi: Rewrite %require directive.
* examples/calc++/Makefile.am: Pass VERSION to extexi.

* src/files.c (compute_exts_from_gc): Look in language structure
for .y extension.
(compute_file_name_parts): Check whether .tab should be added.
* src/getargs.c (valid_languages, skeleton_prio, language_prio):
(language, skeleton_arg, language_argmatch): New.
(long_options): Add --language.
(getargs): Use skeleton_arg, add -L/--language.
* src/getargs.h: Include location.h.
(struct bison_language, language, skeleton_arg, language_argmatch): New.
* src/output.c (prepare): Pick default skeleton from struct language.
Don't dispatch C skeletons here.
* src/parse-gram.y (PERCENT_LANGUAGE): New.
(prologue_declaration): Add "%language" rule, use skeleton_arg.
* src/scan-gram.l ("%language"): New rule.

* tests/calc.at: Test %skeleton and %language.
* tests/local.at (AT_SKEL_CC_IF): Look for %language.
(AT_GLR_IF): Look for %skeleton "glr.cc".
(AT_LALR1_CC_IF, AT_GLR_CC_IF): Rewrite.
(AT_YACC_IF): Reject %language.

2006-12-18  Paul Eggert  <eggert@cs.ucla.edu>

19 files changed:
ChangeLog
NEWS
data/Makefile.am
data/c++-skel.m4 [new file with mode: 0644]
data/c-skel.m4 [new file with mode: 0644]
data/glr.c
doc/bison.texinfo
examples/calc++/Makefile.am
examples/extexi
src/complain.c
src/files.c
src/getargs.c
src/getargs.h
src/main.c
src/output.c
src/parse-gram.y
src/scan-gram.l
tests/calc.at
tests/local.at

index 8f996fa1d3d655e4b7daa519b1c4c26d32f45f62..6901a5b10efa827937b1bc35d57c26a1e0b09fc0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,52 @@
+2006-12-18  Paul Eggert  <eggert@cs.ucla.edu>
+
+       * src/getargs.c (skeleton_arg): Last arg is now location const *.
+       Rewrite to simplify the logic.
+       (language_argmatch): Likewise.
+
+       * doc/bison.texinfo (Decl Summary, Bison Options): Don't claim
+       Java is supported.
+       * src/complain.c (program_name): Remove decl; no longer needed.
+       * src/main.c (program_name): Remove; now belongs to getargs.
+
+2006-12-18  Paolo Bonzini  <bonzini@gnu.org>
+
+       * NEWS: Document %language.
+
+       * data/Makefile.am (dist_pkgdata_DATA): Add c-skel.m4, c++-skel.m4.
+
+       * data/c-skel.m4, data/c++-skel.m4: New files.
+       * data/glr.c: Complain on push parsers.
+
+       * doc/bison.texinfo (C++ Parser Interface): Prefer %language
+       over %skeleton.
+       (Directives): Document %language and %skeleton.
+       (Command line): Document -L.
+
+       * examples/extexi: Rewrite %require directive.
+       * examples/calc++/Makefile.am: Pass VERSION to extexi.
+
+       * src/files.c (compute_exts_from_gc): Look in language structure
+       for .y extension.
+       (compute_file_name_parts): Check whether .tab should be added.
+       * src/getargs.c (valid_languages, skeleton_prio, language_prio):
+       (language, skeleton_arg, language_argmatch): New.
+       (long_options): Add --language.
+       (getargs): Use skeleton_arg, add -L/--language.
+       * src/getargs.h: Include location.h.
+       (struct bison_language, language, skeleton_arg, language_argmatch): New.
+       * src/output.c (prepare): Pick default skeleton from struct language.
+       Don't dispatch C skeletons here.
+       * src/parse-gram.y (PERCENT_LANGUAGE): New.
+       (prologue_declaration): Add "%language" rule, use skeleton_arg.
+       * src/scan-gram.l ("%language"): New rule.
+
+       * tests/calc.at: Test %skeleton and %language.
+       * tests/local.at (AT_SKEL_CC_IF): Look for %language.
+       (AT_GLR_IF): Look for %skeleton "glr.cc".
+       (AT_LALR1_CC_IF, AT_GLR_CC_IF): Rewrite.
+       (AT_YACC_IF): Reject %language.
+
 2006-12-18  Paul Eggert  <eggert@cs.ucla.edu>
 
        * src/symtab.h (struct semantic_type): Remove the tag 'semantic_type',
 2006-12-18  Paul Eggert  <eggert@cs.ucla.edu>
 
        * src/symtab.h (struct semantic_type): Remove the tag 'semantic_type',
diff --git a/NEWS b/NEWS
index 31a44a0c71ad359325c0408093b642a20e1e78f8..119521ccd93a5ba67fee4f4152e5054de42e4704 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,11 @@ Changes in version 2.3a+ (????-??-??):
 * The -g and --graph options now output graphs in Graphviz DOT format,
   not VCG format.
 
 * The -g and --graph options now output graphs in Graphviz DOT format,
   not VCG format.
 
+* An experimental directive %language specifies the language of the
+  generated parser, which can be C (the default) or C++.  This
+  directive affects the skeleton used, and the names of the generated
+  files if the grammar file's name ends in ".y".
+
 * The grammar file may now specify the name of the parser header file using
   %defines.  For example:
 
 * The grammar file may now specify the name of the parser header file using
   %defines.  For example:
 
@@ -96,7 +101,7 @@ Changes in version 2.3a+ (????-??-??):
          - `%start-header {CODE}', which only Bison 2.3a supported.
 
     3. %provides {CODE}
          - `%start-header {CODE}', which only Bison 2.3a supported.
 
     3. %provides {CODE}
-    
+
        This is the right place to write additional definitions you would like
        Bison to expose externally.  That is, this directive inserts your CODE
        both into the parser header file and into the parser code file after
        This is the right place to write additional definitions you would like
        Bison to expose externally.  That is, this directive inserts your CODE
        both into the parser header file and into the parser code file after
index 6fb68120f63248a1497b5c32679023b6a8c96c3c..69574343bf3e53efd432fa634a192c82df3af302 100644 (file)
@@ -16,8 +16,8 @@
 ## 02110-1301  USA
 
 dist_pkgdata_DATA = README bison.m4 \
 ## 02110-1301  USA
 
 dist_pkgdata_DATA = README bison.m4 \
-   c.m4 yacc.c glr.c push.c \
-   c++.m4 location.cc lalr1.cc glr.cc
+   c-skel.m4 c.m4 yacc.c glr.c push.c \
+   c++-skel.m4 c++.m4 location.cc lalr1.cc glr.cc
 
 m4sugardir = $(pkgdatadir)/m4sugar
 dist_m4sugar_DATA = m4sugar/m4sugar.m4
 
 m4sugardir = $(pkgdatadir)/m4sugar
 dist_m4sugar_DATA = m4sugar/m4sugar.m4
diff --git a/data/c++-skel.m4 b/data/c++-skel.m4
new file mode 100644 (file)
index 0000000..183282b
--- /dev/null
@@ -0,0 +1,29 @@
+m4_divert(-1)                                               -*- Autoconf -*-
+
+# C++ skeleton dispatching for Bison.
+# Copyright (C) 2006 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301  USA
+
+b4_glr_if(             [m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.cc]])])
+b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.cc]])])
+
+b4_push_if([m4_fatal([%push-parser is not supported by C++])])
+
+m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[lalr1.cc]])
+m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"])
+
+m4_include(b4_used_skeleton)
diff --git a/data/c-skel.m4 b/data/c-skel.m4
new file mode 100644 (file)
index 0000000..4833d01
--- /dev/null
@@ -0,0 +1,28 @@
+m4_divert(-1)                                               -*- Autoconf -*-
+
+# C skeleton dispatching for Bison.
+# Copyright (C) 2006 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301  USA
+
+b4_push_if(            [m4_define([b4_used_skeleton], [b4_pkgdatadir/[push.c]])])
+b4_glr_if(             [m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.c]])])
+b4_nondeterministic_if([m4_define([b4_used_skeleton], [b4_pkgdatadir/[glr.c]])])
+
+m4_define_default([b4_used_skeleton], [b4_pkgdatadir/[yacc.c]])
+m4_define_default([b4_skeleton], ["b4_basename(b4_used_skeleton)"])
+
+m4_include(b4_used_skeleton)
index 9ac721ba8ad55f28076c699c23904f2b50c06ab9..37ba588cc3fa2259f649f5255836919775e681fd 100644 (file)
@@ -21,6 +21,9 @@ m4_divert(-1)                                                       -*- C -*-
 
 m4_include(b4_pkgdatadir/[c.m4])
 
 
 m4_include(b4_pkgdatadir/[c.m4])
 
+b4_push_if([
+m4_fatal([Non-deterministic push parsers are not yet supported])])
+
 ## ---------------- ##
 ## Default values.  ##
 ## ---------------- ##
 ## ---------------- ##
 ## Default values.  ##
 ## ---------------- ##
index af9d5321af30e5cd97fe739f6153f4bf0bc14f84..061bbc7638c7a3932f73b99e4e883e0981a9ccac 100644 (file)
@@ -4619,6 +4619,11 @@ Specify a prefix to use for all Bison output file names.  The names are
 chosen as if the input file were named @file{@var{prefix}.y}.
 @end deffn
 
 chosen as if the input file were named @file{@var{prefix}.y}.
 @end deffn
 
+@deffn {Directive} %language="@var{language}"
+Specify the programming language for the generated parser.  Currently
+supported languages include C and C++.
+@end deffn
+
 @deffn {Directive} %locations
 Generate the code processing the locations (@pxref{Action Features,
 ,Special Features for Use in Actions}).  This mode is enabled as soon as
 @deffn {Directive} %locations
 Generate the code processing the locations (@pxref{Action Features,
 ,Special Features for Use in Actions}).  This mode is enabled as soon as
@@ -4681,6 +4686,11 @@ Require version @var{version} or higher of Bison.  @xref{Require Decl, ,
 Require a Version of Bison}.
 @end deffn
 
 Require a Version of Bison}.
 @end deffn
 
+@deffn {Directive} %skeleton "@var{file}"
+Specify the skeleton to use.  You probably don't need this option unless
+you are developing Bison.
+@end deffn
+
 @deffn {Directive} %token-table
 Generate an array of token names in the parser file.  The name of the
 array is @code{yytname}; @code{yytname[@var{i}]} is the name of the
 @deffn {Directive} %token-table
 Generate an array of token names in the parser file.  The name of the
 array is @code{yytname}; @code{yytname[@var{i}]} is the name of the
@@ -7262,8 +7272,9 @@ Tuning the parser:
 @table @option
 @item -S @var{file}
 @itemx --skeleton=@var{file}
 @table @option
 @item -S @var{file}
 @itemx --skeleton=@var{file}
-Specify the skeleton to use.  You probably don't need this option unless
-you are developing Bison.
+Specify the skeleton to use, as if @code{%skeleton} was specified
+(@pxref{Decl Summary, , Bison Declaration Summary}).  You probably
+don't need this option unless you are developing Bison.
 
 @item -t
 @itemx --debug
 
 @item -t
 @itemx --debug
@@ -7271,6 +7282,12 @@ In the parser file, define the macro @code{YYDEBUG} to 1 if it is not
 already defined, so that the debugging facilities are compiled.
 @xref{Tracing, ,Tracing Your Parser}.
 
 already defined, so that the debugging facilities are compiled.
 @xref{Tracing, ,Tracing Your Parser}.
 
+@item -L @var{language}
+@itemx --language=@var{language}
+Specify the programming language for the generated parser, as if
+@code{%language} was specified (@pxref{Decl Summary, , Bison Declaration
+Summary}).  Currently supported languages include C and C++.
+
 @item --locations
 Pretend that @code{%locations} was specified.  @xref{Decl Summary}.
 
 @item --locations
 Pretend that @code{%locations} was specified.  @xref{Decl Summary}.
 
@@ -7433,14 +7450,24 @@ int yyparse (void);
 
 @node C++ Bison Interface
 @subsection C++ Bison Interface
 
 @node C++ Bison Interface
 @subsection C++ Bison Interface
-@c - %skeleton "lalr1.cc"
+@c - %language "C++"
 @c - Always pure
 @c - initial action
 
 @c - Always pure
 @c - initial action
 
-The C++ parser @acronym{LALR}(1) skeleton is named @file{lalr1.cc}.  To
-select it, you may either pass the option @option{--skeleton=lalr1.cc}
-to Bison, or include the directive @samp{%skeleton "lalr1.cc"} in the
-grammar preamble.  When run, @command{bison} will create several
+The C++ parser @acronym{LALR}(1) skeleton is selected using a
+language directive, @samp{%language "C++"}, or the synonymous
+command-line option @option{--language=c++}@footnote{For both
+the grammar directive and the command-line option, the
+language name is case-insensitive}.  These were introduced
+in Bison 2.3b; for compatibility with earlier versions, you
+may also pass the option @option{--skeleton=lalr1.cc} to Bison
+or include the directive @samp{%skeleton "lalr1.cc"} in the
+grammar preamble.  Specifying the language is however preferred,
+because it is clearer and because it will automatically choose the
+correct skeleton for @acronym{GLR} parsers (the C++ @acronym{GLR}
+skeleton is still under development).
+
+When run, @command{bison} will create several
 entities in the @samp{yy} namespace.  Use the @samp{%name-prefix}
 directive to change the namespace name, see @ref{Decl Summary}.  The
 various classes are generated in the following files:
 entities in the @samp{yy} namespace.  Use the @samp{%name-prefix}
 directive to change the namespace name, see @ref{Decl Summary}.  The
 various classes are generated in the following files:
@@ -7828,8 +7855,8 @@ the grammar for.
 
 @comment file: calc++-parser.yy
 @example
 
 @comment file: calc++-parser.yy
 @example
-%skeleton "lalr1.cc"                          /*  -*- C++ -*- */
-%require "2.1a"
+%language "C++"                          /*  -*- C++ -*- */
+%require "2.3b"
 %defines
 %define "parser_class_name" "calcxx_parser"
 @end example
 %defines
 %define "parser_class_name" "calcxx_parser"
 @end example
index fea49b173451a474f3d7372728d57f46ba7d4757..5d4758ba28a03fec1deef6d521604f724bf8bc10 100644 (file)
@@ -35,8 +35,8 @@ extexi = $(top_srcdir)/examples/extexi
 # Extract in src.
 $(calc_extracted): $(doc) $(extexi)
        cd $(srcdir) && \
 # Extract in src.
 $(calc_extracted): $(doc) $(extexi)
        cd $(srcdir) && \
-          $(AWK) -f ../extexi ../../doc/bison.texinfo -- \
-            calc++-parser.yy \
+          $(AWK) -f ../extexi -v VERSION="@VERSION@" \
+            ../../doc/bison.texinfo -- calc++-parser.yy \
             calc++-scanner.ll calc++.cc calc++-driver.hh calc++-driver.cc
 
 
             calc++-scanner.ll calc++.cc calc++-driver.hh calc++-driver.cc
 
 
index 56a50c87af2e81b617511d39f4f37888d8884aa2..a004b1af265b725ca6d3ee138e277575a7ff9b8b 100644 (file)
@@ -111,6 +111,7 @@ function normalize(contents,    i, lines, n, line, res) {
        else
          line = "";
 
        else
          line = "";
 
+      gsub (/^%require "[^"]*"$/, "%require \"" VERSION "\"", line);
       gsub (/^@result\{\}/, "", line);
       gsub (/^@error\{\}/,  "", line);
       gsub ("@[{]", "{", line);
       gsub (/^@result\{\}/, "", line);
       gsub (/^@error\{\}/,  "", line);
       gsub ("@[{]", "{", line);
index 7428a4af2f50c95493116348e7d83930f5a94c7b..910b41100b8d0a92a1be452db3c26f772d80d9bc 100644 (file)
 #include "files.h"
 #include "getargs.h"
 
 #include "files.h"
 #include "getargs.h"
 
-/* The calling program should define program_name and set it to the
-   name of the executing program.  */
-extern char *program_name;
-
 bool complaint_issued;
 
 \f
 bool complaint_issued;
 
 \f
index eaa97c6bdb6a5e503a94c9da5ce6689cde5918c1..d90c466475c85d7d87cb926bf2a5bf73916fb997 100644 (file)
@@ -153,12 +153,20 @@ tr (char *s, char from, char to)
 static void
 compute_exts_from_gf (const char *ext)
 {
 static void
 compute_exts_from_gf (const char *ext)
 {
-  src_extension = xstrdup (ext);
-  header_extension = xstrdup (ext);
-  tr (src_extension, 'y', 'c');
-  tr (src_extension, 'Y', 'C');
-  tr (header_extension, 'y', 'h');
-  tr (header_extension, 'Y', 'H');
+  if (strcmp (ext, ".y") == 0)
+    {
+      src_extension = xstrdup (language->src_extension);
+      header_extension = xstrdup (language->header_extension);
+    }
+  else
+    {
+      src_extension = xstrdup (ext);
+      header_extension = xstrdup (ext);
+      tr (src_extension, 'y', 'c');
+      tr (src_extension, 'Y', 'C');
+      tr (header_extension, 'y', 'h');
+      tr (header_extension, 'Y', 'H');
+    }
 }
 
 /* Compute extensions from the given c source file extension.  */
 }
 
 /* Compute extensions from the given c source file extension.  */
@@ -281,7 +289,10 @@ compute_file_name_parts (void)
            xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
        }
 
            xstrndup (base, (strlen (base) - (ext ? strlen (ext) : 0)));
        }
 
-      all_but_ext = concat2 (all_but_tab_ext, TAB_EXT);
+      if (language->add_tab)
+        all_but_ext = concat2 (all_but_tab_ext, TAB_EXT);
+      else
+        all_but_ext = xstrdup (all_but_tab_ext);
 
       /* Compute the extensions from the grammar file name.  */
       if (ext && !yacc_flag)
 
       /* Compute the extensions from the grammar file name.  */
       if (ext && !yacc_flag)
index 563cc129dca2d9bcc36719d96b379b4c3d54ce76..7e7d8a93c9e4686d896068512726f4ad2a1923d9 100644 (file)
@@ -66,10 +66,19 @@ int report_flag = report_none;
 int trace_flag = trace_none;
 int warnings_flag = warnings_none;
 
 int trace_flag = trace_none;
 int warnings_flag = warnings_none;
 
+static struct bison_language const valid_languages[] = {
+  { "c", "c-skel.m4", ".c", ".h", true },
+  { "c++", "c++-skel.m4", ".cc", ".hh", true },
+  { "", "", "", "", false }
+};
+
+static int skeleton_prio = 2;
 const char *skeleton = NULL;
 const char *skeleton = NULL;
+static int language_prio = 2;
+struct bison_language const *language = &valid_languages[0];
 const char *include = NULL;
 
 const char *include = NULL;
 
-extern char *program_name;
+char *program_name;
 
 
 /** Decode an option's set of keys.
 
 
 /** Decode an option's set of keys.
@@ -323,12 +332,63 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 }
 
 
 }
 
 
+/*-------------------------------------.
+| --skeleton and --language handling.  |
+`--------------------------------------*/
+
+void
+skeleton_arg (char const *arg, int prio, location const *loc)
+{
+  if (prio < skeleton_prio)
+    {
+      skeleton_prio = prio;
+      skeleton = arg;
+    }
+  else if (prio == skeleton_prio)
+    {
+      char const *msg =
+       _("multiple skeleton declarations are invalid");
+      if (loc)
+       complain_at (*loc, msg);
+      else
+       complain (msg);
+    }
+}
+
+void
+language_argmatch (char const *arg, int prio, location const *loc)
+{
+  char const *msg;
+
+  if (prio < language_prio)
+    {
+      int i;
+      for (i = 0; valid_languages[i].language[0]; i++)
+       if (strcasecmp (arg, valid_languages[i].language) == 0)
+         {
+           language_prio = prio;
+           language = &valid_languages[i];
+           return;
+         }
+      msg = _("invalid language `%s'");
+    }
+  else if (language_prio == prio)
+    msg = _("multiple language declarations are invalid");
+  else
+    return;
+
+  if (loc)
+    complain_at (*loc, msg, arg);
+  else
+    complain (msg, arg);
+}
+
 /*----------------------.
 | Process the options.  |
 `----------------------*/
 
 /* Shorts options.  */
 /*----------------------.
 | Process the options.  |
 `----------------------*/
 
 /* Shorts options.  */
-static char const short_options[] = "yvegdhr:ltknVo:b:p:S:T::W";
+static char const short_options[] = "yvegdhr:L:ltknVo:b:p:S:T::W";
 
 /* Values for long options that do not have single-letter equivalents.  */
 enum
 
 /* Values for long options that do not have single-letter equivalents.  */
 enum
@@ -374,6 +434,7 @@ static struct option const long_options[] =
   { "no-parser",      no_argument,               0,   'n' },
   { "raw",            no_argument,               0,     0 },
   { "skeleton",       required_argument,         0,   'S' },
   { "no-parser",      no_argument,               0,   'n' },
   { "raw",            no_argument,               0,     0 },
   { "skeleton",       required_argument,         0,   'S' },
+  { "language",       required_argument,         0,   'L' },
   { "token-table",    no_argument,               0,   'k' },
 
   {0, 0, 0, 0}
   { "token-table",    no_argument,               0,   'k' },
 
   {0, 0, 0, 0}
@@ -414,8 +475,12 @@ getargs (int argc, char *argv[])
       case 'h':
        usage (EXIT_SUCCESS);
 
       case 'h':
        usage (EXIT_SUCCESS);
 
+      case 'L':
+       language_argmatch (optarg, 0, NULL);
+       break;
+
       case 'S':
       case 'S':
-       skeleton = AS_FILE_NAME (optarg);
+       skeleton_arg (AS_FILE_NAME (optarg), 0, NULL);
        break;
 
       case 'I':
        break;
 
       case 'I':
index a84a4857d259ec207d6bef314a136dfc2641dd61..523609df003c9d26a014bdea946cd1c8aa254253 100644 (file)
 #ifndef GETARGS_H_
 # define GETARGS_H_
 
 #ifndef GETARGS_H_
 # define GETARGS_H_
 
+#include "location.h"
+
+extern char *program_name;
+
 /* flags set by % directives */
 
 /* for -S */
 /* flags set by % directives */
 
 /* for -S */
@@ -65,6 +69,18 @@ extern bool push_parser;
 extern bool nondeterministic_parser;
 
 
 extern bool nondeterministic_parser;
 
 
+/* --language.  */
+struct bison_language
+{
+  char language[sizeof "c++"];
+  char skeleton[sizeof "c++-skel.m4"];
+  char src_extension[sizeof ".cc"];
+  char header_extension[sizeof ".hh"];
+  bool add_tab;
+};
+
+extern struct bison_language const *language;
+
 /*-----------.
 | --report.  |
 `-----------*/
 /*-----------.
 | --report.  |
 `-----------*/
@@ -126,4 +142,8 @@ extern int warnings_flag;
  */
 void getargs (int argc, char *argv[]);
 
  */
 void getargs (int argc, char *argv[]);
 
+/* Used by parse-gram.y.  */
+void language_argmatch (char const *arg, int prio, location const *loc);
+void skeleton_arg (const char *arg, int prio, location const *loc);
+
 #endif /* !GETARGS_H_ */
 #endif /* !GETARGS_H_ */
index a2056c82bac8854f3d4cc03e60a756b185742d92..610d2c4e46bdf2baf303dcd168b79588e5fcaa6c 100644 (file)
@@ -50,9 +50,6 @@
 #include "tables.h"
 #include "uniqstr.h"
 
 #include "tables.h"
 #include "uniqstr.h"
 
-/* The name this program was run with, for messages.  */
-char *program_name;
-
 
 
 int
 
 
 int
index 1e130dfc18a6713bdc42c8a8c2650b5aabf21f73..4608a2fa58b7110351e6188793cde039561f2860 100644 (file)
@@ -622,16 +622,13 @@ prepare (void)
   muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack));
   muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack));
 
   muscle_insert ("pre_prologue", obstack_finish (&pre_prologue_obstack));
   muscle_insert ("post_prologue", obstack_finish (&post_prologue_obstack));
 
-  /* Find the right skeleton file.  */
-  if (!skeleton)
-    {
-      if (glr_parser || nondeterministic_parser)
-       skeleton = "glr.c";
-      else
-       skeleton = "yacc.c";
-    }
+  /* Find the right skeleton file, and add muscles about the skeletons.  */
+  if (skeleton)
+    MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
+  else
+    skeleton = language->skeleton;
 
 
-  /* About the skeletons. */
+  /* About the skeletons.  */
   {
     char const *pkgdatadir = getenv ("BISON_PKGDATADIR");
     /* b4_pkgdatadir is used inside m4_include in the skeletons, so digraphs
   {
     char const *pkgdatadir = getenv ("BISON_PKGDATADIR");
     /* b4_pkgdatadir is used inside m4_include in the skeletons, so digraphs
@@ -639,7 +636,6 @@ prepare (void)
        his Bison installation path.  */
     MUSCLE_INSERT_STRING_RAW ("pkgdatadir",
                               pkgdatadir ? pkgdatadir : PKGDATADIR);
        his Bison installation path.  */
     MUSCLE_INSERT_STRING_RAW ("pkgdatadir",
                               pkgdatadir ? pkgdatadir : PKGDATADIR);
-    MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
   }
 }
 
   }
 }
 
index a753fa9a28b04ac93f7ca87048c055f5450d6a12..7680f462a1b4814207fe9b22ff4ee90c6da8a3c2 100644 (file)
@@ -143,6 +143,7 @@ static int current_prec = 0;
   PERCENT_FILE_PREFIX     "%file-prefix"
   PERCENT_GLR_PARSER      "%glr-parser"
   PERCENT_INITIAL_ACTION  "%initial-action"
   PERCENT_FILE_PREFIX     "%file-prefix"
   PERCENT_GLR_PARSER      "%glr-parser"
   PERCENT_INITIAL_ACTION  "%initial-action"
+  PERCENT_LANGUAGE        "%language"
   PERCENT_LEX_PARAM       "%lex-param"
   PERCENT_LOCATIONS       "%locations"
   PERCENT_NAME_PREFIX     "%name-prefix"
   PERCENT_LEX_PARAM       "%lex-param"
   PERCENT_LOCATIONS       "%locations"
   PERCENT_NAME_PREFIX     "%name-prefix"
@@ -245,6 +246,7 @@ prologue_declaration:
     {
       muscle_code_grow ("initial_action", translate_symbol_action ($2, @2), @2);
     }
     {
       muscle_code_grow ("initial_action", translate_symbol_action ($2, @2), @2);
     }
+| "%language" STRING           { language_argmatch ($2, 1, &@1); }
 | "%lex-param" "{...}"         { add_param ("lex_param", $2, @2); }
 | "%locations"                  { locations_flag = true; }
 | "%name-prefix" STRING         { spec_name_prefix = $2; }
 | "%lex-param" "{...}"         { add_param ("lex_param", $2, @2); }
 | "%locations"                  { locations_flag = true; }
 | "%name-prefix" STRING         { spec_name_prefix = $2; }
@@ -257,7 +259,7 @@ prologue_declaration:
 | "%pure-parser"                { pure_parser = true; }
 | "%push-parser"                { push_parser = true; pure_parser = true; }
 | "%require" STRING             { version_check (&@2, $2); }
 | "%pure-parser"                { pure_parser = true; }
 | "%push-parser"                { push_parser = true; pure_parser = true; }
 | "%require" STRING             { version_check (&@2, $2); }
-| "%skeleton" STRING            { skeleton = $2; }
+| "%skeleton" STRING            { skeleton_arg ($2, 1, &@1); }
 | "%token-table"                { token_table_flag = true; }
 | "%verbose"                    { report_flag = report_states; }
 | "%yacc"                       { yacc_flag = true; }
 | "%token-table"                { token_table_flag = true; }
 | "%verbose"                    { report_flag = report_states; }
 | "%yacc"                       { yacc_flag = true; }
index 55203a0930f2be99588b60068888b5624091bbd2..2f7516565f643fb5de1a79a19b12cbfc8780bfe4 100644 (file)
@@ -172,6 +172,7 @@ splice       (\\[ \f\t\v]*\n)*
   "%fixed"[-_]"output"[-_]"files"   return PERCENT_YACC;
   "%initial-action"                return PERCENT_INITIAL_ACTION;
   "%glr-parser"                    return PERCENT_GLR_PARSER;
   "%fixed"[-_]"output"[-_]"files"   return PERCENT_YACC;
   "%initial-action"                return PERCENT_INITIAL_ACTION;
   "%glr-parser"                    return PERCENT_GLR_PARSER;
+  "%language"                      return PERCENT_LANGUAGE;
   "%left"                          return PERCENT_LEFT;
   "%lex-param"                     return PERCENT_LEX_PARAM;
   "%locations"                     return PERCENT_LOCATIONS;
   "%left"                          return PERCENT_LEFT;
   "%lex-param"                     return PERCENT_LEX_PARAM;
   "%locations"                     return PERCENT_LOCATIONS;
index 4e67f035ea7b8c1d3cba91fd2da232ab57c3cf7e..64aac6cd0096be14e14e40cc1b521b0e2d0b15bb 100644 (file)
@@ -628,12 +628,15 @@ AT_CHECK_CALC_GLR([%pure-parser %error-verbose %debug %locations %defines %name-
 
 AT_BANNER([[Simple LALR(1) C++ Calculator.]])
 
 
 AT_BANNER([[Simple LALR(1) C++ Calculator.]])
 
+# First let's try using %skeleton
+AT_CHECK_CALC([%skeleton "lalr1.cc" %defines %locations])
+
 # AT_CHECK_CALC_LALR1_CC([BISON-OPTIONS])
 # ---------------------------------------
 # Start a testing chunk which compiles `calc' grammar with
 # the C++ skeleton, and performs several tests over the parser.
 m4_define([AT_CHECK_CALC_LALR1_CC],
 # AT_CHECK_CALC_LALR1_CC([BISON-OPTIONS])
 # ---------------------------------------
 # Start a testing chunk which compiles `calc' grammar with
 # the C++ skeleton, and performs several tests over the parser.
 m4_define([AT_CHECK_CALC_LALR1_CC],
-[AT_CHECK_CALC([%skeleton "lalr1.cc" %defines %locations] $@)])
+[AT_CHECK_CALC([%language "C++" %defines %locations] $@)])
 
 AT_CHECK_CALC_LALR1_CC([])
 AT_CHECK_CALC_LALR1_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
 
 AT_CHECK_CALC_LALR1_CC([])
 AT_CHECK_CALC_LALR1_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
@@ -652,12 +655,15 @@ AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %
 
 AT_BANNER([[Simple GLR C++ Calculator.]])
 
 
 AT_BANNER([[Simple GLR C++ Calculator.]])
 
+# Again, we try also using %skeleton.
+AT_CHECK_CALC([%skeleton "glr.cc" %defines %locations])
+
 # AT_CHECK_CALC_GLR_CC([BISON-OPTIONS])
 # -------------------------------------
 # Start a testing chunk which compiles `calc' grammar with
 # the GLR C++ skeleton, and performs several tests over the parser.
 m4_define([AT_CHECK_CALC_GLR_CC],
 # AT_CHECK_CALC_GLR_CC([BISON-OPTIONS])
 # -------------------------------------
 # Start a testing chunk which compiles `calc' grammar with
 # the GLR C++ skeleton, and performs several tests over the parser.
 m4_define([AT_CHECK_CALC_GLR_CC],
-[AT_CHECK_CALC([%skeleton "glr.cc" %defines %locations] $@)])
+[AT_CHECK_CALC([%language "C++" %glr-parser %defines %locations] $@)])
 
 AT_CHECK_CALC_GLR_CC([])
 AT_CHECK_CALC_GLR_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
 
 AT_CHECK_CALC_GLR_CC([])
 AT_CHECK_CALC_GLR_CC([%error-verbose %name-prefix "calc" %verbose %yacc])
index 10db01432f5c4236bd1e63f9e68347bf9bbde66b..3497c15d977d2a2e3e6cc81e67b92a3f2bb233a7 100644 (file)
@@ -41,17 +41,17 @@ m4_define([AT_BISON_OPTION_PUSHDEFS],
 m4_define([_AT_BISON_OPTION_PUSHDEFS],
 [m4_if([$1$2], $[1]$[2], [],
        [m4_fatal([$0: Invalid arguments: $@])])dnl
 m4_define([_AT_BISON_OPTION_PUSHDEFS],
 [m4_if([$1$2], $[1]$[2], [],
        [m4_fatal([$0: Invalid arguments: $@])])dnl
-m4_pushdef([AT_LALR1_CC_IF],
-[m4_bmatch([$3], ["lalr1.cc"], [$1], [$2])])
-m4_pushdef([AT_GLR_CC_IF],
-[m4_bmatch([$3], ["glr.cc"], [$1], [$2])])
 m4_pushdef([AT_SKEL_CC_IF],
 m4_pushdef([AT_SKEL_CC_IF],
-[m4_bmatch([$3], ["\(glr\|lalr1\).cc"], [$1], [$2])])
+[m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])])
 m4_pushdef([AT_GLR_IF],
 m4_pushdef([AT_GLR_IF],
-[m4_bmatch([$3], [%glr-parser], [$1], [$2])])
+[m4_bmatch([$3], [%glr-parser\|%skeleton "glr\.], [$1], [$2])])
+m4_pushdef([AT_LALR1_CC_IF],
+[AT_SKEL_CC_IF([AT_GLR_IF([$2], [$1])], [$2])])
+m4_pushdef([AT_GLR_CC_IF],
+[AT_SKEL_CC_IF([AT_GLR_IF([$1], [$2])], [$2])])
 # Using yacc.c?
 m4_pushdef([AT_YACC_IF],
 # Using yacc.c?
 m4_pushdef([AT_YACC_IF],
-[m4_bmatch([$3], [%glr-parser\|%skeleton], [$2], [$1])])
+[m4_bmatch([$3], [%language\|%glr-parser\|%skeleton], [$2], [$1])])
 m4_pushdef([AT_PARAM_IF],
 [m4_bmatch([$3], [%parse-param], [$1], [$2])])
 m4_pushdef([AT_LOCATION_IF],
 m4_pushdef([AT_PARAM_IF],
 [m4_bmatch([$3], [%parse-param], [$1], [$2])])
 m4_pushdef([AT_LOCATION_IF],