]> git.saurik.com Git - bison.git/blame - src/parse-gram.y
* data/bison.simple, data/bison.c++: Be sure to restore the
[bison.git] / src / parse-gram.y
CommitLineData
e9955c83
AD
1/* Bison Grammar Parser -*- C -*-
2 Copyright (C) 2002 Free Software Foundation, Inc.
3
4 This file is part of Bison, the GNU Compiler Compiler.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA
20*/
21
22
23%debug
24%defines
25%locations
26%pure-parser
4cdb01db 27// %error-verbose
e9955c83
AD
28%defines
29%name-prefix="gram_"
30
31%{
32#include "system.h"
33#include "muscle_tab.h"
34#include "files.h"
35#include "getargs.h"
36#include "output.h"
37#include "gram.h"
38#include "reader.h"
39#include "conflicts.h"
40
4cdb01db
AD
41#define YYERROR_VERBOSE 1
42
e9955c83
AD
43/* Pass the control structure to YYPARSE and YYLEX. */
44#define YYPARSE_PARAM gram_control
45#define YYLEX_PARAM gram_control
46/* YYPARSE receives GRAM_CONTROL as a void *. Provide a
47 correctly typed access to it. */
48#define yycontrol ((gram_control_t *) gram_control)
49
50/* Request detailed parse error messages, and pass them to
51 GRAM_ERROR. */
52#undef yyerror
53#define yyerror(Msg) \
54 gram_error (yycontrol, &yylloc, Msg)
55
56/* When debugging our pure parser, we want to see values and locations
57 of the tokens. */
58#define YYPRINT(File, Type, Value) \
59 yyprint (File, &yylloc, Type, &Value)
60static void yyprint (FILE *file, const yyltype *loc,
61 int type, const yystype *value);
62
63symbol_class current_class = unknown_sym;
64char *current_type = 0;
65symbol_t *current_lhs;
66associativity current_assoc;
67int current_prec = 0;
68%}
69
70
71/* Only NUMBERS have a value. */
72%union
73{
74 symbol_t *symbol;
75 int integer;
76 char *string;
77 associativity assoc;
78};
79
80/* Define the tokens together with there human representation. */
81%token GRAM_EOF 0 "end of string"
82%token STRING CHARACTER
83%token INT
84
85%token PERCENT_TOKEN "%token"
86%token PERCENT_NTERM "%nterm"
87%token PERCENT_TYPE "%type"
88%token PERCENT_UNION "%union"
89%token PERCENT_EXPECT "%expect"
90%token PERCENT_START "%start"
91%token PERCENT_LEFT "%left"
92%token PERCENT_RIGHT "%right"
93%token PERCENT_NONASSOC "%nonassoc"
94%token PERCENT_PREC "%prec"
95%token PERCENT_VERBOSE "%verbose"
96%token PERCENT_ERROR_VERBOSE "%error-verbose"
97
98%token PERCENT_OUTPUT "%output"
99%token PERCENT_FILE_PREFIX "%file-prefix"
100%token PERCENT_NAME_PREFIX "%name-prefix"
101
102%token PERCENT_DEFINE "%define"
103%token PERCENT_PURE_PARSER "%pure-parser"
104
105%token PERCENT_DEFINES "%defines"
106
107%token PERCENT_YACC "%yacc"
108
109%token PERCENT_DEBUG "%debug"
110%token PERCENT_LOCATIONS "%locations"
111%token PERCENT_NO_LINES "%no-lines"
112%token PERCENT_SKELETON "%skeleton"
113%token PERCENT_TOKEN_TABLE "%token-table"
114
115%token TYPE
116%token EQUAL "="
117%token SEMICOLON ";"
118%token COLON ":"
119%token PIPE "|"
120%token ID "identifier"
121%token PERCENT_PERCENT "%%"
122%token PROLOGUE EPILOGUE
123%token BRACED_CODE
124
4cdb01db
AD
125%type <string> CHARACTER TYPE STRING string_content
126 BRACED_CODE PROLOGUE EPILOGUE epilogue.opt action
e9955c83
AD
127%type <integer> INT
128%type <symbol> ID symbol string_as_id
129%type <assoc> precedence_directive
130%%
131input: { LOCATION_RESET (yylloc); }
132 directives "%%" gram epilogue.opt
133 {
134 yycontrol->errcode = 0;
135 epilogue_set ($5, @5.first_line);
136 }
137;
138
139directives:
140 /* Nothing */
141| directives directive
142;
143
144directive:
145 grammar_directives
4cdb01db
AD
146| PROLOGUE
147 {
148 prologue_augment ($1, @1.first_line);
149 }
e9955c83
AD
150| "%debug" { debug_flag = 1; }
151| "%define" string_content string_content { muscle_insert ($2, $3); }
152| "%defines" { defines_flag = 1; }
153| "%error-verbose" { error_verbose = 1; }
154| "%expect" INT { expected_conflicts = $2; }
155| "%file-prefix" "=" string_content { spec_file_prefix = $3; }
156| "%locations" { locations_flag = 1; }
157| "%name-prefix" "=" string_content { spec_name_prefix = $3; }
158| "%no-lines" { no_lines_flag = 1; }
159| "%output" "=" string_content { spec_outfile = $3; }
160| "%pure-parser" { pure_parser = 1; }
161| "%skeleton" string_content { skeleton = $2; }
162| "%token-table" { token_table_flag = 1; }
163| "%verbose" { report_flag = 1; }
164| "%yacc" { yacc_flag = 1; }
165;
166
167grammar_directives:
168 precedence_directives
169| "%nterm" { current_class = nterm_sym; } symbol_defs.1
170 {
171 current_class = unknown_sym;
172 current_type = NULL;
173 }
174| "%start" symbol
175 {
176 grammar_start_symbol_set ($2);
177 }
178| "%token" { current_class = token_sym; } symbol_defs.1
179 {
180 current_class = unknown_sym;
181 current_type = NULL;
182 }
183| "%type" TYPE {current_type = $2; } nterms_to_type.1
184 {
185 current_type = NULL;
186 }
187| "%union" BRACED_CODE semi_colon_opt
188 {
189 typed = 1;
190 MUSCLE_INSERT_INT ("stype_line", @2.first_line);
191 muscle_insert ("stype", $2);
192 }
193;
194
195precedence_directives:
196 precedence_directive type.opt
197 { current_assoc = $1; ++current_prec; }
198 terms_to_prec.1
199 { current_assoc = non_assoc; current_type = NULL; }
200;
201
202precedence_directive:
203 "%left" { $$ = left_assoc; }
204| "%right" { $$ = right_assoc; }
205| "%nonassoc" { $$ = non_assoc; }
206;
207
208type.opt:
209 /* Nothing. */ { current_type = NULL;}
210| TYPE { current_type = $1; }
211;
212
213/* One or more nonterminals to be %typed. */
214nterms_to_type.1:
215 ID { symbol_type_set ($1, current_type); }
216| nterms_to_type.1 ID { symbol_type_set ($2, current_type); }
217;
218
219/* One or more symbols to be given a precedence/associativity. */
220terms_to_prec.1:
221 symbol
222 {
223 symbol_type_set ($1, current_type);
224 symbol_precedence_set ($1, current_prec, current_assoc);
225 }
226| terms_to_prec.1 symbol
227 {
228 symbol_type_set ($2, current_type);
229 symbol_precedence_set ($2, current_prec, current_assoc);
230 }
231;
232
233
234/* One token definition. */
235symbol_def:
236 TYPE
237 {
238 current_type = $1;
239 }
240| ID
241 {
242 symbol_class_set ($1, current_class);
243 symbol_type_set ($1, current_type);
244 }
245| ID INT
246 {
247 symbol_class_set ($1, current_class);
248 symbol_type_set ($1, current_type);
249 symbol_user_token_number_set ($1, $2);
250 }
251| ID string_as_id
252 {
253 symbol_class_set ($1, current_class);
254 symbol_type_set ($1, current_type);
255 symbol_make_alias ($1, $2);
256 }
257| ID INT string_as_id
258 {
259 symbol_class_set ($1, current_class);
260 symbol_type_set ($1, current_type);
261 symbol_user_token_number_set ($1, $2);
262 symbol_make_alias ($1, $3);
263 }
264;
265
266/* One or more symbol definitions. */
267symbol_defs.1:
268 symbol_def
269 {;}
270| symbol_defs.1 symbol_def
271 {;}
272;
273
274gram:
275 rules
276| gram rules
277;
278
279rules:
280 ID ":" { current_lhs = $1; } rhses.1 ";"
281 {;}
282;
283
284rhses.1:
285 rhs { grammar_rule_end (); }
286| rhses.1 "|" rhs { grammar_rule_end (); }
287;
288
289rhs:
290 /* Nothing. */
291 { grammar_rule_begin (current_lhs); }
292| rhs symbol
293 { grammar_current_rule_symbol_append ($2); }
294| rhs action
295 { grammar_current_rule_action_append ($2, @2.first_line); }
296| rhs "%prec" symbol
297 { grammar_current_rule_prec_set ($3); }
298;
299
300symbol:
301 ID { $$ = $1; }
302| string_as_id { $$ = $1; }
303| CHARACTER { $$ = getsym ($1); }
304;
305
306action:
307 BRACED_CODE
308 { $$ = $1; }
309;
310
311/* A string used as an ID: we have to keep the quotes. */
312string_as_id:
313 STRING
314 {
315 $$ = getsym ($1);
316 symbol_class_set ($$, token_sym);
317 }
318;
319
320/* A string used for its contents. Strip the quotes. */
321string_content:
322 STRING
323 {
324 $$ = $1 + 1;
325 $$[strlen ($$) - 1] = '\0';
326 };
327
328
329epilogue.opt:
330 /* Nothing. */
331 {
332 $$ = xstrdup ("");
333 }
334| "%%" EPILOGUE
335 {
336 $$ = $2;
337 }
338;
339
340semi_colon_opt:
341 /* Nothing. */
342| ";"
343;
344%%
345/*------------------------------------------------------------------.
346| When debugging the parser, display tokens' locations and values. |
347`------------------------------------------------------------------*/
348
349static void
350yyprint (FILE *file,
351 const yyltype *loc, int type, const yystype *value)
352{
353 fputs (" (", file);
354 LOCATION_PRINT (file, *loc);
355 fputs (")", file);
356 switch (type)
357 {
358 case CHARACTER:
359 fprintf (file, " = '%s'", value->string);
360 break;
361
362 case ID:
363 fprintf (file, " = %s", value->symbol->tag);
364 break;
365
366 case INT:
367 fprintf (file, " = %d", value->integer);
368 break;
369
370 case STRING:
371 fprintf (file, " = \"%s\"", value->string);
372 break;
373
374 case TYPE:
375 fprintf (file, " = <%s>", value->string);
376 break;
377
378 case BRACED_CODE:
379 case PROLOGUE:
380 case EPILOGUE:
381 fprintf (file, " = {{ %s }}", value->string);
382 break;
383 }
384}
385
386void
387gram_error (gram_control_t *control ATTRIBUTE_UNUSED,
388 yyltype *yylloc, const char *msg)
389{
390 LOCATION_PRINT (stderr, *yylloc);
391 fprintf (stderr, ": %s\n", msg);
392}