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