From: Akim Demaille Date: Thu, 27 Dec 2001 18:06:06 +0000 (+0000) Subject: * src/gram.h (rule_t): `guard' and `guard_line' are new members. X-Git-Tag: before-m4-back-end~95 X-Git-Url: https://git.saurik.com/bison.git/commitdiff_plain/f499b06243dfe7d6387c9413411601cd5c20dd2c?hp=d945f5cd8e85c0343da52dc720d23624e1c28661 * 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. --- diff --git a/ChangeLog b/ChangeLog index 62168daf..cb4de308 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2001-12-27 Akim Demaille + + * 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 * src/reader.c (symbol_list_new): Be sure to initialize all the diff --git a/src/files.c b/src/files.c index b3064b5a..5e01b9f8 100644 --- a/src/files.c +++ b/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); -} diff --git a/src/files.h b/src/files.h index 573ea3ce..19f07692 100644 --- a/src/files.h +++ b/src/files.h @@ -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)); diff --git a/src/gram.h b/src/gram.h index fc860386..021061d2 100644 --- a/src/gram.h +++ b/src/gram.h @@ -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; diff --git a/src/main.c b/src/main.c index 6deec48a..28b08e18 100644 --- a/src/main.c +++ b/src/main.c @@ -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 diff --git a/src/output.c b/src/output.c index 705db814..1b10c120 100644 --- a/src/output.c +++ b/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); } diff --git a/src/reader.c b/src/reader.c index d7d6e86d..1ad63821 100644 --- a/src/reader.c +++ b/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) diff --git a/tests/Makefile.am b/tests/Makefile.am index ac0c8bfb..1b44a445 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 diff --git a/tests/regression.at b/tests/regression.at index bf863671..f123f0c2 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -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 diff --git a/tests/semantic.at b/tests/semantic.at new file mode 100644 index 00000000..b03329d3 --- /dev/null +++ b/tests/semantic.at @@ -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 INT +%type 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 diff --git a/tests/testsuite.at b/tests/testsuite.at index be0d08d4..4eb833f5 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -31,3 +31,4 @@ m4_include([reduce.at]) m4_include([calc.at]) m4_include([torture.at]) m4_include([regression.at]) +m4_include([semantic.at])