2 |
7u83 |
1 |
/*
|
|
|
2 |
Crown Copyright (c) 1997
|
|
|
3 |
|
|
|
4 |
This TenDRA(r) Computer Program is subject to Copyright
|
|
|
5 |
owned by the United Kingdom Secretary of State for Defence
|
|
|
6 |
acting through the Defence Evaluation and Research Agency
|
|
|
7 |
(DERA). It is made available to Recipients with a
|
|
|
8 |
royalty-free licence for its use, reproduction, transfer
|
|
|
9 |
to other parties and amendment for any purpose not excluding
|
|
|
10 |
product development provided that any such use et cetera
|
|
|
11 |
shall be deemed to be acceptance of the following conditions:-
|
|
|
12 |
|
|
|
13 |
(1) Its Recipients shall ensure that this Notice is
|
|
|
14 |
reproduced upon any copies or amended versions of it;
|
|
|
15 |
|
|
|
16 |
(2) Any amended version of it shall be clearly marked to
|
|
|
17 |
show both the nature of and the organisation responsible
|
|
|
18 |
for the relevant amendment or amendments;
|
|
|
19 |
|
|
|
20 |
(3) Its onward transfer from a recipient to another
|
|
|
21 |
party shall be deemed to be that party's acceptance of
|
|
|
22 |
these conditions;
|
|
|
23 |
|
|
|
24 |
(4) DERA gives no warranty or assurance as to its
|
|
|
25 |
quality or suitability for any purpose and DERA accepts
|
|
|
26 |
no liability whatsoever in relation to any use to which
|
|
|
27 |
it may be put.
|
|
|
28 |
*/
|
|
|
29 |
|
|
|
30 |
|
|
|
31 |
/*** main.c --- SID program main routine.
|
|
|
32 |
*
|
|
|
33 |
** Author: Steve Folkes <smf@hermes.mod.uk>
|
|
|
34 |
*
|
|
|
35 |
*** Commentary:
|
|
|
36 |
*
|
|
|
37 |
* This file implements the main function for SID. The main function just
|
|
|
38 |
* deals with exception handling. It calls the ``main_init'' function to
|
|
|
39 |
* initialise the error reporting routines and parse the command line
|
|
|
40 |
* arguments, and the ``main_1'' function to parse the grammar.
|
|
|
41 |
*
|
|
|
42 |
* The initialisation stuff should be trivial. The ``main_1'' function first
|
|
|
43 |
* parses the grammar and any language specific input files. The grammar
|
|
|
44 |
* parser is defined in the file "parser/parser.sid". The language specific
|
|
|
45 |
* file parsers are defined in the files "LANGUAGE-input/LANGUAGE-parser.sid".
|
|
|
46 |
*
|
|
|
47 |
* After reading in the grammar, and language specific information, it then
|
|
|
48 |
* calls various functions to manipulate the grammar. These functions are
|
|
|
49 |
* described in "transforms/grammar.[ch]".
|
|
|
50 |
*
|
|
|
51 |
* Finally, it calls an output function to output a program to recognise the
|
|
|
52 |
* grammar. The output functions are described in the
|
|
|
53 |
* "LANGUAGE-output/LANGUAGE-output.[ch]" files.
|
|
|
54 |
*
|
|
|
55 |
*** Change Log:
|
|
|
56 |
* $Log: main.c,v $
|
|
|
57 |
* Revision 1.2 1998/02/06 17:05:44 release
|
|
|
58 |
* Last minute pre-release polishing.
|
|
|
59 |
*
|
|
|
60 |
* Revision 1.1.1.1 1998/01/17 15:57:41 release
|
|
|
61 |
* First version to be checked into rolling release.
|
|
|
62 |
*
|
|
|
63 |
* Revision 1.13 1996/07/01 13:29:41 smf
|
|
|
64 |
* main.c:
|
|
|
65 |
* - updated version number.
|
|
|
66 |
*
|
|
|
67 |
* Revision 1.12 1996/07/01 09:36:04 smf
|
|
|
68 |
* main.c:
|
|
|
69 |
* - updated version numer.
|
|
|
70 |
*
|
|
|
71 |
* Revision 1.11 1996/06/28 15:12:34 smf
|
|
|
72 |
* main.c:
|
|
|
73 |
* - added extra information to version string;
|
|
|
74 |
* - added "build" mechanism for release system.
|
|
|
75 |
*
|
|
|
76 |
* Revision 1.10 1996/03/01 09:51:56 smf
|
|
|
77 |
* main.c:
|
|
|
78 |
* - updated version number.
|
|
|
79 |
*
|
|
|
80 |
* Revision 1.9 1996/02/29 09:53:26 smf
|
|
|
81 |
* main.c:
|
|
|
82 |
* - updated version number.
|
|
|
83 |
*
|
|
|
84 |
* Revision 1.8 1996/02/28 15:43:56 smf
|
|
|
85 |
* Updated version number in main.c.
|
|
|
86 |
* Modified build_sid to use new platform designation.
|
|
|
87 |
*
|
|
|
88 |
* Revision 1.7 1995/02/10 16:28:56 smf
|
|
|
89 |
* Fixed bugs "CR95_111.sid-inline-no-var-check" and "CR95_112.sid-lre-var-call".
|
|
|
90 |
* Updated version number.
|
|
|
91 |
*
|
|
|
92 |
* Revision 1.6 1994/12/23 09:44:18 smf
|
|
|
93 |
* Fixing "CR94_227.sid-exception-optimisation-bug" - updated version number.
|
|
|
94 |
*
|
|
|
95 |
* Revision 1.5 1994/12/15 09:55:01 smf
|
|
|
96 |
* Updated version to "1.9#4".
|
|
|
97 |
* Brought into line with OSSG C Coding Standards Document, as per
|
|
|
98 |
* "CR94_178.sid+tld-update".
|
|
|
99 |
*
|
|
|
100 |
* Revision 1.4 1994/11/11 11:35:40 smf
|
|
|
101 |
* Updated version number for bug fix CR94_127.sid-tail-rec.
|
|
|
102 |
*
|
|
|
103 |
* Revision 1.3 1994/08/22 09:34:15 smf
|
|
|
104 |
* Fixed bug DR114:ids-too-long.
|
|
|
105 |
*
|
|
|
106 |
* Revision 1.2 1994/08/18 13:42:35 smf
|
|
|
107 |
* Fixed bug "DR115:SID-shadow-error". Also modified "build_sid" to make
|
|
|
108 |
* parallel bug fixing simpler.
|
|
|
109 |
*
|
|
|
110 |
* Revision 1.1.1.1 1994/07/25 16:04:11 smf
|
|
|
111 |
* Initial import of SID 1.8 non shared files.
|
|
|
112 |
*
|
|
|
113 |
**/
|
|
|
114 |
|
|
|
115 |
/****************************************************************************/
|
|
|
116 |
|
|
|
117 |
#include "os-interface.h"
|
|
|
118 |
#include "release.h"
|
|
|
119 |
#include "arg-parse.h"
|
|
|
120 |
#include "c-check.h"
|
|
|
121 |
#include "c-lexer.h"
|
|
|
122 |
#include "c-output.h"
|
|
|
123 |
#include "c-parser.h"
|
|
|
124 |
#include "cstring.h"
|
|
|
125 |
#include "cstring-list.h"
|
|
|
126 |
#include "dstring.h"
|
|
|
127 |
#include "error.h"
|
|
|
128 |
#include "error-file.h"
|
|
|
129 |
#include "exception.h"
|
|
|
130 |
#include "gen-errors.h"
|
|
|
131 |
#include "grammar.h"
|
|
|
132 |
#include "istream.h"
|
|
|
133 |
#include "lexer.h"
|
|
|
134 |
#include "ostream.h"
|
|
|
135 |
#include "output.h"
|
|
|
136 |
#include "parser.h"
|
|
|
137 |
#include "rule.h"
|
|
|
138 |
#include "syntax.h"
|
|
|
139 |
|
|
|
140 |
/*--------------------------------------------------------------------------*/
|
|
|
141 |
|
|
|
142 |
#define USAGE "\
|
|
|
143 |
\tusage: [option ...] in-file ... out-file ...\n\
|
|
|
144 |
\twhere option is one of:"
|
|
|
145 |
#ifndef VERSION
|
|
|
146 |
#define VERSION "sid: version 1.9#13 (ansi-c, pre-ansi-c, ossg-c, test)"
|
|
|
147 |
#endif /* !defined (VERSION) */
|
|
|
148 |
#ifndef RELEASE
|
|
|
149 |
#define RELEASE "unknown"
|
|
|
150 |
#endif /* !defined (RELEASE) */
|
|
|
151 |
#ifndef BANNER
|
|
|
152 |
#define BANNER ""
|
|
|
153 |
#endif /* !defined (BANNER) */
|
|
|
154 |
|
|
|
155 |
/*--------------------------------------------------------------------------*/
|
|
|
156 |
|
|
|
157 |
typedef struct PhaseListT {
|
|
|
158 |
CStringP phase;
|
|
|
159 |
void (*proc) PROTO_S ((BoolT));
|
|
|
160 |
} PhaseListT, *PhaseListP;
|
|
|
161 |
|
|
|
162 |
typedef struct LangListT {
|
|
|
163 |
CStringP language;
|
|
|
164 |
GenericP (*init_proc) PROTO_S ((OutputInfoP,
|
|
|
165 |
CStringListP));
|
|
|
166 |
void (*input_proc) PROTO_S ((GenericP, GrammarP));
|
|
|
167 |
unsigned num_input_files;
|
|
|
168 |
void (*output_proc) PROTO_S ((GenericP, GrammarP));
|
|
|
169 |
unsigned num_output_files;
|
|
|
170 |
} LangListT, *LangListP;
|
|
|
171 |
|
|
|
172 |
/*--------------------------------------------------------------------------*/
|
|
|
173 |
|
|
|
174 |
static void
|
|
|
175 |
main_handle_phase_all PROTO_N ((enable))
|
|
|
176 |
PROTO_T (BoolT enable)
|
|
|
177 |
{
|
|
|
178 |
rule_set_inline_singles (enable);
|
|
|
179 |
rule_set_inline_tail_calls (enable);
|
|
|
180 |
rule_set_inline_all_basics (enable);
|
|
|
181 |
rule_set_inline_non_tail_calls (enable);
|
|
|
182 |
rule_set_multiple_inlining (enable);
|
|
|
183 |
}
|
|
|
184 |
|
|
|
185 |
/*--------------------------------------------------------------------------*/
|
|
|
186 |
|
|
|
187 |
static GenericP
|
|
|
188 |
main_init_c PROTO_N ((out_info, options, ansi, ossg))
|
|
|
189 |
PROTO_T (OutputInfoP out_info X
|
|
|
190 |
CStringListP options X
|
|
|
191 |
BoolT ansi X
|
|
|
192 |
BoolT ossg )
|
|
|
193 |
{
|
|
|
194 |
COutputInfoP c_out_info = ALLOCATE (COutputInfoT);
|
|
|
195 |
CStringListEntryP entry;
|
|
|
196 |
|
|
|
197 |
c_out_info_init (c_out_info, out_info);
|
|
|
198 |
if (ansi) {
|
|
|
199 |
c_out_info_set_prototypes (c_out_info, TRUE);
|
|
|
200 |
}
|
|
|
201 |
if (ossg) {
|
|
|
202 |
c_out_info_set_ossg (c_out_info, TRUE);
|
|
|
203 |
}
|
|
|
204 |
for (entry = cstring_list_head (options); entry;
|
|
|
205 |
entry = cstring_list_entry_deallocate (entry)) {
|
|
|
206 |
CStringP option = cstring_list_entry_string (entry);
|
|
|
207 |
|
|
|
208 |
if (cstring_equal (option, "prototypes") ||
|
|
|
209 |
cstring_equal (option, "proto")) {
|
|
|
210 |
c_out_info_set_prototypes (c_out_info, TRUE);
|
|
|
211 |
c_out_info_set_ossg (c_out_info, FALSE);
|
|
|
212 |
} else if (cstring_equal (option, "no-prototypes") ||
|
|
|
213 |
cstring_equal (option, "no-proto")) {
|
|
|
214 |
c_out_info_set_prototypes (c_out_info, FALSE);
|
|
|
215 |
c_out_info_set_ossg (c_out_info, FALSE);
|
|
|
216 |
} else if (cstring_equal (option, "ossg-prototypes") ||
|
|
|
217 |
cstring_equal (option, "ossg-proto")) {
|
|
|
218 |
c_out_info_set_prototypes (c_out_info, TRUE);
|
|
|
219 |
c_out_info_set_ossg (c_out_info, TRUE);
|
|
|
220 |
} else if (cstring_equal (option, "split")) {
|
|
|
221 |
c_out_info_set_split (c_out_info, (unsigned) 5000);
|
|
|
222 |
} else if (cstring_starts (option, "split=")) {
|
|
|
223 |
unsigned limit;
|
|
|
224 |
if (!cstring_to_unsigned (option + 6, &limit)) {
|
|
|
225 |
E_bad_split_size (option + 6);
|
|
|
226 |
UNREACHED;
|
|
|
227 |
}
|
|
|
228 |
c_out_info_set_split (c_out_info, limit);
|
|
|
229 |
} else if (cstring_equal (option, "no-split")) {
|
|
|
230 |
c_out_info_set_split (c_out_info, (unsigned) 0);
|
|
|
231 |
} else if (cstring_equal (option, "numeric-ids") ||
|
|
|
232 |
cstring_equal (option, "numeric")) {
|
|
|
233 |
c_out_info_set_numeric_ids (c_out_info, TRUE);
|
|
|
234 |
} else if (cstring_equal (option, "no-numeric-ids") ||
|
|
|
235 |
cstring_equal (option, "no-numeric")) {
|
|
|
236 |
c_out_info_set_numeric_ids (c_out_info, FALSE);
|
|
|
237 |
} else if (cstring_equal (option, "casts") ||
|
|
|
238 |
cstring_equal (option, "cast")) {
|
|
|
239 |
c_out_info_set_casts (c_out_info, TRUE);
|
|
|
240 |
} else if (cstring_equal (option, "no-casts") ||
|
|
|
241 |
cstring_equal (option, "no-cast")) {
|
|
|
242 |
c_out_info_set_casts (c_out_info, FALSE);
|
|
|
243 |
} else if (cstring_equal (option, "unreachable-macros") ||
|
|
|
244 |
cstring_equal (option, "unreachable-macro")) {
|
|
|
245 |
c_out_info_set_unreachable (c_out_info, TRUE);
|
|
|
246 |
} else if (cstring_equal (option, "unreachable-comments") ||
|
|
|
247 |
cstring_equal (option, "unreachable-comment")) {
|
|
|
248 |
c_out_info_set_unreachable (c_out_info, FALSE);
|
|
|
249 |
} else if (cstring_equal (option, "lines") ||
|
|
|
250 |
cstring_equal (option, "line")) {
|
|
|
251 |
c_out_info_set_lines (c_out_info, TRUE);
|
|
|
252 |
} else if (cstring_equal (option, "no-lines") ||
|
|
|
253 |
cstring_equal (option, "no-line")) {
|
|
|
254 |
c_out_info_set_lines (c_out_info, FALSE);
|
|
|
255 |
} else {
|
|
|
256 |
CStringP lang ;
|
|
|
257 |
lang = (ossg ? "ossg-c" : (ansi ? "ansi-c" : "pre-ansi-c"));
|
|
|
258 |
E_bad_language_option (lang, option);
|
|
|
259 |
}
|
|
|
260 |
}
|
|
|
261 |
return ((GenericP) c_out_info);
|
|
|
262 |
}
|
|
|
263 |
|
|
|
264 |
static GenericP
|
|
|
265 |
main_init_ansi_c PROTO_N ((out_info, options))
|
|
|
266 |
PROTO_T (OutputInfoP out_info X
|
|
|
267 |
CStringListP options)
|
|
|
268 |
{
|
|
|
269 |
return (main_init_c (out_info, options, TRUE, FALSE));
|
|
|
270 |
}
|
|
|
271 |
|
|
|
272 |
static GenericP
|
|
|
273 |
main_init_pre_ansi_c PROTO_N ((out_info, options))
|
|
|
274 |
PROTO_T (OutputInfoP out_info X
|
|
|
275 |
CStringListP options)
|
|
|
276 |
{
|
|
|
277 |
return (main_init_c (out_info, options, FALSE, FALSE));
|
|
|
278 |
}
|
|
|
279 |
|
|
|
280 |
static GenericP
|
|
|
281 |
main_init_ossg_c PROTO_N ((out_info, options))
|
|
|
282 |
PROTO_T (OutputInfoP out_info X
|
|
|
283 |
CStringListP options)
|
|
|
284 |
{
|
|
|
285 |
return (main_init_c (out_info, options, TRUE, TRUE));
|
|
|
286 |
}
|
|
|
287 |
|
|
|
288 |
static void
|
|
|
289 |
main_input_c PROTO_N ((gclosure, grammar))
|
|
|
290 |
PROTO_T (GenericP gclosure X
|
|
|
291 |
GrammarP grammar)
|
|
|
292 |
{
|
|
|
293 |
COutputInfoP c_out_info = (COutputInfoP) gclosure;
|
|
|
294 |
OutputInfoP out_info = c_out_info_info (c_out_info);
|
|
|
295 |
CLexerStreamT clstream;
|
|
|
296 |
|
|
|
297 |
c_lexer_init (&clstream, out_info_get_istream (out_info, (unsigned) 1));
|
|
|
298 |
c_current_stream = &clstream;
|
|
|
299 |
c_current_out_info = c_out_info;
|
|
|
300 |
c_current_table = grammar_table (grammar);
|
|
|
301 |
c_parse_grammar ();
|
|
|
302 |
c_lexer_close (&clstream);
|
|
|
303 |
if (error_max_reported_severity () >= ERROR_SEVERITY_ERROR) {
|
|
|
304 |
exit (EXIT_FAILURE);
|
|
|
305 |
UNREACHED;
|
|
|
306 |
}
|
|
|
307 |
c_check_grammar (grammar);
|
|
|
308 |
}
|
|
|
309 |
|
|
|
310 |
static void
|
|
|
311 |
main_output_c PROTO_N ((gclosure, grammar))
|
|
|
312 |
PROTO_T (GenericP gclosure X
|
|
|
313 |
GrammarP grammar)
|
|
|
314 |
{
|
|
|
315 |
COutputInfoP c_out_info = (COutputInfoP) gclosure;
|
|
|
316 |
|
|
|
317 |
grammar_compute_mutations (grammar);
|
|
|
318 |
out_info_set_current_ostream (c_out_info_info (c_out_info), (unsigned) 0);
|
|
|
319 |
c_output_parser (c_out_info, grammar);
|
|
|
320 |
out_info_set_current_ostream (c_out_info_info (c_out_info), (unsigned) 1);
|
|
|
321 |
c_output_header (c_out_info, grammar);
|
|
|
322 |
}
|
|
|
323 |
|
|
|
324 |
static GenericP
|
|
|
325 |
main_init_test PROTO_N ((info, options))
|
|
|
326 |
PROTO_T (OutputInfoP info X
|
|
|
327 |
CStringListP options)
|
|
|
328 |
{
|
|
|
329 |
CStringListEntryP entry;
|
|
|
330 |
|
|
|
331 |
UNUSED (info);
|
|
|
332 |
for (entry = cstring_list_head (options); entry;
|
|
|
333 |
entry = cstring_list_entry_deallocate (entry)) {
|
|
|
334 |
CStringP option = cstring_list_entry_string (entry);
|
|
|
335 |
|
|
|
336 |
E_bad_language_option ("test", option);
|
|
|
337 |
}
|
|
|
338 |
return (NIL (GenericP));
|
|
|
339 |
}
|
|
|
340 |
|
|
|
341 |
static void
|
|
|
342 |
main_input_test PROTO_N ((gclosure, grammar))
|
|
|
343 |
PROTO_T (GenericP gclosure X
|
|
|
344 |
GrammarP grammar)
|
|
|
345 |
{
|
|
|
346 |
UNUSED (gclosure);
|
|
|
347 |
UNUSED (grammar);
|
|
|
348 |
}
|
|
|
349 |
|
|
|
350 |
static void
|
|
|
351 |
main_output_test PROTO_N ((gclosure, grammar))
|
|
|
352 |
PROTO_T (GenericP gclosure X
|
|
|
353 |
GrammarP grammar)
|
|
|
354 |
{
|
|
|
355 |
UNUSED (gclosure);
|
|
|
356 |
UNUSED (grammar);
|
|
|
357 |
}
|
|
|
358 |
|
|
|
359 |
/*--------------------------------------------------------------------------*/
|
|
|
360 |
|
|
|
361 |
static BoolT main_did_one_off = FALSE;
|
|
|
362 |
static BoolT main_did_other = FALSE;
|
|
|
363 |
|
|
|
364 |
static OutputInfoP main_info_closure;
|
|
|
365 |
|
|
|
366 |
static CStringListT main_language_options;
|
|
|
367 |
|
|
|
368 |
static OStreamT dump_stream;
|
|
|
369 |
|
|
|
370 |
static PhaseListT main_phase_list [] = {
|
|
|
371 |
{"singles", rule_set_inline_singles},
|
|
|
372 |
{"tail", rule_set_inline_tail_calls},
|
|
|
373 |
{"basics", rule_set_inline_all_basics},
|
|
|
374 |
{"other", rule_set_inline_non_tail_calls},
|
|
|
375 |
{"multi", rule_set_multiple_inlining},
|
|
|
376 |
{"all", main_handle_phase_all},
|
|
|
377 |
{NIL (CStringP), NIL (void (*) PROTO_S ((BoolT)))}
|
|
|
378 |
};
|
|
|
379 |
|
|
|
380 |
static LangListT main_language_list [] = {
|
|
|
381 |
{"ansi-c", main_init_ansi_c, main_input_c, 2, main_output_c, 2},
|
|
|
382 |
{"pre-ansi-c", main_init_pre_ansi_c, main_input_c, 2, main_output_c, 2},
|
|
|
383 |
{"iso-c", main_init_ansi_c, main_input_c, 2, main_output_c, 2},
|
|
|
384 |
{"pre-iso-c", main_init_pre_ansi_c, main_input_c, 2, main_output_c, 2},
|
|
|
385 |
{"ossg-c", main_init_ossg_c, main_input_c, 2, main_output_c, 2},
|
|
|
386 |
{"test", main_init_test, main_input_test, 1, main_output_test, 0},
|
|
|
387 |
{NIL (CStringP), NIL (GenericP (*) PROTO_S ((OutputInfoP, CStringListP))),
|
|
|
388 |
NIL (void (*) PROTO_S ((GenericP, GrammarP))), 0,
|
|
|
389 |
NIL (void (*) PROTO_S ((GenericP, GrammarP))), 0}
|
|
|
390 |
};
|
|
|
391 |
|
|
|
392 |
static LangListP main_language = &(main_language_list [0]);
|
|
|
393 |
|
|
|
394 |
/*--------------------------------------------------------------------------*/
|
|
|
395 |
|
|
|
396 |
static void
|
|
|
397 |
main_handle_dump_file PROTO_N ((option, usage, gclosure, dump_file))
|
|
|
398 |
PROTO_T (CStringP option X
|
|
|
399 |
ArgUsageP usage X
|
|
|
400 |
GenericP gclosure X
|
|
|
401 |
CStringP dump_file)
|
|
|
402 |
{
|
|
|
403 |
UNUSED (option);
|
|
|
404 |
UNUSED (usage);
|
|
|
405 |
UNUSED (gclosure);
|
|
|
406 |
main_did_other = TRUE;
|
|
|
407 |
if (ostream_is_open (&dump_stream)) {
|
|
|
408 |
E_multiple_dump_files ();
|
|
|
409 |
UNREACHED;
|
|
|
410 |
} else if (!ostream_open (&dump_stream, dump_file)) {
|
|
|
411 |
E_cannot_open_dump_file (dump_file);
|
|
|
412 |
UNREACHED;
|
|
|
413 |
}
|
|
|
414 |
}
|
|
|
415 |
|
|
|
416 |
static void
|
|
|
417 |
main_handle_help PROTO_N ((option, usage, gclosure))
|
|
|
418 |
PROTO_T (CStringP option X
|
|
|
419 |
ArgUsageP usage X
|
|
|
420 |
GenericP gclosure)
|
|
|
421 |
{
|
|
|
422 |
UNUSED (option);
|
|
|
423 |
UNUSED (gclosure);
|
|
|
424 |
main_did_one_off = TRUE;
|
|
|
425 |
write_arg_usage (ostream_error, usage);
|
|
|
426 |
write_newline (ostream_error);
|
|
|
427 |
ostream_flush (ostream_error);
|
|
|
428 |
}
|
|
|
429 |
|
|
|
430 |
static void
|
|
|
431 |
main_handle_factor_limit PROTO_N ((option, usage, gclosure, limit_str))
|
|
|
432 |
PROTO_T (CStringP option X
|
|
|
433 |
ArgUsageP usage X
|
|
|
434 |
GenericP gclosure X
|
|
|
435 |
CStringP limit_str)
|
|
|
436 |
{
|
|
|
437 |
unsigned limit;
|
|
|
438 |
|
|
|
439 |
UNUSED (option);
|
|
|
440 |
UNUSED (usage);
|
|
|
441 |
UNUSED (gclosure);
|
|
|
442 |
main_did_other = TRUE;
|
|
|
443 |
if ((!cstring_to_unsigned (limit_str, &limit)) || (limit == 0)) {
|
|
|
444 |
E_bad_factor_limit (limit_str);
|
|
|
445 |
UNREACHED;
|
|
|
446 |
}
|
|
|
447 |
rule_set_factor_limit (limit);
|
|
|
448 |
}
|
|
|
449 |
|
|
|
450 |
static void
|
|
|
451 |
main_handle_inlining PROTO_N ((option, usage, gclosure, inline_str))
|
|
|
452 |
PROTO_T (CStringP option X
|
|
|
453 |
ArgUsageP usage X
|
|
|
454 |
GenericP gclosure X
|
|
|
455 |
CStringP inline_str)
|
|
|
456 |
{
|
|
|
457 |
UNUSED (option);
|
|
|
458 |
UNUSED (usage);
|
|
|
459 |
UNUSED (gclosure);
|
|
|
460 |
main_did_other = TRUE;
|
|
|
461 |
while (*inline_str) {
|
|
|
462 |
BoolT enable = TRUE;
|
|
|
463 |
DStringT dstring;
|
|
|
464 |
CStringP phase;
|
|
|
465 |
PhaseListP entry;
|
|
|
466 |
|
|
|
467 |
if ((syntax_downcase (inline_str [0]) == 'n') &&
|
|
|
468 |
(syntax_downcase (inline_str [1]) == 'o')) {
|
|
|
469 |
inline_str += 2;
|
|
|
470 |
enable = FALSE;
|
|
|
471 |
}
|
|
|
472 |
dstring_init (&dstring);
|
|
|
473 |
while ((*inline_str) && (*inline_str != ',')) {
|
|
|
474 |
dstring_append_char (&dstring, syntax_downcase (*inline_str ++));
|
|
|
475 |
}
|
|
|
476 |
if (*inline_str == ',') {
|
|
|
477 |
inline_str ++;
|
|
|
478 |
}
|
|
|
479 |
phase = dstring_destroy_to_cstring (&dstring);
|
|
|
480 |
for (entry = main_phase_list; entry->phase; entry ++) {
|
|
|
481 |
if (cstring_equal (phase, entry->phase)) {
|
|
|
482 |
if (entry->proc) {
|
|
|
483 |
(*(entry->proc)) (enable);
|
|
|
484 |
}
|
|
|
485 |
goto next;
|
|
|
486 |
}
|
|
|
487 |
}
|
|
|
488 |
E_bad_inlining_phase (phase);
|
|
|
489 |
UNREACHED;
|
|
|
490 |
next:;
|
|
|
491 |
}
|
|
|
492 |
}
|
|
|
493 |
|
|
|
494 |
static void
|
|
|
495 |
main_handle_language PROTO_N ((option, usage, gclosure, language_str))
|
|
|
496 |
PROTO_T (CStringP option X
|
|
|
497 |
ArgUsageP usage X
|
|
|
498 |
GenericP gclosure X
|
|
|
499 |
CStringP language_str)
|
|
|
500 |
{
|
|
|
501 |
LangListP entry;
|
|
|
502 |
|
|
|
503 |
UNUSED (option);
|
|
|
504 |
UNUSED (usage);
|
|
|
505 |
UNUSED (gclosure);
|
|
|
506 |
main_did_other = TRUE;
|
|
|
507 |
for (entry = main_language_list; entry->language; entry ++) {
|
|
|
508 |
if (cstring_equal (language_str, entry->language)) {
|
|
|
509 |
main_language = entry;
|
|
|
510 |
return;
|
|
|
511 |
}
|
|
|
512 |
}
|
|
|
513 |
E_bad_language (language_str);
|
|
|
514 |
UNREACHED;
|
|
|
515 |
}
|
|
|
516 |
|
|
|
517 |
static void
|
|
|
518 |
main_handle_show_errors PROTO_N ((option, usage, gclosure))
|
|
|
519 |
PROTO_T (CStringP option X
|
|
|
520 |
ArgUsageP usage X
|
|
|
521 |
GenericP gclosure)
|
|
|
522 |
{
|
|
|
523 |
UNUSED (option);
|
|
|
524 |
UNUSED (usage);
|
|
|
525 |
UNUSED (gclosure);
|
|
|
526 |
main_did_one_off = TRUE;
|
|
|
527 |
write_error_file (ostream_output);
|
|
|
528 |
ostream_flush (ostream_output);
|
|
|
529 |
}
|
|
|
530 |
|
|
|
531 |
static void
|
|
|
532 |
main_handle_switch PROTO_N ((option, usage, gclosure, opt))
|
|
|
533 |
PROTO_T (CStringP option X
|
|
|
534 |
ArgUsageP usage X
|
|
|
535 |
GenericP gclosure X
|
|
|
536 |
CStringP opt)
|
|
|
537 |
{
|
|
|
538 |
UNUSED (option);
|
|
|
539 |
UNUSED (usage);
|
|
|
540 |
UNUSED (gclosure);
|
|
|
541 |
main_did_other = TRUE;
|
|
|
542 |
cstring_list_append (&main_language_options, opt);
|
|
|
543 |
}
|
|
|
544 |
|
|
|
545 |
static void
|
|
|
546 |
main_handle_tab_width PROTO_N ((option, usage, gclosure, width_str))
|
|
|
547 |
PROTO_T (CStringP option X
|
|
|
548 |
ArgUsageP usage X
|
|
|
549 |
GenericP gclosure X
|
|
|
550 |
CStringP width_str)
|
|
|
551 |
{
|
|
|
552 |
unsigned width;
|
|
|
553 |
|
|
|
554 |
UNUSED (option);
|
|
|
555 |
UNUSED (usage);
|
|
|
556 |
UNUSED (gclosure);
|
|
|
557 |
main_did_other = TRUE;
|
|
|
558 |
if ((!cstring_to_unsigned (width_str, &width)) || (width == 0)) {
|
|
|
559 |
E_bad_tab_width (width_str);
|
|
|
560 |
UNREACHED;
|
|
|
561 |
}
|
|
|
562 |
out_info_set_tab_width (main_info_closure, width);
|
|
|
563 |
}
|
|
|
564 |
|
|
|
565 |
static void
|
|
|
566 |
main_handle_version PROTO_N ((option, usage, gclosure))
|
|
|
567 |
PROTO_T (CStringP option X
|
|
|
568 |
ArgUsageP usage X
|
|
|
569 |
GenericP gclosure)
|
|
|
570 |
{
|
|
|
571 |
UNUSED (option);
|
|
|
572 |
UNUSED (usage);
|
|
|
573 |
UNUSED (gclosure);
|
|
|
574 |
main_did_one_off = TRUE;
|
|
|
575 |
write_cstring (ostream_error, VERSION);
|
|
|
576 |
write_cstring (ostream_error, " (Release ");
|
|
|
577 |
write_cstring (ostream_error, RELEASE);
|
|
|
578 |
write_cstring (ostream_error, ")");
|
|
|
579 |
write_cstring (ostream_error, BANNER);
|
|
|
580 |
write_newline (ostream_error);
|
|
|
581 |
ostream_flush (ostream_error);
|
|
|
582 |
}
|
|
|
583 |
|
|
|
584 |
/*--------------------------------------------------------------------------*/
|
|
|
585 |
|
|
|
586 |
static EStringDataT main_description_strings [] = {
|
|
|
587 |
UB {
|
|
|
588 |
"description of dump-file",
|
|
|
589 |
" FILE\n\tCause intermediate grammars to be written to FILE."
|
|
|
590 |
} UE, UB {
|
|
|
591 |
"description of help",
|
|
|
592 |
"\n\tDisplay an option summary for the current mode."
|
|
|
593 |
} UE, UB {
|
|
|
594 |
"description of factor-limit",
|
|
|
595 |
" NUMBER\n\tSet the maximum number of rules to be generated during factorisation."
|
|
|
596 |
} UE, UB {
|
|
|
597 |
"description of inlining",
|
|
|
598 |
" INLINES\n\tSet which classes of rule are inlined.\n\tShould be any of 'SINGLES', 'BASICS', 'TAIL', 'OTHER', 'MULTI', or 'ALL'."
|
|
|
599 |
} UE, UB {
|
|
|
600 |
"description of language",
|
|
|
601 |
" LANGUAGE\n\tSet the language for the output parser."
|
|
|
602 |
} UE, UB {
|
|
|
603 |
"description of show-errors",
|
|
|
604 |
"\n\tDisplay the current error table on the standard output."
|
|
|
605 |
} UE, UB {
|
|
|
606 |
"description of switch",
|
|
|
607 |
" OPTION\n\tPass OPTION to language specific option parser."
|
|
|
608 |
} UE, UB {
|
|
|
609 |
"description of tab-width",
|
|
|
610 |
" NUMBER\n\tSet the number of spaces in a tab character."
|
|
|
611 |
} UE, UB {
|
|
|
612 |
"description of version",
|
|
|
613 |
"\n\tDisplay the version number on the standard error."
|
|
|
614 |
} UE, ERROR_END_STRING_LIST
|
|
|
615 |
};
|
|
|
616 |
|
|
|
617 |
#ifdef __TenDRA__
|
|
|
618 |
/* Some conversions to ArgProcP are slightly suspect */
|
|
|
619 |
#pragma TenDRA begin
|
|
|
620 |
#pragma TenDRA conversion analysis (pointer-pointer) off
|
|
|
621 |
#endif
|
|
|
622 |
|
|
|
623 |
static ArgListT main_arglist [] = {
|
|
|
624 |
{
|
|
|
625 |
"dump-file", 'd', AT_FOLLOWING,
|
|
|
626 |
(ArgProcP) main_handle_dump_file, NIL (GenericP),
|
|
|
627 |
UB "description of dump-file" UE
|
|
|
628 |
}, {
|
|
|
629 |
"factor-limit", 'f', AT_FOLLOWING,
|
|
|
630 |
(ArgProcP) main_handle_factor_limit, NIL (GenericP),
|
|
|
631 |
UB "description of factor-limit" UE
|
|
|
632 |
}, {
|
|
|
633 |
"help", '?', AT_EMPTY,
|
|
|
634 |
(ArgProcP) main_handle_help, NIL (GenericP),
|
|
|
635 |
UB "description of help" UE
|
|
|
636 |
}, {
|
|
|
637 |
"inline", 'i', AT_FOLLOWING,
|
|
|
638 |
(ArgProcP) main_handle_inlining, NIL (GenericP),
|
|
|
639 |
UB "description of inlining" UE
|
|
|
640 |
}, {
|
|
|
641 |
"language", 'l', AT_FOLLOWING,
|
|
|
642 |
(ArgProcP) main_handle_language, NIL (GenericP),
|
|
|
643 |
UB "description of language" UE
|
|
|
644 |
}, {
|
|
|
645 |
"show-errors", 'e', AT_EMPTY,
|
|
|
646 |
(ArgProcP) main_handle_show_errors, NIL (GenericP),
|
|
|
647 |
UB "description of show-errors" UE
|
|
|
648 |
}, {
|
|
|
649 |
"switch", 's', AT_FOLLOWING,
|
|
|
650 |
(ArgProcP) main_handle_switch, NIL (GenericP),
|
|
|
651 |
UB "description of switch" UE
|
|
|
652 |
}, {
|
|
|
653 |
"tab-width", 't', AT_FOLLOWING,
|
|
|
654 |
(ArgProcP) main_handle_tab_width, NIL (GenericP),
|
|
|
655 |
UB "description of tab-width" UE
|
|
|
656 |
}, {
|
|
|
657 |
"version", 'v', AT_EMPTY,
|
|
|
658 |
(ArgProcP) main_handle_version, NIL (GenericP),
|
|
|
659 |
UB "description of version" UE
|
|
|
660 |
}, ARG_PARSE_END_LIST
|
|
|
661 |
};
|
|
|
662 |
|
|
|
663 |
#ifdef __TenDRA__
|
|
|
664 |
#pragma TenDRA end
|
|
|
665 |
#endif
|
|
|
666 |
|
|
|
667 |
/*--------------------------------------------------------------------------*/
|
|
|
668 |
|
|
|
669 |
static void
|
|
|
670 |
main_init PROTO_N ((argc, argv, out_info))
|
|
|
671 |
PROTO_T (int argc X
|
|
|
672 |
char **argv X
|
|
|
673 |
OutputInfoP out_info)
|
|
|
674 |
{
|
|
|
675 |
EStringP usage_estring = error_define_string ("sid usage message", USAGE);
|
|
|
676 |
ArgUsageT closure;
|
|
|
677 |
CStringP error_file;
|
|
|
678 |
int skip;
|
|
|
679 |
unsigned i;
|
|
|
680 |
unsigned num_infiles;
|
|
|
681 |
unsigned num_outfiles;
|
|
|
682 |
|
|
|
683 |
error_init (argv [0], gen_errors_init_errors);
|
|
|
684 |
error_intern_strings (main_description_strings);
|
|
|
685 |
if ((error_file = getenv ("SID_ERROR_FILE")) != NIL (CStringP)) {
|
|
|
686 |
error_file_parse (error_file, FALSE);
|
|
|
687 |
}
|
|
|
688 |
closure.usage = error_string_contents (usage_estring);
|
|
|
689 |
closure.arg_list = main_arglist;
|
|
|
690 |
main_info_closure = out_info;
|
|
|
691 |
arg_parse_intern_descriptions (main_arglist);
|
|
|
692 |
skip = arg_parse_arguments (main_arglist, usage_estring, -- argc, ++ argv);
|
|
|
693 |
argc -= skip;
|
|
|
694 |
argv += skip;
|
|
|
695 |
if (main_did_one_off && (!main_did_other) && (argc == 0)) {
|
|
|
696 |
exit (EXIT_SUCCESS);
|
|
|
697 |
UNREACHED;
|
|
|
698 |
}
|
|
|
699 |
num_infiles = main_language->num_input_files;
|
|
|
700 |
num_outfiles = main_language->num_output_files;
|
|
|
701 |
if ((unsigned) argc != (num_infiles + num_outfiles)) {
|
|
|
702 |
E_usage (main_language->language, num_infiles, num_outfiles, &closure);
|
|
|
703 |
UNREACHED;
|
|
|
704 |
}
|
|
|
705 |
out_info_set_num_input_files (out_info, num_infiles);
|
|
|
706 |
out_info_set_num_output_files (out_info, num_outfiles);
|
|
|
707 |
for (i = 0; i < num_infiles; i ++) {
|
|
|
708 |
CStringP name = argv [i];
|
|
|
709 |
if (!istream_open (out_info_get_istream (out_info, i), name)) {
|
|
|
710 |
E_cannot_open_input_file (name);
|
|
|
711 |
UNREACHED;
|
|
|
712 |
}
|
|
|
713 |
out_info_set_infile_name (out_info, i, name);
|
|
|
714 |
}
|
|
|
715 |
for (i = 0; i < num_outfiles; i ++) {
|
|
|
716 |
CStringP name = argv [num_infiles + i];
|
|
|
717 |
if (!ostream_open (out_info_get_ostream (out_info, i), name)) {
|
|
|
718 |
E_cannot_open_output_file (name);
|
|
|
719 |
UNREACHED;
|
|
|
720 |
}
|
|
|
721 |
out_info_set_outfile_name (out_info, i, name);
|
|
|
722 |
}
|
|
|
723 |
}
|
|
|
724 |
|
|
|
725 |
static void
|
|
|
726 |
main_dump_grammar PROTO_N ((dstream, grammar, mesg))
|
|
|
727 |
PROTO_T (OStreamP dstream X
|
|
|
728 |
GrammarP grammar X
|
|
|
729 |
CStringP mesg)
|
|
|
730 |
{
|
|
|
731 |
if (dstream) {
|
|
|
732 |
write_cstring (dstream, mesg);
|
|
|
733 |
write_newline (dstream);
|
|
|
734 |
write_newline (dstream);
|
|
|
735 |
write_grammar (dstream, grammar);
|
|
|
736 |
}
|
|
|
737 |
}
|
|
|
738 |
|
|
|
739 |
static void
|
|
|
740 |
main_abort_if_errored PROTO_Z ()
|
|
|
741 |
{
|
|
|
742 |
if (error_max_reported_severity () >= ERROR_SEVERITY_ERROR) {
|
|
|
743 |
exit (EXIT_FAILURE);
|
|
|
744 |
UNREACHED;
|
|
|
745 |
}
|
|
|
746 |
}
|
|
|
747 |
|
|
|
748 |
static void
|
|
|
749 |
main_1 PROTO_N ((out_info, dstream))
|
|
|
750 |
PROTO_T (OutputInfoP out_info X
|
|
|
751 |
OStreamP dstream)
|
|
|
752 |
{
|
|
|
753 |
LexerStreamT lstream;
|
|
|
754 |
GrammarT grammar;
|
|
|
755 |
GenericP output_closure;
|
|
|
756 |
|
|
|
757 |
output_closure = (*(main_language->init_proc)) (out_info,
|
|
|
758 |
&main_language_options);
|
|
|
759 |
grammar_init (&grammar);
|
|
|
760 |
lexer_init (&lstream, out_info_get_istream (out_info, (unsigned) 0));
|
|
|
761 |
sid_current_stream = &lstream;
|
|
|
762 |
sid_current_grammar = &grammar;
|
|
|
763 |
sid_parse_grammar ();
|
|
|
764 |
lexer_close (&lstream);
|
|
|
765 |
main_abort_if_errored ();
|
|
|
766 |
grammar_check_complete (&grammar);
|
|
|
767 |
main_abort_if_errored ();
|
|
|
768 |
(*(main_language->input_proc)) (output_closure, &grammar);
|
|
|
769 |
main_abort_if_errored ();
|
|
|
770 |
main_dump_grammar (dstream, &grammar, "Original grammar:");
|
|
|
771 |
grammar_remove_left_recursion (&grammar);
|
|
|
772 |
main_dump_grammar (dstream, &grammar, "After left recursion elimination:");
|
|
|
773 |
main_abort_if_errored ();
|
|
|
774 |
grammar_compute_first_sets (&grammar);
|
|
|
775 |
main_abort_if_errored ();
|
|
|
776 |
grammar_factor (&grammar);
|
|
|
777 |
main_dump_grammar (dstream, &grammar, "After factorisation:");
|
|
|
778 |
main_abort_if_errored ();
|
|
|
779 |
grammar_simplify (&grammar);
|
|
|
780 |
main_dump_grammar (dstream, &grammar, "After simplification:");
|
|
|
781 |
grammar_compute_inlining (&grammar);
|
|
|
782 |
grammar_check_collisions (&grammar);
|
|
|
783 |
main_dump_grammar (dstream, &grammar, "After everything:");
|
|
|
784 |
main_abort_if_errored ();
|
|
|
785 |
grammar_recompute_alt_names (&grammar);
|
|
|
786 |
if (dstream) {
|
|
|
787 |
ostream_close (dstream);
|
|
|
788 |
}
|
|
|
789 |
(*(main_language->output_proc)) (output_closure, &grammar);
|
|
|
790 |
}
|
|
|
791 |
|
|
|
792 |
/*--------------------------------------------------------------------------*/
|
|
|
793 |
|
|
|
794 |
int
|
|
|
795 |
main PROTO_N ((argc, argv))
|
|
|
796 |
PROTO_T (int argc X
|
|
|
797 |
char **argv)
|
|
|
798 |
{
|
|
|
799 |
HANDLE {
|
|
|
800 |
OutputInfoT out_info;
|
|
|
801 |
|
|
|
802 |
istream_setup ();
|
|
|
803 |
ostream_setup ();
|
|
|
804 |
out_info_init (&out_info, argv [0]);
|
|
|
805 |
ostream_init (&dump_stream);
|
|
|
806 |
cstring_list_init (&main_language_options);
|
|
|
807 |
main_init (argc, argv, &out_info);
|
|
|
808 |
if (ostream_is_open (&dump_stream)) {
|
|
|
809 |
main_1 (&out_info, &dump_stream);
|
|
|
810 |
} else {
|
|
|
811 |
main_1 (&out_info, NIL (OStreamP));
|
|
|
812 |
}
|
|
|
813 |
} WITH {
|
|
|
814 |
ExceptionP exception = EXCEPTION_EXCEPTION ();
|
|
|
815 |
|
|
|
816 |
if (exception == XX_dalloc_no_memory) {
|
|
|
817 |
E_no_memory ();
|
|
|
818 |
UNREACHED;
|
|
|
819 |
} else if (exception == XX_istream_read_error) {
|
|
|
820 |
CStringP file = (CStringP) EXCEPTION_VALUE ();
|
|
|
821 |
|
|
|
822 |
E_read_error (file);
|
|
|
823 |
UNREACHED;
|
|
|
824 |
} else if (exception == XX_ostream_write_error) {
|
|
|
825 |
CStringP file = (CStringP) EXCEPTION_VALUE ();
|
|
|
826 |
|
|
|
827 |
E_write_error (file);
|
|
|
828 |
UNREACHED;
|
|
|
829 |
} else {
|
|
|
830 |
RETHROW ();
|
|
|
831 |
UNREACHED;
|
|
|
832 |
}
|
|
|
833 |
} END_HANDLE
|
|
|
834 |
exit (EXIT_SUCCESS);
|
|
|
835 |
UNREACHED;
|
|
|
836 |
}
|
|
|
837 |
|
|
|
838 |
/*
|
|
|
839 |
* Local variables(smf):
|
|
|
840 |
* compile-command: "build_sid"
|
|
|
841 |
* eval: (include::add-path-entry "os-interface" "library" "transforms")
|
|
|
842 |
* eval: (include::add-path-entry "parser" "output" "c-output" "c-input")
|
|
|
843 |
* eval: (include::add-path-entry "generated")
|
|
|
844 |
* End:
|
|
|
845 |
**/
|