Automaton VCG graph output.

Using option ``-g'' or long option ``--graph'', you can generate
a gram_filename.vcg file containing a VCG description of the LALR (1)
automaton of your grammar.
* src/main.c: Call to print_graph() function.
* src/getargs.h: Update.
* src/getargs.c (options): Update to catch `-g' and `--graph' options.
(graph_flag): New flag.
(longopts): Update.
(getargs): Add case `g'.
* src/files.c (graph_obstack): New obstack struct.
(open_files): Initialize new obstack.
(output_files): Saves graph_obstack if required.
* src/files.h (graph_obstack): New extern declaration.
* src/Makefile.am: Add new source files.
This commit is contained in:
Akim Demaille
2001-08-06 09:22:33 +00:00
parent ce4d5ce009
commit 22c2cbc078
8 changed files with 74 additions and 39 deletions

View File

@@ -1,3 +1,22 @@
2001-08-06 Marc Autret <autret_@epita.fr>
Automaton VCG graph output.
Using option ``-g'' or long option ``--graph'', you can generate
a gram_filename.vcg file containing a VCG description of the LALR (1)
automaton of your grammar.
* src/main.c: Call to print_graph() function.
* src/getargs.h: Update.
* src/getargs.c (options): Update to catch `-g' and `--graph' options.
(graph_flag): New flag.
(longopts): Update.
(getargs): Add case `g'.
* src/files.c (graph_obstack): New obstack struct.
(open_files): Initialize new obstack.
(output_files): Saves graph_obstack if required.
* src/files.h (graph_obstack): New extern declaration.
* src/Makefile.am: Add new source files.
2001-08-06 Marc Autret <autret_@epita.fr> 2001-08-06 Marc Autret <autret_@epita.fr>
* src/print_graph.c, src/print_graph.h (graph): New. * src/print_graph.c, src/print_graph.h (graph): New.

View File

@@ -14,7 +14,7 @@ bison_SOURCES = LR0.c closure.c complain.c conflicts.c \
derives.c \ derives.c \
files.c getargs.c gram.c lalr.c lex.c main.c nullable.c \ files.c getargs.c gram.c lalr.c lex.c main.c nullable.c \
output.c \ output.c \
print.c reader.c reduce.c symtab.c warshall.c print.c reader.c reduce.c symtab.c warshall.c vcg.c print_graph.c
EXTRA_bison_SOURCES = vmsgetargs.c EXTRA_bison_SOURCES = vmsgetargs.c
@@ -22,7 +22,8 @@ noinst_HEADERS = LR0.h closure.h complain.h conflicts.h \
derives.h \ derives.h \
files.h getargs.h gram.h lalr.h lex.h nullable.h \ files.h getargs.h gram.h lalr.h lex.h nullable.h \
output.h state.h \ output.h state.h \
print.h reader.h reduce.h symtab.h warshall.h system.h types.h print.h reader.h reduce.h symtab.h warshall.h system.h types.h \
vcg.h vcg_defaults.h print_graph.h
pkgdata_DATA = bison.simple bison.hairy pkgdata_DATA = bison.simple bison.hairy

View File

@@ -103,12 +103,12 @@ LDADD = @INTLLIBS@ ../lib/libbison.a
bin_PROGRAMS = bison bin_PROGRAMS = bison
bison_SOURCES = LR0.c closure.c complain.c conflicts.c derives.c files.c getargs.c gram.c lalr.c lex.c main.c nullable.c output.c print.c reader.c reduce.c symtab.c warshall.c bison_SOURCES = LR0.c closure.c complain.c conflicts.c derives.c files.c getargs.c gram.c lalr.c lex.c main.c nullable.c output.c print.c reader.c reduce.c symtab.c warshall.c vcg.c print_graph.c
EXTRA_bison_SOURCES = vmsgetargs.c EXTRA_bison_SOURCES = vmsgetargs.c
noinst_HEADERS = LR0.h closure.h complain.h conflicts.h derives.h files.h getargs.h gram.h lalr.h lex.h nullable.h output.h state.h print.h reader.h reduce.h symtab.h warshall.h system.h types.h noinst_HEADERS = LR0.h closure.h complain.h conflicts.h derives.h files.h getargs.h gram.h lalr.h lex.h nullable.h output.h state.h print.h reader.h reduce.h symtab.h warshall.h system.h types.h vcg.h vcg_defaults.h print_graph.h
pkgdata_DATA = bison.simple bison.hairy pkgdata_DATA = bison.simple bison.hairy
@@ -126,7 +126,7 @@ ANSI2KNR = ../lib/ansi2knr
bison_OBJECTS = LR0$U.o closure$U.o complain$U.o conflicts$U.o \ bison_OBJECTS = LR0$U.o closure$U.o complain$U.o conflicts$U.o \
derives$U.o files$U.o getargs$U.o gram$U.o lalr$U.o lex$U.o main$U.o \ derives$U.o files$U.o getargs$U.o gram$U.o lalr$U.o lex$U.o main$U.o \
nullable$U.o output$U.o print$U.o reader$U.o reduce$U.o symtab$U.o \ nullable$U.o output$U.o print$U.o reader$U.o reduce$U.o symtab$U.o \
warshall$U.o warshall$U.o vcg$U.o print_graph$U.o
bison_LDADD = $(LDADD) bison_LDADD = $(LDADD)
bison_DEPENDENCIES = ../lib/libbison.a bison_DEPENDENCIES = ../lib/libbison.a
bison_LDFLAGS = bison_LDFLAGS =
@@ -148,8 +148,9 @@ GZIP_ENV = --best
DEP_FILES = .deps/LR0.P .deps/closure.P .deps/complain.P \ DEP_FILES = .deps/LR0.P .deps/closure.P .deps/complain.P \
.deps/conflicts.P .deps/derives.P .deps/files.P .deps/getargs.P \ .deps/conflicts.P .deps/derives.P .deps/files.P .deps/getargs.P \
.deps/gram.P .deps/lalr.P .deps/lex.P .deps/main.P .deps/nullable.P \ .deps/gram.P .deps/lalr.P .deps/lex.P .deps/main.P .deps/nullable.P \
.deps/output.P .deps/print.P .deps/reader.P .deps/reduce.P \ .deps/output.P .deps/print.P .deps/print_graph.P .deps/reader.P \
.deps/symtab.P .deps/vmsgetargs.P .deps/warshall.P .deps/reduce.P .deps/symtab.P .deps/vcg.P .deps/vmsgetargs.P \
.deps/warshall.P
SOURCES = $(bison_SOURCES) $(EXTRA_bison_SOURCES) SOURCES = $(bison_SOURCES) $(EXTRA_bison_SOURCES)
OBJECTS = $(bison_OBJECTS) OBJECTS = $(bison_OBJECTS)
@@ -255,6 +256,8 @@ output_.c: output.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/output.c; then echo $(srcdir)/output.c; else echo output.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > output_.c $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/output.c; then echo $(srcdir)/output.c; else echo output.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > output_.c
print_.c: print.c $(ANSI2KNR) print_.c: print.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/print.c; then echo $(srcdir)/print.c; else echo print.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > print_.c $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/print.c; then echo $(srcdir)/print.c; else echo print.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > print_.c
print_graph_.c: print_graph.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/print_graph.c; then echo $(srcdir)/print_graph.c; else echo print_graph.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > print_graph_.c
reader_.c: reader.c $(ANSI2KNR) reader_.c: reader.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/reader.c; then echo $(srcdir)/reader.c; else echo reader.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > reader_.c $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/reader.c; then echo $(srcdir)/reader.c; else echo reader.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > reader_.c
reduce_.c: reduce.c $(ANSI2KNR) reduce_.c: reduce.c $(ANSI2KNR)
@@ -269,14 +272,17 @@ strspn_.c: strspn.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/strspn.c; then echo $(srcdir)/strspn.c; else echo strspn.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > strspn_.c $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/strspn.c; then echo $(srcdir)/strspn.c; else echo strspn.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > strspn_.c
symtab_.c: symtab.c $(ANSI2KNR) symtab_.c: symtab.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/symtab.c; then echo $(srcdir)/symtab.c; else echo symtab.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > symtab_.c $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/symtab.c; then echo $(srcdir)/symtab.c; else echo symtab.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > symtab_.c
vcg_.c: vcg.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/vcg.c; then echo $(srcdir)/vcg.c; else echo vcg.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > vcg_.c
vmsgetargs_.c: vmsgetargs.c $(ANSI2KNR) vmsgetargs_.c: vmsgetargs.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/vmsgetargs.c; then echo $(srcdir)/vmsgetargs.c; else echo vmsgetargs.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > vmsgetargs_.c $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/vmsgetargs.c; then echo $(srcdir)/vmsgetargs.c; else echo vmsgetargs.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > vmsgetargs_.c
warshall_.c: warshall.c $(ANSI2KNR) warshall_.c: warshall.c $(ANSI2KNR)
$(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/warshall.c; then echo $(srcdir)/warshall.c; else echo warshall.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > warshall_.c $(CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/warshall.c; then echo $(srcdir)/warshall.c; else echo warshall.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > warshall_.c
LR0_.o alloca_.o closure_.o complain_.o conflicts_.o derives_.o \ LR0_.o alloca_.o closure_.o complain_.o conflicts_.o derives_.o \
files_.o getargs_.o gram_.o lalr_.o lex_.o main_.o memchr_.o \ files_.o getargs_.o gram_.o lalr_.o lex_.o main_.o memchr_.o \
nullable_.o output_.o print_.o reader_.o reduce_.o stpcpy_.o strndup_.o \ nullable_.o output_.o print_.o print_graph_.o reader_.o reduce_.o \
strnlen_.o strspn_.o symtab_.o vmsgetargs_.o warshall_.o : $(ANSI2KNR) stpcpy_.o strndup_.o strnlen_.o strspn_.o symtab_.o vcg_.o \
vmsgetargs_.o warshall_.o : $(ANSI2KNR)
install-pkgdataDATA: $(pkgdata_DATA) install-pkgdataDATA: $(pkgdata_DATA)
@$(NORMAL_INSTALL) @$(NORMAL_INSTALL)

View File

@@ -1,5 +1,5 @@
/* Open and close files for bison, /* Open and close files for bison,
Copyright 1984, 1986, 1989, 1992, 2000 Free Software Foundation, Inc. Copyright 1984, 1986, 1989, 1992, 2000, 2001 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler. This file is part of Bison, the GNU Compiler Compiler.
@@ -34,6 +34,7 @@ struct obstack table_obstack;
struct obstack defines_obstack; struct obstack defines_obstack;
struct obstack guard_obstack; struct obstack guard_obstack;
struct obstack output_obstack; struct obstack output_obstack;
struct obstack graph_obstack;
char *spec_outfile = NULL; /* for -o. */ char *spec_outfile = NULL; /* for -o. */
char *spec_file_prefix = NULL; /* for -b. */ char *spec_file_prefix = NULL; /* for -b. */
@@ -213,7 +214,7 @@ compute_exts_from_gf(const char *ext)
{ {
src_extension = tr(ext, 'y', 'c'); src_extension = tr(ext, 'y', 'c');
src_extension = tr(src_extension, 'Y', 'C'); src_extension = tr(src_extension, 'Y', 'C');
} }
if (!header_extension) if (!header_extension)
{ {
header_extension = tr(ext, 'y', 'h'); header_extension = tr(ext, 'y', 'h');
@@ -228,7 +229,7 @@ compute_exts_from_src(const char *ext)
if (!src_extension) if (!src_extension)
src_extension = xstrdup(ext); src_extension = xstrdup(ext);
if (!header_extension) if (!header_extension)
{ {
header_extension = tr(ext, 'c', 'h'); header_extension = tr(ext, 'c', 'h');
header_extension = tr(header_extension, 'C', 'H'); header_extension = tr(header_extension, 'C', 'H');
} }

View File

@@ -56,6 +56,8 @@ extern struct obstack guard_obstack;
/* The verbose output. */ /* The verbose output. */
extern struct obstack output_obstack; extern struct obstack output_obstack;
/* The VCG graph output. */
extern struct obstack graph_obstack;
extern char *infile; extern char *infile;
extern char *attrsfile; extern char *attrsfile;

View File

@@ -34,11 +34,12 @@ int token_table_flag = 0;
int verbose_flag = 0; int verbose_flag = 0;
int statistics_flag = 0; int statistics_flag = 0;
int yacc_flag = 0; /* for -y */ int yacc_flag = 0; /* for -y */
int graph_flag = 0;
const char *skeleton = NULL; const char *skeleton = NULL;
extern char *program_name; extern char *program_name;
const char *shortopts = "yvdhrltknVo:b:p:S:"; const char *shortopts = "yvgdhrltknVo:b:p:S:";
static struct option longopts[] = static struct option longopts[] =
{ {
/* Operation modes. */ /* Operation modes. */
@@ -63,6 +64,7 @@ static struct option longopts[] =
{"verbose", no_argument, 0, 'v'}, {"verbose", no_argument, 0, 'v'},
{"file-prefix", required_argument, 0, 'b'}, {"file-prefix", required_argument, 0, 'b'},
{"output-file", required_argument, 0, 'o'}, {"output-file", required_argument, 0, 'o'},
{"graph", no_argument, 0, 'g'},
/* Hidden. */ /* Hidden. */
{"statistics", no_argument, &statistics_flag, 1}, {"statistics", no_argument, &statistics_flag, 1},
@@ -178,6 +180,10 @@ getargs (int argc, char *argv[])
version (stdout); version (stdout);
exit (0); exit (0);
case 'g':
graph_flag = 1;
break;
case 'v': case 'v':
verbose_flag = 1; verbose_flag = 1;
break; break;

View File

@@ -34,6 +34,7 @@ extern int no_parser_flag; /* for -n */
extern int statistics_flag; extern int statistics_flag;
extern int token_table_flag; /* for -k */ extern int token_table_flag; /* for -k */
extern int verbose_flag; /* for -v */ extern int verbose_flag; /* for -v */
extern int graph_flag; /* for -g */
extern int yacc_flag; /* for -y */ extern int yacc_flag; /* for -y */
void getargs PARAMS ((int argc, char *argv[])); void getargs PARAMS ((int argc, char *argv[]));

View File

@@ -1,5 +1,5 @@
/* Output a VCG description on generated parser, for bison, /* Output a VCG description on generated parser, for Bison,
Copyright 1984, 1986, 1989, 2000, 2001 Free Software Foundation, Inc. Copyright 2001 Free Software Foundation, Inc.
This file is part of Bison, the GNU Compiler Compiler. This file is part of Bison, the GNU Compiler Compiler.
@@ -45,13 +45,13 @@ print_core (int state)
core *statep; core *statep;
short *sp; short *sp;
short *sp1; short *sp1;
statep = state_table[state]; statep = state_table[state];
k = statep->nitems; k = statep->nitems;
if (k == 0) if (k == 0)
return; return;
obstack_sgrow(&graph_obstack, "\t\tlabel:\t\""); obstack_sgrow(&graph_obstack, "\t\tlabel:\t\"");
for (i = 0; i < k; i++) for (i = 0; i < k; i++)
@@ -64,16 +64,16 @@ print_core (int state)
rule = -(*sp); rule = -(*sp);
obstack_fgrow1(&graph_obstack, _("%d: "), rule); obstack_fgrow1(&graph_obstack, _("%d: "), rule);
obstack_fgrow1(&graph_obstack, " %s -> ", tags[rlhs[rule]]); obstack_fgrow1(&graph_obstack, " %s -> ", tags[rlhs[rule]]);
for (sp = ritem + rrhs[rule]; sp < sp1; sp++) for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
obstack_fgrow1(&graph_obstack, "%s ", tags[*sp]); obstack_fgrow1(&graph_obstack, "%s ", tags[*sp]);
obstack_1grow(&graph_obstack, '.'); obstack_1grow(&graph_obstack, '.');
while (*sp > 0) while (*sp > 0)
obstack_fgrow1(&graph_obstack, " %s", tags[*sp++]); obstack_fgrow1(&graph_obstack, " %s", tags[*sp++]);
obstack_sgrow(&graph_obstack, "\\n"); obstack_sgrow(&graph_obstack, "\\n");
} }
obstack_sgrow(&graph_obstack, "\"\n"); obstack_sgrow(&graph_obstack, "\"\n");
@@ -92,7 +92,7 @@ print_actions (int state, node_t *node)
int rule; int rule;
static char buff[10]; static char buff[10];
edge_t edge; edge_t edge;
shiftp = shift_table[state]; shiftp = shift_table[state];
redp = reduction_table[state]; redp = reduction_table[state];
errp = err_table[state]; errp = err_table[state];
@@ -119,7 +119,7 @@ print_actions (int state, node_t *node)
if (ISVAR (symbol)) if (ISVAR (symbol))
break; break;
{ {
new_edge (&edge); new_edge (&edge);
@@ -129,11 +129,11 @@ print_actions (int state, node_t *node)
edge.sourcename = node->title; edge.sourcename = node->title;
edge.targetname = buff; edge.targetname = buff;
sprintf (edge.targetname, "%d", state1); sprintf (edge.targetname, "%d", state1);
edge.color = (symbol == 0) ? blue : red; edge.color = (symbol == 0) ? blue : red;
edge.label = tags[symbol]; edge.label = tags[symbol];
output_edge (&edge, &graph_obstack); output_edge (&edge, &graph_obstack);
close_edge (&graph_obstack); close_edge (&graph_obstack);
} }
} }
} }
else else
@@ -155,13 +155,13 @@ print_actions (int state, node_t *node)
symbol = errp->errs[j]; symbol = errp->errs[j];
} }
} }
if (consistent[state] && redp) if (consistent[state] && redp)
{ {
rule = redp->rules[0]; rule = redp->rules[0];
symbol = rlhs[rule]; symbol = rlhs[rule];
} }
if (i < k) if (i < k)
{ {
for (; i < k; i++) for (; i < k; i++)
@@ -188,19 +188,19 @@ static void
print_state (int state) print_state (int state)
{ {
static char name[10]; static char name[10];
node_t node; node_t node;
new_node (&node); new_node (&node);
open_node (&graph_obstack); open_node (&graph_obstack);
sprintf(name, "%d", state); sprintf(name, "%d", state);
node.title = name; node.title = name;
output_node (&node, &graph_obstack); output_node (&node, &graph_obstack);
print_core (state); /* node label */ print_core (state); /* node label */
close_node (&graph_obstack); close_node (&graph_obstack);
print_actions (state, &node); /* edges */ print_actions (state, &node); /* edges */
} }
@@ -209,23 +209,23 @@ void
print_graph (void) print_graph (void)
{ {
int i; int i;
if (!graph_flag) if (!graph_flag)
return ; return ;
new_graph (&graph); new_graph (&graph);
/* graph.smanhattan_edges = yes; /* graph.smanhattan_edges = yes;
graph.manhattan_edges = yes; */ graph.manhattan_edges = yes; */
graph.display_edge_labels = yes; graph.display_edge_labels = yes;
graph.layoutalgorithm = 0; graph.layoutalgorithm = 0;
graph.port_sharing = no; graph.port_sharing = no;
graph.finetuning = yes; graph.finetuning = yes;
graph.straight_phase = yes; graph.straight_phase = yes;
graph.priority_phase = yes; graph.priority_phase = yes;
graph.splines = yes; graph.splines = yes;
graph.crossing_weight = median; graph.crossing_weight = median;
/* Output graph options. */ /* Output graph options. */
@@ -239,4 +239,3 @@ print_graph (void)
/* Close graph. */ /* Close graph. */
close_graph (&graph, &graph_obstack); close_graph (&graph, &graph_obstack);
} }