]> git.saurik.com Git - bison.git/blame - src/parse-skel.y
* src/parse-skel.y: Get rid of the shift/reduce conflict:
[bison.git] / src / parse-skel.y
CommitLineData
1239777d
AD
1 /* -*- C -*- */
2/* Parse Bison Skeletons.
3 Copyright (C) 2001 Free Software Foundation, Inc.
4
5 This file is part of Bison, the GNU Compiler Compiler.
6
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)
10 any later version.
11
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.
16
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
20 02111-1307, USA. */
21
22%debug
23%defines
a4b36db4 24%verbose
1239777d 25%error-verbose
9b3add5b 26
1239777d 27%{
9b3add5b
RA
28#include "system.h"
29#include "obstack.h"
30#include "files.h"
1239777d
AD
31#include "output.h"
32#include "skeleton.h"
9b3add5b
RA
33#include "muscle_tab.h"
34
9b3add5b
RA
35extern FILE* yyin;
36extern int yylineno;
37
38char* prefix = NULL;
39FILE* parser = NULL;
40
41size_t output_line;
42size_t skeleton_line;
43
1239777d
AD
44static int merror PARAMS ((const char* error));
45static int yyerror PARAMS ((const char* error));
9b3add5b
RA
46
47%}
48
49%union
50{
a4b36db4
AD
51 char *muscle;
52 char *string;
24fad99e 53 char *literal;
9b3add5b
RA
54 char character;
55 int yacc;
56}
57
24fad99e 58/* Name of a muscle. */
1239777d 59%token <muscle> MUSCLE
24fad99e 60/* A string dedicated to Bison (%%"foo"). */
1239777d 61%token <string> STRING
24fad99e
AD
62/* Raw data, to output directly. */
63%token <literal> RAW
64/* Spaces. */
65%token <literal> BLANKS
66/* Raw data, but char by char. */
1239777d 67%token <character> CHARACTER
9b3add5b
RA
68
69%token LINE
70%token SLINE
71
72%token YACC
73%token SECTION
74
75%token GUARDS
76%token TOKENS
77%token ACTIONS
78
1239777d 79%type <yacc> section.yacc
9b3add5b
RA
80
81%start skeleton
82
83%%
84
85skeleton : /* Empty. */ { }
86 | section skeleton { }
87;
88
89section : section.header section.body { }
90;
91
24fad99e 92section.header : SECTION BLANKS MUSCLE BLANKS STRING BLANKS section.yacc '\n'
9b3add5b 93{
1239777d
AD
94 char *name = 0;
95 char *limit = 0;
96 char *suffix = $5;
9b3add5b
RA
97
98 /* Close the previous parser. */
99 if (parser)
100 parser = (xfclose (parser), NULL);
101
102 /* If the following section should be named with the yacc-style, and it's
103 suffix is of the form 'something.h' or 'something.c', then add '.tab' in
104 the middle of the suffix. */
1239777d 105 if (tab_extension && $7 && (strsuffix (suffix, ".h") ||
9b3add5b
RA
106 strsuffix (suffix, ".c")))
107 {
108 size_t prefix_len = strlen (prefix);
109 size_t suffix_len = strlen (suffix);
110
111 /* Allocate enough space to insert '.tab'. */
112 name = XMALLOC (char, prefix_len + suffix_len + 5);
113 limit = strrchr (suffix, '.');
114 if (!limit)
115 limit = suffix;
116
117 /* Prefix is 'X', suffix is 'Y.Z'. Name will be 'XY.tab.Z'. */
118 {
119 char* cp = 0;
120 cp = stpcpy (name, prefix);
121 cp = stpncpy (cp, suffix, limit - suffix);
122 cp = stpcpy (cp, ".tab");
123 cp = stpcpy (cp, limit);
124 }
125 }
126 else
127 name = stringappend (prefix, suffix);
1239777d 128
9b3add5b
RA
129 /* Prepare the next parser to be output. */
130 parser = xfopen (name, "w");
131 MUSCLE_INSERT_STRING ("parser-file-name", name);
132 XFREE (name);
133
134 ++skeleton_line;
135}
136;
137
138section.yacc : /* Empty. */ { $$ = 0; }
139 | YACC { $$ = 1; }
140;
141
1239777d 142section.body
9b3add5b
RA
143: /* Empty. */ { }
144| section.body '\n' { fputc ('\n', parser); ++output_line; ++skeleton_line; }
145| section.body LINE { fprintf (parser, "%d", output_line); }
146| section.body SLINE { fprintf (parser, "%d", skeleton_line); }
147| section.body GUARDS { guards_output (parser, &output_line); }
148| section.body TOKENS { token_definitions_output (parser, &output_line); }
149| section.body ACTIONS { actions_output (parser, &output_line); }
150| section.body CHARACTER { fputc ($2, parser); }
24fad99e
AD
151| section.body RAW { fputs ($2, parser); }
152| section.body BLANKS { fputs ($2, parser); }
1239777d 153| section.body MUSCLE {
9b3add5b
RA
154 const char* value = muscle_find ($2);
155 if (value)
156 {
157 fputs (value, parser);
158 output_line += get_lines_number (value);
159 }
160 else
161 {
162 fprintf (parser, "%%{%s}", $2);
163 merror ($2);
164 }
165}
166;
9b3add5b
RA
167%%
168
1239777d 169static int
9b3add5b
RA
170merror (const char* error)
171{
172 printf ("line %d: %%{%s} undeclared.\n", skeleton_line, error);
173 return 0;
174}
175
1239777d 176static int
9b3add5b
RA
177yyerror (const char* error)
178{
1239777d 179 fprintf (stderr, "%s\n", error);
9b3add5b
RA
180 return 0;
181}
182
1239777d
AD
183void
184process_skeleton (const char* skel)
9b3add5b 185{
9b3add5b
RA
186 /* Compute prefix. Actually, it seems that the processing I need here is
187 done in compute_base_names, and the result stored in short_base_name. */
188 prefix = short_base_name;
189
190 /* Prepare a few things. */
191 output_line = 1;
192 skeleton_line = 1;
193
194 /* Output. */
1239777d 195 yyin = fopen (skel, "r");
9b3add5b
RA
196 yydebug = 0;
197 yyparse ();
198
199 /* Close the last parser. */
200 if (parser)
201 parser = (xfclose (parser), NULL);
202}