mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
* src/gram.h (rule_t): guard' and guard_line' are new members.
* src/reader.c (symbol_list): `guard' and `guard_line' are new members. (symbol_list_new): Adjust. (copy_action): action_line is the first line, not the last. (copy_guard): Just as for actions, store the `action' only, not the switch/case/break flesh. Don't parse the user action that might follow the guard, let... (readgram): do it, i.e., now, there can be an action after a guard. In other words the guard is just explicitly optional. (packgram): Adjust. * src/output.c (guards_output): New. (output_parser): Call it when needed. (output): Also free the guard and attrs obstacks. * src/files.c, src/files.h (obstack_save): Remove. (output_files): Remove. As a result, if one needs the former `.act' file, using an appropriate skeleton which requires actions and guards is now required. * src/main.c (main): Adjust. * tests/semantic.at: New. * tests/regression.at: Use `input.y' as input file name. Avoid 8+3 problems by requiring input.c when the test needs the parser.
This commit is contained in:
28
ChangeLog
28
ChangeLog
@@ -1,3 +1,31 @@
|
||||
2001-12-27 Akim Demaille <akim@epita.fr>
|
||||
|
||||
* src/gram.h (rule_t): `guard' and `guard_line' are new members.
|
||||
* src/reader.c (symbol_list): `guard' and `guard_line' are new
|
||||
members.
|
||||
(symbol_list_new): Adjust.
|
||||
(copy_action): action_line is the first line, not the last.
|
||||
(copy_guard): Just as for actions, store the `action' only, not
|
||||
the switch/case/break flesh.
|
||||
Don't parse the user action that might follow the guard, let...
|
||||
(readgram): do it, i.e., now, there can be an action after a
|
||||
guard.
|
||||
In other words the guard is just explicitly optional.
|
||||
(packgram): Adjust.
|
||||
* src/output.c (guards_output): New.
|
||||
(output_parser): Call it when needed.
|
||||
(output): Also free the guard and attrs obstacks.
|
||||
* src/files.c, src/files.h (obstack_save): Remove.
|
||||
(output_files): Remove.
|
||||
As a result, if one needs the former `.act' file, using an
|
||||
appropriate skeleton which requires actions and guards is now
|
||||
required.
|
||||
* src/main.c (main): Adjust.
|
||||
* tests/semantic.at: New.
|
||||
* tests/regression.at: Use `input.y' as input file name.
|
||||
Avoid 8+3 problems by requiring input.c when the test needs the
|
||||
parser.
|
||||
|
||||
2001-12-27 Akim Demaille <akim@epita.fr>
|
||||
|
||||
* src/reader.c (symbol_list_new): Be sure to initialize all the
|
||||
|
||||
47
src/files.c
47
src/files.c
@@ -164,18 +164,6 @@ xfclose (FILE *ptr)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------.
|
||||
| Save the content of the obstack OBS in FILENAME. |
|
||||
`--------------------------------------------------*/
|
||||
|
||||
static void
|
||||
obstack_save (struct obstack *obs, const char *filename)
|
||||
{
|
||||
FILE *out = xfopen (filename, "w");
|
||||
size_t size = obstack_object_size (obs);
|
||||
fwrite (obstack_finish (obs), 1, size, out);
|
||||
xfclose (out);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------.
|
||||
| Return the path to the skeleton which locaction might be given in |
|
||||
@@ -436,38 +424,3 @@ compute_output_file_names (void)
|
||||
attrsfile = stringappend (attrsfile, header_extension);
|
||||
#endif /* MSDOS */
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------.
|
||||
| Produce the output files. |
|
||||
`---------------------------*/
|
||||
|
||||
void
|
||||
output_files (void)
|
||||
{
|
||||
#if 0
|
||||
/* Seems to be invalid now --akim. */
|
||||
|
||||
/* If we output only the table, dump the actions in ACTFILE. */
|
||||
if (no_parser_flag)
|
||||
obstack_save (&action_obstack, stringappend (short_base_name, ".act"));
|
||||
obstack_free (&action_obstack, NULL);
|
||||
#endif
|
||||
|
||||
/* If we produced a semantic parser ATTRS_OBSTACK must be dumped
|
||||
into its own file, ATTTRSFILE. */
|
||||
if (semantic_parser)
|
||||
{
|
||||
char *temp_name;
|
||||
|
||||
obstack_save (&attrs_obstack, attrsfile);
|
||||
temp_name = stringappend (short_base_name, EXT_GUARD_C);
|
||||
#ifndef MSDOS
|
||||
temp_name = stringappend (temp_name, src_extension);
|
||||
#endif /* MSDOS */
|
||||
obstack_save (&guard_obstack, temp_name);
|
||||
}
|
||||
|
||||
obstack_free (&guard_obstack, NULL);
|
||||
obstack_free (&attrs_obstack, NULL);
|
||||
}
|
||||
|
||||
@@ -62,13 +62,12 @@ extern char *infile;
|
||||
extern char *attrsfile;
|
||||
|
||||
void compute_output_file_names PARAMS((void));
|
||||
void output_files PARAMS((void));
|
||||
|
||||
FILE *xfopen PARAMS ((const char *name, const char *mode));
|
||||
int xfclose PARAMS ((FILE *ptr));
|
||||
|
||||
/* Compute the double inclusion guard's name. */
|
||||
char * compute_header_macro PARAMS ((void));
|
||||
char *compute_header_macro PARAMS ((void));
|
||||
|
||||
const char *skeleton_find PARAMS ((const char *envvar,
|
||||
const char *skeleton_name));
|
||||
|
||||
@@ -122,8 +122,12 @@ typedef struct rule_s
|
||||
short assoc;
|
||||
short line;
|
||||
bool useful;
|
||||
|
||||
const char *action;
|
||||
short action_line;
|
||||
|
||||
const char *guard;
|
||||
short guard_line;
|
||||
} rule_t;
|
||||
|
||||
extern struct rule_s *rule_table;
|
||||
|
||||
@@ -110,8 +110,6 @@ main (int argc, char *argv[])
|
||||
free_nullable ();
|
||||
free_derives ();
|
||||
|
||||
output_files ();
|
||||
|
||||
/* If using alloca.c, flush the alloca'ed memory for the benefit of
|
||||
people running Bison as a library in IDEs. */
|
||||
#if C_ALLOCA
|
||||
|
||||
42
src/output.c
42
src/output.c
@@ -536,6 +536,38 @@ actions_output (FILE *out, size_t *line)
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------.
|
||||
| Output the guards to OOUT. |
|
||||
`----------------------------*/
|
||||
|
||||
static void
|
||||
guards_output (FILE *out, size_t *line)
|
||||
{
|
||||
int rule;
|
||||
for (rule = 1; rule < nrules + 1; ++rule)
|
||||
if (rule_table[rule].action)
|
||||
{
|
||||
fprintf (out, " case %d:\n", rule);
|
||||
|
||||
if (!no_lines_flag)
|
||||
fprintf (out, muscle_find ("linef"),
|
||||
rule_table[rule].guard_line,
|
||||
quotearg_style (c_quoting_style,
|
||||
muscle_find ("filename")));
|
||||
fprintf (out, "{ %s; }\n break;\n\n",
|
||||
rule_table[rule].guard);
|
||||
|
||||
/* We always output 4 '\n' per action. */
|
||||
*line += 4;
|
||||
/* Plus one if !no_lines_flag. */
|
||||
if (!no_lines_flag)
|
||||
++*line;
|
||||
/* Get the number of lines written by the user. */
|
||||
*line += get_lines_number (rule_table[rule].guard);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
save_column (int symbol, int default_state)
|
||||
{
|
||||
@@ -928,6 +960,8 @@ output_parser (const char *skel_filename, FILE *out)
|
||||
muscle_value = muscle_find (muscle_key);
|
||||
if (!strcmp (muscle_key, "actions"))
|
||||
actions_output (out, &output_line);
|
||||
else if (!strcmp (muscle_key, "guards"))
|
||||
guards_output (out, &output_line);
|
||||
else if (!strcmp (muscle_key, "line"))
|
||||
fprintf (out, "%d", output_line);
|
||||
else if (!strcmp (muscle_key, "skeleton-line"))
|
||||
@@ -1091,7 +1125,9 @@ output (void)
|
||||
header_output ();
|
||||
|
||||
free (rule_table + 1);
|
||||
obstack_free (&muscle_obstack, 0);
|
||||
obstack_free (&format_obstack, 0);
|
||||
obstack_free (&action_obstack, 0);
|
||||
obstack_free (&muscle_obstack, NULL);
|
||||
obstack_free (&format_obstack, NULL);
|
||||
obstack_free (&action_obstack, NULL);
|
||||
obstack_free (&guard_obstack, NULL);
|
||||
obstack_free (&attrs_obstack, NULL);
|
||||
}
|
||||
|
||||
38
src/reader.c
38
src/reader.c
@@ -40,9 +40,14 @@ typedef struct symbol_list
|
||||
struct symbol_list *next;
|
||||
bucket *sym;
|
||||
int line;
|
||||
|
||||
/* The action is attached to the LHS of a rule. */
|
||||
const char *action;
|
||||
int action_line;
|
||||
|
||||
/* The guard is attached to the LHS of a rule. */
|
||||
const char *guard;
|
||||
int guard_line;
|
||||
bucket *ruleprec;
|
||||
} symbol_list;
|
||||
|
||||
@@ -76,6 +81,8 @@ symbol_list_new (bucket *sym)
|
||||
res->line = lineno;
|
||||
res->action = NULL;
|
||||
res->action_line = 0;
|
||||
res->guard = NULL;
|
||||
res->guard_line = 0;
|
||||
res->ruleprec = NULL;
|
||||
return res;
|
||||
}
|
||||
@@ -1088,6 +1095,8 @@ copy_action (symbol_list *rule, int stack_offset)
|
||||
count = 1;
|
||||
c = getc (finput);
|
||||
|
||||
rule->action_line = lineno;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
while (c != '}')
|
||||
@@ -1144,7 +1153,6 @@ copy_action (symbol_list *rule, int stack_offset)
|
||||
|
||||
obstack_1grow (&action_obstack, '\0');
|
||||
rule->action = obstack_finish (&action_obstack);
|
||||
rule->action_line = lineno;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------.
|
||||
@@ -1167,12 +1175,7 @@ copy_guard (symbol_list *rule, int stack_offset)
|
||||
if (semantic_parser)
|
||||
stack_offset = 0;
|
||||
|
||||
obstack_fgrow1 (&guard_obstack, "\ncase %d:\n", nrules);
|
||||
if (!no_lines_flag)
|
||||
obstack_fgrow2 (&guard_obstack, muscle_find ("linef"),
|
||||
lineno, quotearg_style (c_quoting_style,
|
||||
muscle_find ("filename")));
|
||||
obstack_1grow (&guard_obstack, '{');
|
||||
rule->guard_line = lineno;
|
||||
|
||||
count = 0;
|
||||
c = getc (finput);
|
||||
@@ -1231,19 +1234,8 @@ copy_guard (symbol_list *rule, int stack_offset)
|
||||
c = getc (finput);
|
||||
}
|
||||
|
||||
c = skip_white_space ();
|
||||
|
||||
obstack_sgrow (&guard_obstack, ";\n break;}");
|
||||
if (c == '{')
|
||||
copy_action (rule, stack_offset);
|
||||
else if (c == '=')
|
||||
{
|
||||
c = getc (finput); /* why not skip_white_space -wjh */
|
||||
if (c == '{')
|
||||
copy_action (rule, stack_offset);
|
||||
}
|
||||
else
|
||||
ungetc (c, finput);
|
||||
obstack_1grow (&guard_obstack, '\0');
|
||||
rule->guard = obstack_finish (&guard_obstack);
|
||||
}
|
||||
|
||||
|
||||
@@ -1466,6 +1458,7 @@ readgram (void)
|
||||
crule->ruleprec = symval;
|
||||
t = lex ();
|
||||
}
|
||||
|
||||
if (t == tok_guard)
|
||||
{
|
||||
if (!semantic_parser)
|
||||
@@ -1474,7 +1467,8 @@ readgram (void)
|
||||
copy_guard (crule, rulelength);
|
||||
t = lex ();
|
||||
}
|
||||
else if (t == tok_left_curly)
|
||||
|
||||
if (t == tok_left_curly)
|
||||
{
|
||||
/* This case never occurs -wjh */
|
||||
if (action_flag)
|
||||
@@ -1781,6 +1775,8 @@ packgram (void)
|
||||
rule_table[ruleno].useful = TRUE;
|
||||
rule_table[ruleno].action = p->action;
|
||||
rule_table[ruleno].action_line = p->action_line;
|
||||
rule_table[ruleno].guard = p->guard;
|
||||
rule_table[ruleno].guard_line = p->guard_line;
|
||||
|
||||
p = p->next;
|
||||
while (p && p->sym)
|
||||
|
||||
@@ -25,7 +25,9 @@ MAINTAINERCLEANFILES = Makefile.in $(TESTSUITE)
|
||||
|
||||
TESTSUITE_AT = \
|
||||
testsuite.at \
|
||||
output.at sets.at reduce.at calc.at torture.at regression.at
|
||||
output.at sets.at reduce.at calc.at torture.at regression.at \
|
||||
semantic.at
|
||||
|
||||
TESTSUITE = $(srcdir)/testsuite
|
||||
|
||||
AUTOTEST = $(AUTOM4TE) --language=autotest
|
||||
|
||||
@@ -25,7 +25,7 @@ AT_BANNER([[Regression tests.]])
|
||||
|
||||
AT_SETUP([Duplicate string])
|
||||
|
||||
AT_DATA([duplicate.y],
|
||||
AT_DATA([input.y],
|
||||
[[/* `Bison -v' used to dump core when two tokens are defined with the same
|
||||
string, as LE and GE below. */
|
||||
|
||||
@@ -38,7 +38,7 @@ exp: '(' exp ')' | NUM ;
|
||||
%%
|
||||
]])
|
||||
|
||||
AT_CHECK([bison -v duplicate.y -o duplicate.c], 0, ignore, ignore)
|
||||
AT_CHECK([bison -v input.y -o input.c], 0, ignore, ignore)
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -478,7 +478,7 @@ AT_CLEANUP
|
||||
|
||||
AT_SETUP([%union and --defines])
|
||||
|
||||
AT_DATA([union.y],
|
||||
AT_DATA([input.y],
|
||||
[%union
|
||||
{
|
||||
int integer;
|
||||
@@ -488,7 +488,7 @@ AT_DATA([union.y],
|
||||
exp: {};
|
||||
])
|
||||
|
||||
AT_CHECK([bison --defines union.y])
|
||||
AT_CHECK([bison --defines input.y])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
@@ -500,7 +500,7 @@ AT_CLEANUP
|
||||
|
||||
AT_SETUP([%union and C comments])
|
||||
|
||||
AT_DATA([union-comment.y],
|
||||
AT_DATA([input.y],
|
||||
[%union
|
||||
{
|
||||
/* The int. */ int integer;
|
||||
@@ -510,8 +510,8 @@ AT_DATA([union-comment.y],
|
||||
exp: {};
|
||||
])
|
||||
|
||||
AT_CHECK([bison union-comment.y])
|
||||
AT_CHECK([fgrep '//*' union-comment.tab.c], [1], [])
|
||||
AT_CHECK([bison input.y -o input.c])
|
||||
AT_CHECK([fgrep '//*' input.c], [1], [])
|
||||
|
||||
AT_CLEANUP
|
||||
|
||||
|
||||
47
tests/semantic.at
Normal file
47
tests/semantic.at
Normal file
@@ -0,0 +1,47 @@
|
||||
# Bison Semantic Parsers. -*- Autotest -*-
|
||||
# Copyright 2001 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, 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., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
|
||||
AT_BANNER([[Semantic Parsers.]])
|
||||
|
||||
# Well, nothing, or almost, is known about semantic parsers. For the
|
||||
# time being, just make sure we still parse them properly.
|
||||
|
||||
## ---------------- ##
|
||||
## Parsing Guards. ##
|
||||
## ---------------- ##
|
||||
|
||||
|
||||
AT_SETUP([Parsing Guards])
|
||||
|
||||
AT_DATA([input.y],
|
||||
[[%semantic-parser
|
||||
%union {
|
||||
int ival;
|
||||
}
|
||||
%token <ival> INT
|
||||
%type <ival> exp
|
||||
%%
|
||||
exp: exp '+' exp { $$ = $1 + $3 }
|
||||
| exp '/' exp %guard { if ($3 == 0) yyerror = 1 } { $$ = $1 / $3 }
|
||||
| INT
|
||||
%%
|
||||
]])
|
||||
|
||||
AT_CHECK([bison -v input.y -o input.c], 0, ignore, ignore)
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -31,3 +31,4 @@ m4_include([reduce.at])
|
||||
m4_include([calc.at])
|
||||
m4_include([torture.at])
|
||||
m4_include([regression.at])
|
||||
m4_include([semantic.at])
|
||||
|
||||
Reference in New Issue
Block a user