2 /* Parse Bison Skeletons.
3 Copyright (C) 2001 Free Software Foundation, Inc.
5 This file is part of Bison, the GNU Compiler Compiler.
7 Bison is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 Bison is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bison; see the file COPYING. If not, write to the Free
19 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
33 #include "muscle_tab.h"
44 static int merror PARAMS ((const char* error));
45 static int yyerror PARAMS ((const char* error));
57 %token <muscle> MUSCLE
58 %token <string> STRING
59 %token <character> CHARACTER
71 %type <yacc> section.yacc
77 skeleton : /* Empty. */ { }
78 | section skeleton { }
81 section : section.header section.body { }
84 section.header : SECTION gb MUSCLE gb STRING gb section.yacc gb '\n'
90 /* Close the previous parser. */
92 parser = (xfclose (parser), NULL);
94 /* If the following section should be named with the yacc-style, and it's
95 suffix is of the form 'something.h' or 'something.c', then add '.tab' in
96 the middle of the suffix. */
97 if (tab_extension && $7 && (strsuffix (suffix, ".h") ||
98 strsuffix (suffix, ".c")))
100 size_t prefix_len = strlen (prefix);
101 size_t suffix_len = strlen (suffix);
103 /* Allocate enough space to insert '.tab'. */
104 name = XMALLOC (char, prefix_len + suffix_len + 5);
105 limit = strrchr (suffix, '.');
109 /* Prefix is 'X', suffix is 'Y.Z'. Name will be 'XY.tab.Z'. */
112 cp = stpcpy (name, prefix);
113 cp = stpncpy (cp, suffix, limit - suffix);
114 cp = stpcpy (cp, ".tab");
115 cp = stpcpy (cp, limit);
119 name = stringappend (prefix, suffix);
121 /* Prepare the next parser to be output. */
122 parser = xfopen (name, "w");
123 MUSCLE_INSERT_STRING ("parser-file-name", name);
130 section.yacc : /* Empty. */ { $$ = 0; }
136 | section.body '\n' { fputc ('\n', parser); ++output_line; ++skeleton_line; }
137 | section.body LINE { fprintf (parser, "%d", output_line); }
138 | section.body SLINE { fprintf (parser, "%d", skeleton_line); }
139 | section.body GUARDS { guards_output (parser, &output_line); }
140 | section.body TOKENS { token_definitions_output (parser, &output_line); }
141 | section.body ACTIONS { actions_output (parser, &output_line); }
142 | section.body CHARACTER { fputc ($2, parser); }
143 | section.body MUSCLE {
144 const char* value = muscle_find ($2);
147 fputs (value, parser);
148 output_line += get_lines_number (value);
152 fprintf (parser, "%%{%s}", $2);
158 gb : /* Empty. */ { }
159 | gb CHARACTER { /* Do not echo garbage characters. */ }
165 merror (const char* error)
167 printf ("line %d: %%{%s} undeclared.\n", skeleton_line, error);
172 yyerror (const char* error)
174 fprintf (stderr, "%s\n", error);
179 process_skeleton (const char* skel)
181 /* Compute prefix. Actually, it seems that the processing I need here is
182 done in compute_base_names, and the result stored in short_base_name. */
183 prefix = short_base_name;
185 /* Prepare a few things. */
190 yyin = fopen (skel, "r");
194 /* Close the last parser. */
196 parser = (xfclose (parser), NULL);