* 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>
This commit is contained in:
Paul Eggert
2006-12-19 00:34:37 +00:00
parent db06f0ce72
commit 0e021770cc
19 changed files with 287 additions and 51 deletions

View File

@@ -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',

5
NEWS
View File

@@ -6,6 +6,11 @@ Changes in version 2.3a+ (????-??-??):
* 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:

View File

@@ -16,8 +16,8 @@
## 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

29
data/c++-skel.m4 Normal file
View File

@@ -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)

28
data/c-skel.m4 Normal file
View File

@@ -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)

View File

@@ -21,6 +21,9 @@ m4_divert(-1) -*- C -*-
m4_include(b4_pkgdatadir/[c.m4])
b4_push_if([
m4_fatal([Non-deterministic push parsers are not yet supported])])
## ---------------- ##
## Default values. ##
## ---------------- ##

View 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
@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
@@ -4681,6 +4686,11 @@ Require version @var{version} or higher of Bison. @xref{Require Decl, ,
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
@@ -7262,8 +7272,9 @@ Tuning the parser:
@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
@@ -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}.
@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}.
@@ -7433,14 +7450,24 @@ int yyparse (void);
@node C++ Bison Interface
@subsection C++ Bison Interface
@c - %skeleton "lalr1.cc"
@c - %language "C++"
@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:
@@ -7828,8 +7855,8 @@ the grammar for.
@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

View File

@@ -35,8 +35,8 @@ extexi = $(top_srcdir)/examples/extexi
# 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

View File

@@ -111,6 +111,7 @@ function normalize(contents, i, lines, n, line, res) {
else
line = "";
gsub (/^%require "[^"]*"$/, "%require \"" VERSION "\"", line);
gsub (/^@result\{\}/, "", line);
gsub (/^@error\{\}/, "", line);
gsub ("@[{]", "{", line);

View File

@@ -30,10 +30,6 @@
#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;

View File

@@ -153,12 +153,20 @@ tr (char *s, char from, char to)
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. */
@@ -281,7 +289,10 @@ compute_file_name_parts (void)
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)

View File

@@ -66,10 +66,19 @@ int report_flag = report_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;
static int language_prio = 2;
struct bison_language const *language = &valid_languages[0];
const char *include = NULL;
extern char *program_name;
char *program_name;
/** 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. */
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
@@ -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' },
{ "language", required_argument, 0, 'L' },
{ "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 'L':
language_argmatch (optarg, 0, NULL);
break;
case 'S':
skeleton = AS_FILE_NAME (optarg);
skeleton_arg (AS_FILE_NAME (optarg), 0, NULL);
break;
case 'I':

View File

@@ -22,6 +22,10 @@
#ifndef GETARGS_H_
# define GETARGS_H_
#include "location.h"
extern char *program_name;
/* flags set by % directives */
/* for -S */
@@ -65,6 +69,18 @@ extern bool push_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. |
`-----------*/
@@ -126,4 +142,8 @@ extern int warnings_flag;
*/
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_ */

View File

@@ -50,9 +50,6 @@
#include "tables.h"
#include "uniqstr.h"
/* The name this program was run with, for messages. */
char *program_name;
int

View 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));
/* 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
@@ -639,7 +636,6 @@ prepare (void)
his Bison installation path. */
MUSCLE_INSERT_STRING_RAW ("pkgdatadir",
pkgdatadir ? pkgdatadir : PKGDATADIR);
MUSCLE_INSERT_C_STRING ("skeleton", skeleton);
}
}

View 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_LANGUAGE "%language"
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);
}
| "%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; }
@@ -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); }
| "%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; }

View 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;
"%language" return PERCENT_LANGUAGE;
"%left" return PERCENT_LEFT;
"%lex-param" return PERCENT_LEX_PARAM;
"%locations" return PERCENT_LOCATIONS;

View File

@@ -628,12 +628,15 @@ AT_CHECK_CALC_GLR([%pure-parser %error-verbose %debug %locations %defines %name-
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([%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])
@@ -652,12 +655,15 @@ AT_CHECK_CALC_LALR1_CC([%pure-parser %error-verbose %debug %name-prefix "calc" %
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([%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])

View 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_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_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_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],
[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],