Subversion Repositories tendra.SVN

Rev

Rev 6 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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
**/