Subversion Repositories tendra.SVN

Rev

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

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