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:
Akim Demaille
2012-10-12 12:39:52 +02:00
16 changed files with 303 additions and 48 deletions

View File

@@ -25,12 +25,14 @@
#include <quotearg.h>
#include "files.h"
#include "gram.h"
#include "graphviz.h"
#include "tables.h"
/* Return an unambiguous printable representation for NAME, suitable
for C strings. Use slot 2 since the user may use slots 0 and 1. */
static char const *
static char *
quote (char const *name)
{
return quotearg_n_style (2, c_quoting_style, name);
@@ -51,12 +53,13 @@ start_graph (FILE *fout)
"digraph %s\n"
"{\n",
quote (grammar_file));
fprintf (fout, "node [shape=box]\n");
}
void
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
@@ -69,6 +72,98 @@ output_edge (int source, int destination, char const *label,
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
finish_graph (FILE *fout)
{

View File

@@ -22,6 +22,8 @@
#ifndef GRAPHVIZ_H_
# define GRAPHVIZ_H_
#include "state.h"
/// Begin a Dot graph.
/// \param fout output stream.
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,
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.
/// \param fout output stream.
void finish_graph (FILE *fout);
/// Escape a lookahead token.
/// \param name the token.
char const *escape (char const *name);
#endif /* ! GRAPHVIZ_H_ */

View File

@@ -398,6 +398,7 @@ muscle_percent_variable_update (char const *variable, location variable_loc)
const conversion_type conversion[] =
{
{ "api.push_pull", "api.push-pull", },
{ "location_type", "api.location.type", },
{ "lr.keep_unreachable_states", "lr.keep-unreachable-states", },
{ "namespace", "api.namespace", },
};
@@ -416,23 +417,17 @@ muscle_percent_variable_update (char const *variable, location variable_loc)
}
void
muscle_percent_define_insert (char const *variable, location variable_loc,
muscle_percent_define_insert (char const *var, location variable_loc,
char const *value,
muscle_percent_define_how how)
{
char const *name;
char const *loc_name;
char const *syncline_name;
char const *how_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 =
/* Backward compatibility. */
char const *variable = muscle_percent_variable_update (var, variable_loc);
char const *name = UNIQSTR_CONCAT ("percent_define(", variable, ")");
char const *loc_name = UNIQSTR_CONCAT ("percent_define_loc(", variable, ")");
char const *syncline_name =
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. */
if (how == MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE

View File

@@ -18,6 +18,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <config.h>
#include <quotearg.h>
#include "system.h"
#include "LR0.h"
@@ -54,7 +55,7 @@ print_core (struct obstack *oout, state *s)
snritems = nitemset;
}
obstack_printf (oout, "%d", s->number);
obstack_printf (oout, "state %d\\n", s->number);
for (i = 0; i < snritems; i++)
{
item_number *sp;
@@ -68,15 +69,15 @@ print_core (struct obstack *oout, state *s)
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++)
obstack_printf (oout, "%s ", symbols[*sp]->tag);
obstack_printf (oout, "%s ", escape (symbols[*sp]->tag));
obstack_1grow (oout, '.');
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. */
if (report_flag & report_lookahead_tokens
@@ -92,15 +93,17 @@ print_core (struct obstack *oout, state *s)
bitset_iterator biter;
int k;
char const *sep = "";
obstack_sgrow (oout, "[");
obstack_1grow (oout, '[');
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 = ", ";
}
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;
/* Display reductions. */
output_red (s, s->reductions, fgraph);
if (!trans->num && !s->reductions)
return;

View File

@@ -55,6 +55,10 @@
#include <unistd.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
/* This isn't perfect, but it's good enough for Bison, which needs
only to hash pointers. */
@@ -220,8 +224,6 @@ typedef size_t uintptr_t;
(obstack_1grow (Obs, '\0'), (char *) obstack_finish (Obs))
/*-----------------------------------------.
| Extensions to use for the output files. |
`-----------------------------------------*/