mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-19 17:23:02 +00:00
Merge branch 'maint'
* origin/maint: tests: check %no-lines tests: minor simplification graphs: stylistic changes. graphs: minor style changes graphs: show reductions graphs: style: prefix state number with "state" graphs: style: use left justification for states graphs: style: prefix rules and change shapes obstack: import obstack_finish0 from master c++: api.location.type muscles: a function for backward compatibility maint: more macros Conflicts: data/glr.cc data/java.m4 data/lalr1.cc doc/bison.texi src/muscle-tab.c src/system.h tests/calc.at
This commit is contained in:
15
NEWS
15
NEWS
@@ -301,6 +301,21 @@ GNU Bison NEWS
|
|||||||
"function declared 'noreturn' should not return") have also been
|
"function declared 'noreturn' should not return") have also been
|
||||||
addressed.
|
addressed.
|
||||||
|
|
||||||
|
** New %define variable: api.location.type (glr.cc, lalr1.cc)
|
||||||
|
|
||||||
|
The %define variable api.location.type defines the name of the type to use
|
||||||
|
for locations. When defined, Bison no longer generates the position.hh
|
||||||
|
and location.hh files, nor does the parser will include them: the user is
|
||||||
|
then responsible to define her type.
|
||||||
|
|
||||||
|
This can be used in programs with several parsers to factor their location
|
||||||
|
and position files: let one of them generate them, and the others just use
|
||||||
|
them.
|
||||||
|
|
||||||
|
This feature was actually introduced, but not documented, in Bison 2.5,
|
||||||
|
under the name "location_type" (which is maintained for backward
|
||||||
|
compatibility).
|
||||||
|
|
||||||
* Noteworthy changes in release 2.6.2 (2012-08-03) [stable]
|
* Noteworthy changes in release 2.6.2 (2012-08-03) [stable]
|
||||||
|
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ b4_percent_define_default([[parser_class_name]], [[parser]])
|
|||||||
# Don't do that so that we remember whether we're using a user
|
# Don't do that so that we remember whether we're using a user
|
||||||
# request, or the default value.
|
# request, or the default value.
|
||||||
#
|
#
|
||||||
# b4_percent_define_default([[location_type]], [[location]])
|
# b4_percent_define_default([[api.location.type]], [[location]])
|
||||||
|
|
||||||
b4_percent_define_default([[filename_type]], [[std::string]])
|
b4_percent_define_default([[filename_type]], [[std::string]])
|
||||||
b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
|
b4_percent_define_default([[api.namespace]], m4_defn([b4_prefix]))
|
||||||
@@ -130,7 +130,7 @@ m4_define([b4_public_types_declare],
|
|||||||
typedef ]b4_api_PREFIX[STYPE semantic_type;
|
typedef ]b4_api_PREFIX[STYPE semantic_type;
|
||||||
#endif]b4_locations_if([
|
#endif]b4_locations_if([
|
||||||
/// Symbol locations.
|
/// Symbol locations.
|
||||||
typedef b4_percent_define_get([[location_type]],
|
typedef b4_percent_define_get([[api.location.type]],
|
||||||
[[location]]) location_type;])[
|
[[location]]) location_type;])[
|
||||||
|
|
||||||
/// Syntax errors thrown from user actions.
|
/// Syntax errors thrown from user actions.
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
m4_define([b4_pure_flag], [1])
|
m4_define([b4_pure_flag], [1])
|
||||||
|
|
||||||
m4_include(b4_pkgdatadir/[c++.m4])
|
m4_include(b4_pkgdatadir/[c++.m4])
|
||||||
b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
|
b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
|
||||||
[m4_include(b4_pkgdatadir/[location.cc])])])
|
[m4_include(b4_pkgdatadir/[location.cc])])])
|
||||||
|
|
||||||
m4_define([b4_parser_class_name],
|
m4_define([b4_parser_class_name],
|
||||||
@@ -219,14 +219,14 @@ b4_percent_code_get([[requires]])[
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>]b4_defines_if([
|
#include <iostream>]b4_defines_if([
|
||||||
b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
|
b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
|
||||||
[[#include "location.hh"]])])])[
|
[[#include "location.hh"]])])])[
|
||||||
|
|
||||||
]b4_YYDEBUG_define[
|
]b4_YYDEBUG_define[
|
||||||
|
|
||||||
]b4_namespace_open[
|
]b4_namespace_open[
|
||||||
]b4_defines_if([],
|
]b4_defines_if([],
|
||||||
[b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
|
[b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
|
||||||
[b4_position_define
|
[b4_position_define
|
||||||
b4_location_define])])])[
|
b4_location_define])])])[
|
||||||
|
|
||||||
|
|||||||
@@ -197,8 +197,8 @@ m4_define([b4_throws], [b4_percent_define_get([[throws]])])
|
|||||||
b4_percent_define_default([[init_throws]], [])
|
b4_percent_define_default([[init_throws]], [])
|
||||||
m4_define([b4_init_throws], [b4_percent_define_get([[init_throws]])])
|
m4_define([b4_init_throws], [b4_percent_define_get([[init_throws]])])
|
||||||
|
|
||||||
b4_percent_define_default([[location_type]], [Location])
|
b4_percent_define_default([[api.location.type]], [Location])
|
||||||
m4_define([b4_location_type], [b4_percent_define_get([[location_type]])])
|
m4_define([b4_location_type], [b4_percent_define_get([[api.location.type]])])
|
||||||
|
|
||||||
b4_percent_define_default([[position_type]], [Position])
|
b4_percent_define_default([[position_type]], [Position])
|
||||||
m4_define([b4_position_type], [b4_percent_define_get([[position_type]])])
|
m4_define([b4_position_type], [b4_percent_define_get([[position_type]])])
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ m4_pushdef([b4_copyright_years],
|
|||||||
m4_define([b4_parser_class_name],
|
m4_define([b4_parser_class_name],
|
||||||
[b4_percent_define_get([[parser_class_name]])])
|
[b4_percent_define_get([[parser_class_name]])])
|
||||||
|
|
||||||
b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
|
b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
|
||||||
[# Backward compatibility.
|
[# Backward compatibility.
|
||||||
m4_define([b4_location_constructors])
|
m4_define([b4_location_constructors])
|
||||||
m4_include(b4_pkgdatadir/[location.cc])])])
|
m4_include(b4_pkgdatadir/[location.cc])])])
|
||||||
@@ -139,7 +139,7 @@ m4_define([b4_shared_declarations],
|
|||||||
# include <stdexcept>
|
# include <stdexcept>
|
||||||
# include <string>]b4_defines_if([[
|
# include <string>]b4_defines_if([[
|
||||||
# include "stack.hh"
|
# include "stack.hh"
|
||||||
]b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
|
]b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
|
||||||
[[# include "location.hh"]])])])[
|
[[# include "location.hh"]])])])[
|
||||||
|
|
||||||
]b4_YYDEBUG_define[
|
]b4_YYDEBUG_define[
|
||||||
@@ -148,7 +148,7 @@ m4_define([b4_shared_declarations],
|
|||||||
|
|
||||||
]b4_defines_if([],
|
]b4_defines_if([],
|
||||||
[b4_stack_define
|
[b4_stack_define
|
||||||
b4_locations_if([b4_percent_define_ifdef([[location_type]], [],
|
b4_locations_if([b4_percent_define_ifdef([[api.location.type]], [],
|
||||||
[b4_position_define
|
[b4_position_define
|
||||||
b4_location_define])])])[
|
b4_location_define])])])[
|
||||||
|
|
||||||
|
|||||||
@@ -331,6 +331,7 @@ C++ Location Values
|
|||||||
|
|
||||||
* C++ position:: One point in the source file
|
* C++ position:: One point in the source file
|
||||||
* C++ location:: Two points in the source file
|
* C++ location:: Two points in the source file
|
||||||
|
* User Defined Location Type:: Required interface for locations
|
||||||
|
|
||||||
A Complete C++ Example
|
A Complete C++ Example
|
||||||
|
|
||||||
@@ -5473,6 +5474,22 @@ The parser namespace is @code{foo} and @code{yylex} is referenced as
|
|||||||
@end itemize
|
@end itemize
|
||||||
@c namespace
|
@c namespace
|
||||||
|
|
||||||
|
@c ================================================== api.location.type
|
||||||
|
@item @code{api.location.type}
|
||||||
|
@findex %define api.location.type
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item Language(s): C++
|
||||||
|
|
||||||
|
@item Purpose: Define the location type.
|
||||||
|
@xref{User Defined Location Type}.
|
||||||
|
|
||||||
|
@item Accepted Values: String
|
||||||
|
|
||||||
|
@item Default Value: none
|
||||||
|
|
||||||
|
@item History: introduced in Bison 2.7
|
||||||
|
@end itemize
|
||||||
|
|
||||||
@c ================================================== api.prefix
|
@c ================================================== api.prefix
|
||||||
@item api.prefix
|
@item api.prefix
|
||||||
@@ -5481,7 +5498,7 @@ The parser namespace is @code{foo} and @code{yylex} is referenced as
|
|||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item Language(s): All
|
@item Language(s): All
|
||||||
|
|
||||||
@item Purpose: Rename exported symbols
|
@item Purpose: Rename exported symbols.
|
||||||
@xref{Multiple Parsers, ,Multiple Parsers in the Same Program}.
|
@xref{Multiple Parsers, ,Multiple Parsers in the Same Program}.
|
||||||
|
|
||||||
@item Accepted Values: String
|
@item Accepted Values: String
|
||||||
@@ -9564,8 +9581,10 @@ in the following files:
|
|||||||
@table @file
|
@table @file
|
||||||
@item position.hh
|
@item position.hh
|
||||||
@itemx location.hh
|
@itemx location.hh
|
||||||
The definition of the classes @code{position} and @code{location},
|
The definition of the classes @code{position} and @code{location}, used for
|
||||||
used for location tracking when enabled. @xref{C++ Location Values}.
|
location tracking when enabled. These files are not generated if the
|
||||||
|
@code{%define} variable @code{api.location.type} is defined. @xref{C++
|
||||||
|
Location Values}.
|
||||||
|
|
||||||
@item stack.hh
|
@item stack.hh
|
||||||
An auxiliary class @code{stack} used by the parser.
|
An auxiliary class @code{stack} used by the parser.
|
||||||
@@ -9724,10 +9743,13 @@ is some time and/or some talented C++ hacker willing to contribute to Bison.
|
|||||||
@c - %define filename_type "const symbol::Symbol"
|
@c - %define filename_type "const symbol::Symbol"
|
||||||
|
|
||||||
When the directive @code{%locations} is used, the C++ parser supports
|
When the directive @code{%locations} is used, the C++ parser supports
|
||||||
location tracking, see @ref{Tracking Locations}. Two auxiliary classes
|
location tracking, see @ref{Tracking Locations}.
|
||||||
define a @code{position}, a single point in a file, and a @code{location}, a
|
|
||||||
range composed of a pair of @code{position}s (possibly spanning several
|
By default, two auxiliary classes define a @code{position}, a single point
|
||||||
files).
|
in a file, and a @code{location}, a range composed of a pair of
|
||||||
|
@code{position}s (possibly spanning several files). But if the
|
||||||
|
@code{%define} variable @code{api.location.type} is defined, then these
|
||||||
|
classes will not be generated, and the user defined type will be used.
|
||||||
|
|
||||||
@tindex uint
|
@tindex uint
|
||||||
In this section @code{uint} is an abbreviation for @code{unsigned int}: in
|
In this section @code{uint} is an abbreviation for @code{unsigned int}: in
|
||||||
@@ -9736,6 +9758,7 @@ genuine code only the latter is used.
|
|||||||
@menu
|
@menu
|
||||||
* C++ position:: One point in the source file
|
* C++ position:: One point in the source file
|
||||||
* C++ location:: Two points in the source file
|
* C++ location:: Two points in the source file
|
||||||
|
* User Defined Location Type:: Required interface for locations
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node C++ position
|
@node C++ position
|
||||||
@@ -9839,6 +9862,63 @@ Report @var{p} on @var{o}, taking care of special cases such as: no
|
|||||||
@code{filename} defined, or equal filename/line or column.
|
@code{filename} defined, or equal filename/line or column.
|
||||||
@end deftypefun
|
@end deftypefun
|
||||||
|
|
||||||
|
@node User Defined Location Type
|
||||||
|
@subsubsection User Defined Location Type
|
||||||
|
@findex %define api.location.type
|
||||||
|
|
||||||
|
Instead of using the built-in types you may use the @code{%define} variable
|
||||||
|
@code{api.location.type} to specify your own type:
|
||||||
|
|
||||||
|
@example
|
||||||
|
%define api.location.type @var{LocationType}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The requirements over your @var{LocationType} are:
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
it must be copyable;
|
||||||
|
|
||||||
|
@item
|
||||||
|
in order to compute the (default) value of @code{@@$} in a reduction, the
|
||||||
|
parser basically runs
|
||||||
|
@example
|
||||||
|
@@$.begin = @@$1.begin;
|
||||||
|
@@$.end = @@$@var{N}.end; // The location of last right-hand side symbol.
|
||||||
|
@end example
|
||||||
|
@noindent
|
||||||
|
so there must be copyable @code{begin} and @code{end} members;
|
||||||
|
|
||||||
|
@item
|
||||||
|
alternatively you may redefine the computation of the default location, in
|
||||||
|
which case these members are not required (@pxref{Location Default Action});
|
||||||
|
|
||||||
|
@item
|
||||||
|
if traces are enabled, then there must exist an @samp{std::ostream&
|
||||||
|
operator<< (std::ostream& o, const @var{LocationType}& s)} function.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@sp 1
|
||||||
|
|
||||||
|
In programs with several C++ parsers, you may also use the @code{%define}
|
||||||
|
variable @code{api.location.type} to share a common set of built-in
|
||||||
|
definitions for @code{position} and @code{location}. For instance, one
|
||||||
|
parser @file{master/parser.yy} might use:
|
||||||
|
|
||||||
|
@example
|
||||||
|
%defines
|
||||||
|
%locations
|
||||||
|
%define namespace "master::"
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
to generate the @file{master/position.hh} and @file{master/location.hh}
|
||||||
|
files, reused by other parsers as follows:
|
||||||
|
|
||||||
|
@example
|
||||||
|
%define location_type "master::location"
|
||||||
|
%code requires @{ #include <master/location.hh> @}
|
||||||
|
@end example
|
||||||
|
|
||||||
@node C++ Parser Interface
|
@node C++ Parser Interface
|
||||||
@subsection C++ Parser Interface
|
@subsection C++ Parser Interface
|
||||||
@c - define parser_class_name
|
@c - define parser_class_name
|
||||||
|
|||||||
@@ -25,12 +25,14 @@
|
|||||||
#include <quotearg.h>
|
#include <quotearg.h>
|
||||||
|
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
|
#include "gram.h"
|
||||||
#include "graphviz.h"
|
#include "graphviz.h"
|
||||||
|
#include "tables.h"
|
||||||
|
|
||||||
/* Return an unambiguous printable representation for NAME, suitable
|
/* Return an unambiguous printable representation for NAME, suitable
|
||||||
for C strings. Use slot 2 since the user may use slots 0 and 1. */
|
for C strings. Use slot 2 since the user may use slots 0 and 1. */
|
||||||
|
|
||||||
static char const *
|
static char *
|
||||||
quote (char const *name)
|
quote (char const *name)
|
||||||
{
|
{
|
||||||
return quotearg_n_style (2, c_quoting_style, name);
|
return quotearg_n_style (2, c_quoting_style, name);
|
||||||
@@ -51,12 +53,13 @@ start_graph (FILE *fout)
|
|||||||
"digraph %s\n"
|
"digraph %s\n"
|
||||||
"{\n",
|
"{\n",
|
||||||
quote (grammar_file));
|
quote (grammar_file));
|
||||||
|
fprintf (fout, "node [shape=box]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
output_node (int id, char const *label, FILE *fout)
|
output_node (int id, char const *label, FILE *fout)
|
||||||
{
|
{
|
||||||
fprintf (fout, " %d [label=%s]\n", id, quote (label));
|
fprintf (fout, " %d [label=\"%s\"]\n", id, label);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -69,6 +72,98 @@ output_edge (int source, int destination, char const *label,
|
|||||||
fputs ("]\n", fout);
|
fputs ("]\n", fout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char const *
|
||||||
|
escape (char const *name)
|
||||||
|
{
|
||||||
|
char *q = quote (name);
|
||||||
|
q[strlen (q) - 1] = '\0';
|
||||||
|
return q + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
no_reduce_bitset_init (state const *s, bitset *no_reduce_set)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
*no_reduce_set = bitset_create (ntokens, BITSET_FIXED);
|
||||||
|
bitset_zero (*no_reduce_set);
|
||||||
|
FOR_EACH_SHIFT (s->transitions, n)
|
||||||
|
bitset_set (*no_reduce_set, TRANSITION_SYMBOL (s->transitions, n));
|
||||||
|
for (n = 0; n < s->errs->num; ++n)
|
||||||
|
if (s->errs->symbols[n])
|
||||||
|
bitset_set (*no_reduce_set, s->errs->symbols[n]->number);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
print_token (struct obstack *out, bool first, char const *tok)
|
||||||
|
{
|
||||||
|
char const *q = escape (tok);
|
||||||
|
|
||||||
|
if (! first)
|
||||||
|
obstack_sgrow (out, ",");
|
||||||
|
obstack_sgrow (out, q);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
output_red (state const *s, reductions const *reds, FILE *fout)
|
||||||
|
{
|
||||||
|
bitset no_reduce_set;
|
||||||
|
int j;
|
||||||
|
int source = s->number;
|
||||||
|
struct obstack oout;
|
||||||
|
|
||||||
|
no_reduce_bitset_init (s, &no_reduce_set);
|
||||||
|
obstack_init (&oout);
|
||||||
|
|
||||||
|
for (j = 0; j < reds->num; ++j)
|
||||||
|
{
|
||||||
|
bool disabled = false;
|
||||||
|
bool first = true;
|
||||||
|
int ruleno = reds->rules[j]->user_number;
|
||||||
|
rule *default_reduction = NULL;
|
||||||
|
|
||||||
|
if (yydefact[s->number] != 0)
|
||||||
|
default_reduction = &rules[yydefact[s->number] - 1];
|
||||||
|
|
||||||
|
/* First, print the edges that represent each possible reduction for
|
||||||
|
the given state. */
|
||||||
|
obstack_printf (&oout, " %1$d -> \"%1$dR%2$d\" [label=\"",
|
||||||
|
source, ruleno);
|
||||||
|
if (default_reduction && default_reduction == reds->rules[j])
|
||||||
|
first = print_token (&oout, true, "$default");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ntokens; i++)
|
||||||
|
if (bitset_test (reds->lookahead_tokens[j], i))
|
||||||
|
{
|
||||||
|
first = print_token (&oout, first, symbols[i]->tag);
|
||||||
|
if (bitset_test (no_reduce_set, i))
|
||||||
|
disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obstack_sgrow (&oout, "\" style=solid]\n");
|
||||||
|
|
||||||
|
/* Then, print the reduction's representation. Done later since
|
||||||
|
we need to know whether this reduction is disabled. */
|
||||||
|
obstack_printf (&oout,
|
||||||
|
" \"%dR%d\" "
|
||||||
|
"[style=filled shape=diamond fillcolor=%s "
|
||||||
|
"label=\"R%d\"]\n",
|
||||||
|
source, ruleno,
|
||||||
|
disabled ? "firebrick1" : "yellowgreen",
|
||||||
|
ruleno);
|
||||||
|
|
||||||
|
/* If no lookahead tokens were valid transitions, this reduction is
|
||||||
|
actually disabled, so don't print it. */
|
||||||
|
if (first)
|
||||||
|
(void) obstack_finish0 (&oout);
|
||||||
|
else
|
||||||
|
fprintf (fout, obstack_finish0 (&oout));
|
||||||
|
}
|
||||||
|
obstack_free (&oout, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
finish_graph (FILE *fout)
|
finish_graph (FILE *fout)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#ifndef GRAPHVIZ_H_
|
#ifndef GRAPHVIZ_H_
|
||||||
# define GRAPHVIZ_H_
|
# define GRAPHVIZ_H_
|
||||||
|
|
||||||
|
#include "state.h"
|
||||||
|
|
||||||
/// Begin a Dot graph.
|
/// Begin a Dot graph.
|
||||||
/// \param fout output stream.
|
/// \param fout output stream.
|
||||||
void start_graph (FILE *fout);
|
void start_graph (FILE *fout);
|
||||||
@@ -42,8 +44,18 @@ void output_node (int id, char const *label, FILE *fout);
|
|||||||
void output_edge (int source, int destination, char const *label,
|
void output_edge (int source, int destination, char const *label,
|
||||||
char const *style, FILE *fout);
|
char const *style, FILE *fout);
|
||||||
|
|
||||||
|
/// Output a reduction.
|
||||||
|
/// \param s current state
|
||||||
|
/// \param reds the set of reductions
|
||||||
|
/// \param fout output stream.
|
||||||
|
void output_red (state const *s, reductions const *reds, FILE *fout);
|
||||||
|
|
||||||
/// End a Dot graph.
|
/// End a Dot graph.
|
||||||
/// \param fout output stream.
|
/// \param fout output stream.
|
||||||
void finish_graph (FILE *fout);
|
void finish_graph (FILE *fout);
|
||||||
|
|
||||||
|
/// Escape a lookahead token.
|
||||||
|
/// \param name the token.
|
||||||
|
char const *escape (char const *name);
|
||||||
|
|
||||||
#endif /* ! GRAPHVIZ_H_ */
|
#endif /* ! GRAPHVIZ_H_ */
|
||||||
|
|||||||
@@ -398,6 +398,7 @@ muscle_percent_variable_update (char const *variable, location variable_loc)
|
|||||||
const conversion_type conversion[] =
|
const conversion_type conversion[] =
|
||||||
{
|
{
|
||||||
{ "api.push_pull", "api.push-pull", },
|
{ "api.push_pull", "api.push-pull", },
|
||||||
|
{ "location_type", "api.location.type", },
|
||||||
{ "lr.keep_unreachable_states", "lr.keep-unreachable-states", },
|
{ "lr.keep_unreachable_states", "lr.keep-unreachable-states", },
|
||||||
{ "namespace", "api.namespace", },
|
{ "namespace", "api.namespace", },
|
||||||
};
|
};
|
||||||
@@ -416,23 +417,17 @@ muscle_percent_variable_update (char const *variable, location variable_loc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
muscle_percent_define_insert (char const *variable, location variable_loc,
|
muscle_percent_define_insert (char const *var, location variable_loc,
|
||||||
char const *value,
|
char const *value,
|
||||||
muscle_percent_define_how how)
|
muscle_percent_define_how how)
|
||||||
{
|
{
|
||||||
char const *name;
|
/* Backward compatibility. */
|
||||||
char const *loc_name;
|
char const *variable = muscle_percent_variable_update (var, variable_loc);
|
||||||
char const *syncline_name;
|
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
|
||||||
char const *how_name;
|
char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
|
||||||
|
char const *syncline_name =
|
||||||
/* Permit certain names with underscores for backward compatibility. */
|
|
||||||
variable = muscle_percent_variable_update (variable, variable_loc);
|
|
||||||
|
|
||||||
name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
|
|
||||||
loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
|
|
||||||
syncline_name =
|
|
||||||
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
|
UNIQSTR_CONCAT ("percent_define_syncline(", variable, ")");
|
||||||
how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
|
char const *how_name = UNIQSTR_CONCAT ("percent_define_how(", variable, ")");
|
||||||
|
|
||||||
/* Command-line options are processed before the grammar file. */
|
/* Command-line options are processed before the grammar file. */
|
||||||
if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
|
if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <quotearg.h>
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
#include "LR0.h"
|
#include "LR0.h"
|
||||||
@@ -54,7 +55,7 @@ print_core (struct obstack *oout, state *s)
|
|||||||
snritems = nitemset;
|
snritems = nitemset;
|
||||||
}
|
}
|
||||||
|
|
||||||
obstack_printf (oout, "%d", s->number);
|
obstack_printf (oout, "state %d\\n", s->number);
|
||||||
for (i = 0; i < snritems; i++)
|
for (i = 0; i < snritems; i++)
|
||||||
{
|
{
|
||||||
item_number *sp;
|
item_number *sp;
|
||||||
@@ -68,15 +69,15 @@ print_core (struct obstack *oout, state *s)
|
|||||||
|
|
||||||
r = item_number_as_rule_number (*sp);
|
r = item_number_as_rule_number (*sp);
|
||||||
|
|
||||||
obstack_printf (oout, "\n%s -> ", rules[r].lhs->tag);
|
obstack_printf (oout, "%d: %s -> ", r, escape (rules[r].lhs->tag));
|
||||||
|
|
||||||
for (sp = rules[r].rhs; sp < sp1; sp++)
|
for (sp = rules[r].rhs; sp < sp1; sp++)
|
||||||
obstack_printf (oout, "%s ", symbols[*sp]->tag);
|
obstack_printf (oout, "%s ", escape (symbols[*sp]->tag));
|
||||||
|
|
||||||
obstack_1grow (oout, '.');
|
obstack_1grow (oout, '.');
|
||||||
|
|
||||||
for (/* Nothing */; *sp >= 0; ++sp)
|
for (/* Nothing */; *sp >= 0; ++sp)
|
||||||
obstack_printf (oout, " %s", symbols[*sp]->tag);
|
obstack_printf (oout, " %s", escape (symbols[*sp]->tag));
|
||||||
|
|
||||||
/* Experimental feature: display the lookahead tokens. */
|
/* Experimental feature: display the lookahead tokens. */
|
||||||
if (report_flag & report_lookahead_tokens
|
if (report_flag & report_lookahead_tokens
|
||||||
@@ -92,15 +93,17 @@ print_core (struct obstack *oout, state *s)
|
|||||||
bitset_iterator biter;
|
bitset_iterator biter;
|
||||||
int k;
|
int k;
|
||||||
char const *sep = "";
|
char const *sep = "";
|
||||||
obstack_sgrow (oout, "[");
|
obstack_1grow (oout, '[');
|
||||||
BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0)
|
BITSET_FOR_EACH (biter, reds->lookahead_tokens[redno], k, 0)
|
||||||
{
|
{
|
||||||
obstack_printf (oout, "%s%s", sep, symbols[k]->tag);
|
obstack_sgrow (oout, sep);
|
||||||
|
obstack_sgrow (oout, escape (symbols[k]->tag));
|
||||||
sep = ", ";
|
sep = ", ";
|
||||||
}
|
}
|
||||||
obstack_sgrow (oout, "]");
|
obstack_1grow (oout, ']');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
obstack_sgrow (oout, "\\l");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,6 +120,9 @@ print_actions (state const *s, FILE *fgraph)
|
|||||||
|
|
||||||
transitions const *trans = s->transitions;
|
transitions const *trans = s->transitions;
|
||||||
|
|
||||||
|
/* Display reductions. */
|
||||||
|
output_red (s, s->reductions, fgraph);
|
||||||
|
|
||||||
if (!trans->num && !s->reductions)
|
if (!trans->num && !s->reductions)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,10 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
|
||||||
|
#define STREQ(L, R) (strcmp(L, R) == 0)
|
||||||
|
#define STRNEQ(L, R) (!STREQ(L, R))
|
||||||
|
|
||||||
#ifndef UINTPTR_MAX
|
#ifndef UINTPTR_MAX
|
||||||
/* This isn't perfect, but it's good enough for Bison, which needs
|
/* This isn't perfect, but it's good enough for Bison, which needs
|
||||||
only to hash pointers. */
|
only to hash pointers. */
|
||||||
@@ -220,8 +224,6 @@ typedef size_t uintptr_t;
|
|||||||
(obstack_1grow (Obs, '\0'), (char *) obstack_finish (Obs))
|
(obstack_1grow (Obs, '\0'), (char *) obstack_finish (Obs))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------.
|
/*-----------------------------------------.
|
||||||
| Extensions to use for the output files. |
|
| Extensions to use for the output files. |
|
||||||
`-----------------------------------------*/
|
`-----------------------------------------*/
|
||||||
|
|||||||
@@ -716,7 +716,7 @@ m4_define([AT_CHECK_CALC_LALR1_CC],
|
|||||||
|
|
||||||
AT_CHECK_CALC_LALR1_CC([])
|
AT_CHECK_CALC_LALR1_CC([])
|
||||||
AT_CHECK_CALC_LALR1_CC([%locations])
|
AT_CHECK_CALC_LALR1_CC([%locations])
|
||||||
AT_CHECK_CALC_LALR1_CC([%locations %define location_type Span])
|
AT_CHECK_CALC_LALR1_CC([%locations %define api.location.type Span])
|
||||||
AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %name-prefix "calc" %verbose %yacc])
|
AT_CHECK_CALC_LALR1_CC([%defines %locations %define parse.error verbose %name-prefix "calc" %verbose %yacc])
|
||||||
|
|
||||||
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %define api.prefix "calc" %verbose %yacc])
|
AT_CHECK_CALC_LALR1_CC([%locations %define parse.error verbose %define api.prefix "calc" %verbose %yacc])
|
||||||
@@ -750,7 +750,7 @@ m4_define([AT_CHECK_CALC_GLR_CC],
|
|||||||
|
|
||||||
AT_CHECK_CALC_GLR_CC([])
|
AT_CHECK_CALC_GLR_CC([])
|
||||||
AT_CHECK_CALC_GLR_CC([%locations])
|
AT_CHECK_CALC_GLR_CC([%locations])
|
||||||
AT_CHECK_CALC_GLR_CC([%locations %define location_type Span])
|
AT_CHECK_CALC_GLR_CC([%locations %define api.location.type Span])
|
||||||
AT_CHECK_CALC_GLR_CC([%defines %define parse.error verbose %name-prefix "calc" %verbose %yacc])
|
AT_CHECK_CALC_GLR_CC([%defines %define parse.error verbose %name-prefix "calc" %verbose %yacc])
|
||||||
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %define api.prefix "calc" %verbose %yacc])
|
AT_CHECK_CALC_GLR_CC([%define parse.error verbose %define api.prefix "calc" %verbose %yacc])
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ AT_SETUP([Several parsers])
|
|||||||
# self-contained, and can be compiled by a C++ compiler.
|
# self-contained, and can be compiled by a C++ compiler.
|
||||||
m4_pushdef([AT_TEST],
|
m4_pushdef([AT_TEST],
|
||||||
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix "$1_" $2])
|
[AT_BISON_OPTION_PUSHDEFS([%define api.prefix "$1_" $2])
|
||||||
AT_DATA_GRAMMAR([$1.AT_SKEL_CC_IF([yy], [y])],
|
AT_DATA_GRAMMAR([$1.y],
|
||||||
[[%define api.prefix "$1_"
|
[[%define api.prefix "$1_"
|
||||||
$2
|
$2
|
||||||
%error-verbose
|
%error-verbose
|
||||||
@@ -161,7 +161,7 @@ exp:
|
|||||||
]AT_YYLEX_DEFINE(["$1"])[
|
]AT_YYLEX_DEFINE(["$1"])[
|
||||||
]])
|
]])
|
||||||
|
|
||||||
AT_BISON_CHECK([-d -o AT_SKEL_CC_IF([$1.cc $1.yy], [$1.c $1.y])])
|
AT_BISON_CHECK([-d -o $1.AT_SKEL_CC_IF([cc], [c]) $1.y])
|
||||||
|
|
||||||
# Check there is no 'yy' left.
|
# Check there is no 'yy' left.
|
||||||
# C++ output relies on namespaces and still uses yy a lot.
|
# C++ output relies on namespaces and still uses yy a lot.
|
||||||
|
|||||||
@@ -751,7 +751,7 @@ AT_SETUP([Java stype, position_class and location_class])
|
|||||||
AT_CHECK_JAVA_MINIMAL([[
|
AT_CHECK_JAVA_MINIMAL([[
|
||||||
%define stype "java.awt.Color"
|
%define stype "java.awt.Color"
|
||||||
%type<java.awt.Color> start;
|
%type<java.awt.Color> start;
|
||||||
%define location_type "MyLoc"
|
%define api.location.type "MyLoc"
|
||||||
%define position_type "MyPos"
|
%define position_type "MyPos"
|
||||||
%code { class MyPos {} }]], [[$$ = $<java.awt.Color>1;]], [[MyPos]])
|
%code { class MyPos {} }]], [[$$ = $<java.awt.Color>1;]], [[MyPos]])
|
||||||
AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore])
|
AT_CHECK([[grep 'java.awt.Color' YYParser.java]], [0], [ignore])
|
||||||
@@ -761,7 +761,7 @@ AT_CHECK([[$EGREP -v ' */?\*' YYParser.java | grep 'Location']], [1], [ignore])
|
|||||||
AT_CHECK_JAVA_MINIMAL_W_LEXER([[
|
AT_CHECK_JAVA_MINIMAL_W_LEXER([[
|
||||||
%define stype "java.awt.Color"
|
%define stype "java.awt.Color"
|
||||||
%type<java.awt.Color> start;
|
%type<java.awt.Color> start;
|
||||||
%define location_type "MyLoc"
|
%define api.location.type "MyLoc"
|
||||||
%define position_type "MyPos"
|
%define position_type "MyPos"
|
||||||
%code { class MyPos {} }]], [], [[return EOF;]], [],
|
%code { class MyPos {} }]], [], [[return EOF;]], [],
|
||||||
[[$$ = $<java.awt.Color>1;]],
|
[[$$ = $<java.awt.Color>1;]],
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ m4_pushdef([AT_LEXPARAM_IF],
|
|||||||
m4_pushdef([AT_LOCATION_IF],
|
m4_pushdef([AT_LOCATION_IF],
|
||||||
[m4_bmatch([$3], [%locations], [$1], [$2])])
|
[m4_bmatch([$3], [%locations], [$1], [$2])])
|
||||||
m4_pushdef([AT_LOCATION_TYPE_IF],
|
m4_pushdef([AT_LOCATION_TYPE_IF],
|
||||||
[m4_bmatch([$3], [%define location_type], [$1], [$2])])
|
[m4_bmatch([$3], [%define \(api\.location\.type\|location_type\)], [$1], [$2])])
|
||||||
m4_pushdef([AT_PARAM_IF],
|
m4_pushdef([AT_PARAM_IF],
|
||||||
[m4_bmatch([$3], [%parse-param], [$1], [$2])])
|
[m4_bmatch([$3], [%parse-param], [$1], [$2])])
|
||||||
m4_pushdef([AT_PURE_IF],
|
m4_pushdef([AT_PURE_IF],
|
||||||
|
|||||||
@@ -216,4 +216,54 @@ exp: '0';
|
|||||||
[input.y:8: #error "8"
|
[input.y:8: #error "8"
|
||||||
])
|
])
|
||||||
|
|
||||||
|
## -------------------- ##
|
||||||
|
## %code top syncline. ##
|
||||||
|
## -------------------- ##
|
||||||
|
|
||||||
|
AT_TEST([%code top syncline],
|
||||||
|
[[%code top {
|
||||||
|
#error "2"
|
||||||
|
}
|
||||||
|
%{
|
||||||
|
]AT_YYERROR_DECLARE_EXTERN[
|
||||||
|
]AT_YYLEX_DECLARE_EXTERN[
|
||||||
|
%}
|
||||||
|
%%
|
||||||
|
exp: '0';
|
||||||
|
%%
|
||||||
|
]],
|
||||||
|
[input.y:2: #error "2"
|
||||||
|
])
|
||||||
|
|
||||||
|
m4_popdef([AT_TEST])
|
||||||
|
|
||||||
|
## ----------- ##
|
||||||
|
## %no-lines. ##
|
||||||
|
## ----------- ##
|
||||||
|
|
||||||
|
m4_pushdef([AT_TEST],
|
||||||
|
[AT_SETUP([%no-lines])
|
||||||
|
|
||||||
|
AT_BISON_OPTION_PUSHDEFS([%skeleton "$1" %defines])
|
||||||
|
AT_DATA_GRAMMAR([input.y],
|
||||||
|
[%skeleton "$1" %defines
|
||||||
|
%{
|
||||||
|
]AT_YYERROR_DECLARE_EXTERN[
|
||||||
|
]AT_YYLEX_DECLARE_EXTERN[
|
||||||
|
%}
|
||||||
|
%%
|
||||||
|
exp: '0'
|
||||||
|
])
|
||||||
|
AT_BISON_CHECK([--no-lines -o input.AT_SKEL_CC_IF([cc], [c]) -d input.y])
|
||||||
|
AT_CHECK([[grep '#line' ]AT_SKEL_CC_IF([*.cc *.hh], [*.c *.h])], 1)
|
||||||
|
AT_BISON_OPTION_POPDEFS
|
||||||
|
|
||||||
|
AT_CLEANUP
|
||||||
|
])
|
||||||
|
|
||||||
|
AT_TEST([yacc.c])
|
||||||
|
AT_TEST([glr.c])
|
||||||
|
AT_TEST([lalr1.cc])
|
||||||
|
AT_TEST([glr.cc])
|
||||||
|
|
||||||
m4_popdef([AT_TEST])
|
m4_popdef([AT_TEST])
|
||||||
|
|||||||
Reference in New Issue
Block a user