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
// -*- c -*-
2
 
3
%prefixes%
4
 
5
%maps%
6
 
7
AltP			-> AltP;
8
BoolT			-> BoolT;
9
EntryP			-> EntryP;
10
ItemP			-> ItemP;
11
RuleP			-> RuleP;
12
StringT			-> NStringT;
13
sid-parse-grammar	-> sid_parse_grammar;
14
 
15
%header% @{
16
/*
17
    		 Crown Copyright (c) 1997
18
 
19
    This TenDRA(r) Computer Program is subject to Copyright
20
    owned by the United Kingdom Secretary of State for Defence
21
    acting through the Defence Evaluation and Research Agency
22
    (DERA).  It is made available to Recipients with a
23
    royalty-free licence for its use, reproduction, transfer
24
    to other parties and amendment for any purpose not excluding
25
    product development provided that any such use et cetera
26
    shall be deemed to be acceptance of the following conditions:-
27
 
28
        (1) Its Recipients shall ensure that this Notice is
29
        reproduced upon any copies or amended versions of it;
30
 
31
        (2) Any amended version of it shall be clearly marked to
32
        show both the nature of and the organisation responsible
33
        for the relevant amendment or amendments;
34
 
35
        (3) Its onward transfer from a recipient to another
36
        party shall be deemed to be that party's acceptance of
37
        these conditions;
38
 
39
        (4) DERA gives no warranty or assurance as to its
40
        quality or suitability for any purpose and DERA accepts
41
        no liability whatsoever in relation to any use to which
42
        it may be put.
43
*/
44
 
45
 
46
#include "parser.h"
47
#include "action.h"
48
#include "basic.h"
49
#include "bitvec.h"
50
#include "dalloc.h"
51
#include "dstring.h"
52
#include "gen-errors.h"
53
#include "grammar.h"
54
#include "lexer.h"
55
#include "non-local.h"
56
#include "rule.h"
57
#include "scope.h"
58
#include "table.h"
59
#include "types.h"
60
 
61
/*--------------------------------------------------------------------------*/
62
 
63
#define CURRENT_TERMINAL lexer_get_terminal (sid_current_stream)
64
#define ADVANCE_LEXER lexer_next_token (sid_current_stream)
65
#define SAVE_LEXER(x) (lexer_save_terminal (sid_current_stream, (LexerTokenT) (x)))
66
#define RESTORE_LEXER (lexer_restore_terminal (sid_current_stream))
67
#define ALT_LIMIT (UINT_MAX - 1)
68
 
69
/*--------------------------------------------------------------------------*/
70
 
71
LexerStreamP		sid_current_stream;
72
GrammarP		sid_current_grammar;
73
 
74
/*--------------------------------------------------------------------------*/
75
 
76
static TableP		sid_current_table;
77
static EntryListP	sid_current_entry_list;
78
static ScopeStackT	sid_scope_stack;
79
static ScopeStackT	sid_global_scope;
80
static ScopeStackP	sid_current_scope;
81
static EntryP		sid_current_entry;
82
static RuleP		sid_enclosing_rule;
83
static union {
84
    BasicP		basic;
85
    ActionP		action;
86
    RuleP		rule;
87
} sid_current;
88
static BoolT		sid_redefining_entry;
89
static NStringT		sid_maximum_scope;
90
static TypeTupleT	sid_saved_type;
91
static TypeTupleT	sid_current_type;
92
static EntryP		sid_saved_pred_id;
93
static EntryP		sid_current_pred_id;
94
static EntryP		sid_unique_pred_id = NIL (EntryP);
95
static EntryP		sid_predicate_type = NIL (EntryP);
96
static AltP		sid_current_alt;
97
static ItemP		sid_current_item;
98
static unsigned		sid_alternative;
99
static BoolT            sid_internal_rule;
100
static EntryP		sid_external_rule;
101
static unsigned		sid_num_alternatives = 0;
102
static NonLocalEntryP	sid_non_local;
103
static BoolT		sid_propagating_error = FALSE;
104
static BoolT		sid_finished_terminals = FALSE;
105
@}, @{
106
/*
107
    		 Crown Copyright (c) 1997
108
 
109
    This TenDRA(r) Computer Program is subject to Copyright
110
    owned by the United Kingdom Secretary of State for Defence
111
    acting through the Defence Evaluation and Research Agency
112
    (DERA).  It is made available to Recipients with a
113
    royalty-free licence for its use, reproduction, transfer
114
    to other parties and amendment for any purpose not excluding
115
    product development provided that any such use et cetera
116
    shall be deemed to be acceptance of the following conditions:-
117
 
118
        (1) Its Recipients shall ensure that this Notice is
119
        reproduced upon any copies or amended versions of it;
120
 
121
        (2) Any amended version of it shall be clearly marked to
122
        show both the nature of and the organisation responsible
123
        for the relevant amendment or amendments;
124
 
125
        (3) Its onward transfer from a recipient to another
126
        party shall be deemed to be that party's acceptance of
127
        these conditions;
128
 
129
        (4) DERA gives no warranty or assurance as to its
130
        quality or suitability for any purpose and DERA accepts
131
        no liability whatsoever in relation to any use to which
132
        it may be put.
133
*/
134
 
135
 
136
@};
137
 
138
%assignments%
139
 
140
StringT: (a) -> (b) = @{
141
    nstring_assign (&@b, @&a);
142
@};
143
 
144
%parameter-assignments%
145
 
146
StringT: (a) -> (b) = @{
147
    nstring_assign (&@b, @a);
148
@};
149
 
150
%result-assignments%
151
 
152
StringT: (a) -> (b) = @{
153
    nstring_assign (@b, @&a);
154
@};
155
 
156
%terminals%
157
 
158
identifier: () -> (i) = @{
159
    nstring_assign (&@i, lexer_string_value (sid_current_stream));
160
@};
161
 
162
%actions%
163
 
164
<init> = @{
165
sid_current_table      = grammar_table (sid_current_grammar);
166
sid_current_entry_list = grammar_entry_list (sid_current_grammar);
167
scope_stack_init (&sid_scope_stack);
168
scope_stack_init (&sid_global_scope);
169
@};
170
 
171
// Type section actions:
172
 
173
<add-type>: (string) -> () = @{
174
    if (table_add_type (sid_current_table, &@=string) == NIL (EntryP)) {
175
	E_duplicate_type (@&string);
176
	nstring_destroy (&@=string);
177
    }
178
@};
179
 
180
// Terminals section actions:
181
 
182
<terminal>: (string) -> () = @{
183
    sid_current_entry = table_add_basic (sid_current_table, &@=string,
184
					 sid_current_grammar, FALSE);
185
    if (sid_current_entry == NIL (EntryP)) {
186
	E_duplicate_basic (@&string);
187
	nstring_destroy (&@=string);
188
    } else {
189
	sid_current.basic = entry_get_basic (sid_current_entry);
190
    }
191
@};
192
 
193
<i-terminal>: (string) -> () = @{
194
    sid_current_entry = table_add_basic (sid_current_table, &@=string,
195
					 sid_current_grammar, TRUE);
196
    if (sid_current_entry == NIL (EntryP)) {
197
	E_duplicate_basic (@&string);
198
	nstring_destroy (&@=string);
199
    } else {
200
	sid_current.basic = entry_get_basic (sid_current_entry);
201
    }
202
@};
203
 
204
<x-terminal> = @{
205
    if (sid_current_entry) {
206
	KeyP key = entry_key (sid_current_entry);
207
 
208
	if (types_contains_names (&sid_saved_type)) {
209
	    E_basic_param_has_names (key, &sid_saved_type);
210
	}
211
	if (types_contains_names (&sid_current_type)) {
212
	    E_basic_result_has_names (key, &sid_current_type);
213
	}
214
	if (types_contains_references (&sid_current_type)) {
215
	    E_basic_result_has_refs (key, &sid_current_type);
216
	}
217
	if (!types_equal_zero_tuple (&sid_saved_type)) {
218
	    E_basic_param_mismatch (key, &sid_saved_type);
219
	}
220
	types_assign (basic_result (sid_current.basic), &sid_current_type);
221
    } else {
222
	types_destroy (&sid_current_type);
223
    }
224
    types_destroy (&sid_saved_type);
225
@};
226
 
227
<x-terminals> = @{
228
    unsigned max_terminal = grammar_max_terminal (sid_current_grammar);
229
 
230
    bitvec_set_size (max_terminal);
231
    sid_finished_terminals = TRUE;
232
@};
233
 
234
// Tuple manipulation actions:
235
 
236
<save-tuple> = @{
237
    types_assign (&sid_saved_type, &sid_current_type);
238
    sid_saved_pred_id = sid_current_pred_id;
239
@};
240
 
241
<null-type> = @{
242
    types_init (&sid_saved_type);
243
    types_init (&sid_current_type);
244
    sid_saved_pred_id   = NIL (EntryP);
245
    sid_current_pred_id = NIL (EntryP);
246
@};
247
 
248
<init-tuple> = @{
249
    types_init (&sid_current_type);
250
    sid_current_pred_id = NIL (EntryP);
251
@};
252
 
253
<tuple-name>: (name, type) -> () = @{
254
    if (!types_add_typed_name (&sid_current_type, sid_current_table, &@=name,
255
			       @&type, FALSE)) {
256
	E_unknown_type (@&type);
257
    }
258
    nstring_destroy (&@=type);
259
@};
260
 
261
<tuple-ref-name>: (name, type) -> () = @{
262
    if (!types_add_typed_name (&sid_current_type, sid_current_table, &@=name,
263
			       @&type, TRUE)) {
264
	E_unknown_type (@&type);
265
    }
266
    nstring_destroy (&@=type);
267
@};
268
 
269
<tuple-type>: (type) -> () = @{
270
    if (!types_add_type (&sid_current_type, sid_current_table, @&type,
271
			 FALSE)) {
272
	E_unknown_type (@&type);
273
    }
274
    nstring_destroy (&@=type);
275
@};
276
 
277
<tuple-ref-type>: (type) -> () = @{
278
    if (!types_add_type (&sid_current_type, sid_current_table, @&type, TRUE)) {
279
	E_unknown_type (@&type);
280
    }
281
    nstring_destroy (&@=type);
282
@};
283
 
284
<add-name>: (name) -> () = @{
285
    NStringT scope;
286
    EntryP   non_local_entry = scope_stack_get_non_local (&sid_scope_stack,
287
							  sid_current_table,
288
							  @&name, &scope);
289
    EntryP   name_entry      = table_get_entry (sid_current_table, @&name);
290
 
291
    if (name_entry) {
292
	if ((sid_current_entry) && (sid_current_alt)) {
293
	    if ((!types_contains (alt_names (sid_current_alt), name_entry)) &&
294
		(!types_contains (rule_param (sid_current.rule),
295
				  name_entry))) {
296
		name_entry = NIL (EntryP);
297
	    }
298
	} else {
299
	    name_entry = NIL (EntryP);
300
	}
301
    }
302
    if (name_entry) {
303
	types_add_name_and_type (&sid_current_type, name_entry, NIL (EntryP),
304
				 FALSE);
305
	if (non_local_entry) {
306
	    nstring_destroy (&scope);
307
	}
308
	nstring_destroy (&@=name);
309
    } else if (non_local_entry) {
310
	types_add_name_and_type (&sid_current_type, non_local_entry,
311
				 NIL (EntryP), FALSE);
312
	if (nstring_length (&scope) > nstring_length (&sid_maximum_scope)) {
313
	    nstring_destroy (&sid_maximum_scope);
314
	    nstring_assign (&sid_maximum_scope, &scope);
315
	} else {
316
	    nstring_destroy (&scope);
317
	}
318
	nstring_destroy (&@=name);
319
    } else {
320
	types_add_name (&sid_current_type, sid_current_table, &@=name, FALSE);
321
    }
322
@};
323
 
324
<add-ref-name>: (name) -> () = @{
325
    NStringT scope;
326
    EntryP   non_local_entry = scope_stack_get_non_local (&sid_scope_stack,
327
							  sid_current_table,
328
							  @&name, &scope);
329
    EntryP   name_entry      = table_get_entry (sid_current_table, @&name);
330
 
331
    if (name_entry) {
332
	if ((sid_current_entry) && (sid_current_alt)) {
333
	    if ((!types_contains (alt_names (sid_current_alt), name_entry)) &&
334
		(!types_contains (rule_param (sid_current.rule),
335
				  name_entry))) {
336
		name_entry = NIL (EntryP);
337
	    }
338
	} else {
339
	    name_entry = NIL (EntryP);
340
	}
341
    }
342
    if (name_entry) {
343
	types_add_name_and_type (&sid_current_type, name_entry, NIL (EntryP),
344
				 TRUE);
345
	if (non_local_entry) {
346
	    nstring_destroy (&scope);
347
	}
348
	nstring_destroy (&@=name);
349
    } else if (non_local_entry) {
350
	types_add_name_and_type (&sid_current_type, non_local_entry,
351
				 NIL (EntryP), TRUE);
352
	if (nstring_length (&scope) > nstring_length (&sid_maximum_scope)) {
353
	    nstring_destroy (&sid_maximum_scope);
354
	    nstring_assign (&sid_maximum_scope, &scope);
355
	} else {
356
	    nstring_destroy (&scope);
357
	}
358
	nstring_destroy (&@=name);
359
    } else {
360
	types_add_name (&sid_current_type, sid_current_table, &@=name, TRUE);
361
    }
362
@};
363
 
364
<add-var>: (name) -> () = @{
365
    NStringT scope;
366
    EntryP   non_local_entry = scope_stack_get_non_local (&sid_scope_stack,
367
							  sid_current_table,
368
							  @&name, &scope);
369
    EntryP   name_entry      = table_get_entry (sid_current_table, @&name);
370
 
371
    if (name_entry) {
372
	if ((sid_current_entry) && (sid_current_alt)) {
373
	    if ((!types_contains (alt_names (sid_current_alt), name_entry)) &&
374
		(!types_contains (rule_param (sid_current.rule),
375
				  name_entry))) {
376
		name_entry = NIL (EntryP);
377
	    }
378
	} else {
379
	    name_entry = NIL (EntryP);
380
	}
381
    }
382
    if (name_entry) {
383
	types_add_name_and_type_var (&sid_current_type, name_entry,
384
				     NIL (EntryP));
385
	if (non_local_entry) {
386
	    nstring_destroy (&scope);
387
	}
388
	nstring_destroy (&@=name);
389
    } else if (non_local_entry) {
390
	types_add_name_and_type_var (&sid_current_type, non_local_entry,
391
				     NIL (EntryP));
392
	if (nstring_length (&scope) > nstring_length (&sid_maximum_scope)) {
393
	    nstring_destroy (&sid_maximum_scope);
394
	    nstring_assign (&sid_maximum_scope, &scope);
395
	} else {
396
	    nstring_destroy (&scope);
397
	}
398
	nstring_destroy (&@=name);
399
    } else {
400
	E_undefined_assignment (@&name);
401
	types_add_name (&sid_current_type, sid_current_table, &@=name, FALSE);
402
    }
403
@};
404
 
405
<add-pred> = @{
406
    if (sid_current_pred_id) {
407
	E_multi_predicate_return ();
408
    } else if (sid_unique_pred_id == NIL (EntryP)) {
409
	sid_unique_pred_id = grammar_get_predicate_id (sid_current_grammar);
410
    }
411
    sid_current_pred_id = sid_unique_pred_id;
412
    types_add_name_entry (&sid_current_type, sid_current_pred_id);
413
@};
414
 
415
<add-void> = @{
416
    EntryP entry = table_add_generated_name (sid_current_table);
417
 
418
    types_add_name_entry (&sid_current_type, entry);
419
@};
420
 
421
// Productions section actions:
422
 
423
<use-global> = @{
424
    sid_current_scope = &sid_global_scope;
425
@};
426
 
427
<use-local> = @{
428
    sid_current_scope = &sid_scope_stack;
429
@};
430
 
431
<action>: (string) -> () = @{
432
    sid_current_entry = scope_stack_add_action (sid_current_scope,
433
						sid_current_table, &@=string,
434
						sid_enclosing_rule,
435
						&sid_redefining_entry);
436
    if (sid_current_entry) {
437
	sid_current.action = entry_get_action (sid_current_entry);
438
    } else {
439
	E_duplicate_action (@&string);
440
	nstring_destroy (&@=string);
441
    }
442
@};
443
 
444
<x-action> = @{
445
    if (sid_current_entry) {
446
	KeyP       key     = entry_key (sid_current_entry);
447
	TypeTupleP param   = action_param (sid_current.action);
448
	TypeTupleP result  = action_result (sid_current.action);
449
	BoolT      errored = FALSE;
450
 
451
	if (types_contains_names (&sid_saved_type)) {
452
	    E_action_param_has_names (key, &sid_saved_type);
453
	    errored = TRUE;
454
	}
455
	if (sid_redefining_entry) {
456
	    if (!types_equal (param, &sid_saved_type)) {
457
		E_action_param_mismatch (key, param, &sid_saved_type);
458
		errored = TRUE;
459
	    }
460
	}
461
	if (types_contains_names (&sid_current_type)) {
462
	    E_action_result_has_names (key, &sid_current_type);
463
	    errored = TRUE;
464
	}
465
	if (types_contains_references (&sid_current_type)) {
466
	    E_action_result_has_refs (key, &sid_current_type);
467
	    errored = TRUE;
468
	}
469
	if (sid_redefining_entry) {
470
	    if (!types_equal (result, &sid_current_type)) {
471
		E_action_result_mismatch (key, result, &sid_current_type);
472
		errored = TRUE;
473
	    }
474
	}
475
	if (errored || sid_redefining_entry) {
476
	    types_destroy (&sid_saved_type);
477
	    types_destroy (&sid_current_type);
478
	} else {
479
	    types_assign (param, &sid_saved_type);
480
	    types_assign (result, &sid_current_type);
481
	}
482
    } else {
483
	types_destroy (&sid_saved_type);
484
	types_destroy (&sid_current_type);
485
    }
486
@};
487
 
488
<non-local>: (id, type_id) -> () = @{
489
    sid_non_local = NIL (NonLocalEntryP);
490
    if ((sid_enclosing_rule == NIL (RuleP)) ||
491
	(sid_current_scope == &sid_global_scope)) {
492
	E_global_scope_non_local (@&id);
493
	nstring_destroy (&@=id);
494
    } else {
495
	EntryP type = table_get_type (sid_current_table, @&type_id);
496
 
497
	if (type == NIL (EntryP)) {
498
	    E_unknown_type (@&type_id);
499
	    nstring_destroy (&@=id);
500
	} else {
501
	    EntryP name = scope_stack_add_non_local (sid_current_scope,
502
						     sid_current_table,
503
						     &@=id, type,
504
						     sid_enclosing_rule);
505
 
506
	    if (name) {
507
		NonLocalListP non_locals = rule_non_locals (sid_enclosing_rule);
508
		sid_non_local = non_local_list_add (non_locals, name, type);
509
	    } else {
510
		E_duplicate_non_local (@&id);
511
		nstring_destroy (&@=id);
512
	    }
513
	}
514
    }
515
    nstring_destroy (&@=type_id);
516
@};
517
 
518
<non-local-init>: (action_id) -> () = @{
519
    EntryP entry = scope_stack_get_action (&sid_scope_stack, sid_current_table,
520
					   @&action_id);
521
 
522
    if (entry == NIL (EntryP)) {
523
	E_unknown_action (@&action_id);
524
    } else if (sid_non_local) {
525
	EntryP     type   = non_local_entry_get_type (sid_non_local);
526
	KeyP       name   = entry_key (non_local_entry_get_name (sid_non_local));
527
	ActionP    action = entry_get_action (entry);
528
	TypeTupleP param  = action_param (action);
529
	TypeTupleP result = action_result (action);
530
	TypeTupleT tuple;
531
	TypeTupleT ref_tuple;
532
 
533
	types_init (&tuple);
534
	types_init (&ref_tuple);
535
	types_add_type_entry (&tuple, type, FALSE);
536
	types_add_type_entry (&ref_tuple, type, TRUE);
537
	if ((!types_equal (param, &tuple)) &&
538
	    (!types_equal (param, &ref_tuple)) &&
539
	    (!types_equal_zero_tuple (param))) {
540
	    E_initialiser_param_mismatch (name, &tuple, &ref_tuple, param);
541
	}
542
	if (!types_equal (result, &tuple)) {
543
	    E_initialiser_result_mismatch (name, &tuple, result);
544
	}
545
	types_destroy (&ref_tuple);
546
	types_destroy (&tuple);
547
	non_local_entry_set_initialiser (sid_non_local, entry);
548
    }
549
    nstring_destroy (&@=action_id);
550
@};
551
 
552
<rule>: (string) -> () = @{
553
    sid_current_entry = scope_stack_add_rule (sid_current_scope,
554
					      sid_current_table, &@=string,
555
					      sid_enclosing_rule,
556
					      &sid_redefining_entry);
557
    if (sid_current_entry) {
558
	sid_current.rule = entry_get_rule (sid_current_entry);
559
    } else {
560
	E_duplicate_rule (@&string);
561
	nstring_destroy (&@=string);
562
    }
563
@};
564
 
565
<x-rule> = @{
566
    if (sid_current_entry) {
567
	KeyP       key     = entry_key (sid_current_entry);
568
	TypeTupleP param   = rule_param (sid_current.rule);
569
	TypeTupleP result  = rule_result (sid_current.rule);
570
	BoolT      errored = FALSE;
571
 
572
	if (types_contains_names (&sid_saved_type)) {
573
	    E_rule_param_has_names (key, &sid_saved_type);
574
	    errored = TRUE;
575
	}
576
	if (sid_redefining_entry) {
577
	    if (!types_equal (param, &sid_saved_type)) {
578
		E_rule_param_mismatch (key, param, &sid_saved_type);
579
		errored = TRUE;
580
	    }
581
	}
582
	if (types_contains_names (&sid_current_type)) {
583
	    E_rule_result_has_names (key, &sid_current_type);
584
	    errored = TRUE;
585
	}
586
	if (types_contains_references (&sid_current_type)) {
587
	    E_rule_result_has_refs (key, &sid_current_type);
588
	    errored = TRUE;
589
	}
590
	if (sid_redefining_entry) {
591
	    if (!types_equal (result, &sid_current_type)) {
592
		E_rule_result_mismatch (key, result, &sid_current_type);
593
		errored = TRUE;
594
	    }
595
	}
596
	if (errored || sid_redefining_entry) {
597
	    types_destroy (&sid_saved_type);
598
	    types_destroy (&sid_current_type);
599
	} else {
600
	    types_assign (param, &sid_saved_type);
601
	    types_assign (result, &sid_current_type);
602
	}
603
    } else {
604
	types_destroy (&sid_saved_type);
605
	types_destroy (&sid_current_type);
606
    }
607
@};
608
 
609
<prod> = @{
610
    if (sid_current_entry) {
611
	KeyP key = entry_key (sid_current_entry);
612
 
613
	if (rule_is_defined (sid_current.rule)) {
614
	    E_rule_already_defined (key);
615
	    sid_current_entry = NIL (EntryP);
616
	    types_destroy (&sid_saved_type);
617
	    types_destroy (&sid_current_type);
618
	} else {
619
	    TypeTupleP param   = rule_param (sid_current.rule);
620
	    TypeTupleP result  = rule_result (sid_current.rule);
621
	    BoolT      errored = FALSE;
622
 
623
	    rule_defined (sid_current.rule);
624
	    if (!types_disjoint_names (&sid_saved_type)) {
625
		E_rule_param_clash (key, &sid_saved_type);
626
		errored = TRUE;
627
	    }
628
	    if (types_check_shadowing (&sid_saved_type, &sid_scope_stack,
629
				       sid_current.rule)) {
630
		errored = TRUE;
631
	    }
632
	    if (sid_redefining_entry) {
633
		if (!types_fillin_names (param, &sid_saved_type)) {
634
		    E_rule_param_mismatch (key, param, &sid_saved_type);
635
		    errored = TRUE;
636
		}
637
		types_destroy (&sid_saved_type);
638
	    } else {
639
		types_assign (param, &sid_saved_type);
640
	    }
641
	    if (!types_disjoint_names (&sid_current_type)) {
642
		E_rule_result_clash (key, &sid_current_type);
643
		errored = TRUE;
644
	    }
645
	    if (types_check_shadowing (&sid_current_type, &sid_scope_stack,
646
				       sid_current.rule)) {
647
		errored = TRUE;
648
	    }
649
	    if (types_contains_references (&sid_current_type)) {
650
		E_rule_result_has_refs (key, &sid_current_type);
651
		errored = TRUE;
652
	    }
653
	    if (sid_redefining_entry) {
654
		if (!types_fillin_names (result, &sid_current_type)) {
655
		    E_rule_result_mismatch (key, result, &sid_current_type);
656
		    errored = TRUE;
657
		}
658
		types_destroy (&sid_current_type);
659
	    } else {
660
		types_assign (result, &sid_current_type);
661
	    }
662
	    if (errored) {
663
		sid_current_entry = NIL (EntryP);
664
	    } else {
665
		if (types_intersect (param, result)) {
666
		    E_rule_formal_clash (key, param, result);
667
		    sid_current_entry = NIL (EntryP);
668
		}
669
	    }
670
	}
671
    } else {
672
	types_destroy (&sid_saved_type);
673
	types_destroy (&sid_current_type);
674
    }
675
    sid_alternative   = 0;
676
    sid_internal_rule = FALSE;
677
    sid_external_rule = sid_current_entry;
678
    nstring_init (&sid_maximum_scope);
679
@};
680
 
681
<x-prod> = @{
682
    if (sid_current_entry) {
683
	nstring_assign (rule_maximum_scope (sid_current.rule),
684
			&sid_maximum_scope);
685
    } else {
686
	nstring_destroy (&sid_maximum_scope);
687
    }
688
@};
689
 
690
<push-scope> = @{
691
    if (sid_current_entry) {
692
	KeyP     key   = entry_key (sid_current_entry);
693
	NStringP scope = key_get_string (key);
694
 
695
	scope_stack_push (&sid_scope_stack, scope);
696
    }
697
@};
698
 
699
<pop-scope> = @{
700
    if (sid_current_entry) {
701
	scope_stack_pop (&sid_scope_stack);
702
    }
703
@};
704
 
705
<save-scope>: () -> (saved_entry, saved_rule) = @{
706
    @saved_entry       = sid_current_entry;
707
    @saved_rule        = sid_enclosing_rule;
708
 
709
    sid_enclosing_rule = sid_current.rule;
710
@};
711
 
712
<restore-scope>: (saved_entry, saved_rule) -> () = @{
713
    sid_current_entry  = @saved_entry;
714
    sid_current.rule   = sid_enclosing_rule;
715
    sid_enclosing_rule = @saved_rule;
716
    sid_alternative    = 0;
717
    sid_internal_rule  = FALSE;
718
    sid_external_rule  = sid_current_entry;
719
    nstring_init (&sid_maximum_scope);
720
@};
721
 
722
<empty-alt> = @{
723
    if ((++ sid_num_alternatives) == ALT_LIMIT) {
724
	E_too_many_alternatives ();
725
	UNREACHED;
726
    }
727
    if (!sid_internal_rule) {
728
	sid_alternative ++;
729
    }
730
    if (sid_current_entry) {
731
	if (rule_has_empty_alt (sid_current.rule)) {
732
	    E_multiple_empty_alts (entry_key (sid_external_rule));
733
	} else if (!types_equal_zero_tuple (rule_result (sid_current.rule))) {
734
	    E_alt_result_mismatch (entry_key (sid_external_rule),
735
				   sid_alternative);
736
	} else {
737
	    rule_add_empty_alt (sid_current.rule);
738
	}
739
    }
740
@};
741
 
742
<non-empty-alt> = @{
743
    if ((++ sid_num_alternatives) == ALT_LIMIT) {
744
	E_too_many_alternatives ();
745
	UNREACHED;
746
    }
747
    if (!sid_internal_rule) {
748
	sid_alternative ++;
749
    }
750
    if (sid_current_entry) {
751
	sid_current_alt = alt_create ();
752
    }
753
@};
754
 
755
<x-non-empty-alt> = @{
756
    if ((sid_current_entry) && (sid_current_alt)) {
757
	if (types_check_names (rule_result (sid_current.rule),
758
			       alt_names (sid_current_alt))) {
759
	    TypeTupleT used;
760
 
761
	    types_copy (&used, rule_result (sid_current.rule));
762
	    item_compute_minimal_dataflow (alt_item_head (sid_current_alt),
763
					   &used);
764
	    types_destroy (&used);
765
	    rule_add_alt (sid_current.rule, sid_current_alt);
766
	} else {
767
	    (void) alt_deallocate (sid_current_alt);
768
	    E_alt_result_mismatch (entry_key (sid_external_rule),
769
				   sid_alternative);
770
	}
771
    }
772
@};
773
 
774
<handler> = @{
775
    if (sid_current_entry) {
776
	sid_current_alt = alt_create ();
777
    }
778
@};
779
 
780
<x-handler> = @{
781
    if ((sid_current_entry) && (sid_current_alt)) {
782
	if (types_check_names (rule_result (sid_current.rule),
783
			       alt_names (sid_current_alt))) {
784
	    TypeTupleT used;
785
 
786
	    types_copy (&used, rule_result (sid_current.rule));
787
	    item_compute_minimal_dataflow (alt_item_head (sid_current_alt),
788
					   &used);
789
	    types_destroy (&used);
790
	    rule_set_handler (sid_current.rule, sid_current_alt);
791
	} else {
792
	    (void) alt_deallocate (sid_current_alt);
793
	    E_handler_result_mismatch (entry_key (sid_external_rule));
794
	}
795
    }
796
@};
797
 
798
<save>: () -> (saved_entry, saved_rule, saved_alt, saved_internal, item) = @{
799
    @saved_entry      = sid_current_entry;
800
    @saved_rule       = sid_current.rule;
801
    @saved_alt        = sid_current_alt;
802
    @saved_internal   = sid_internal_rule;
803
    @item             = NIL (ItemP);
804
    sid_internal_rule = TRUE;
805
    if ((sid_current_entry) && (sid_current_alt)) {
806
	sid_current_entry = table_add_generated_rule (sid_current_table,
807
						      FALSE);
808
	sid_current.rule  = entry_get_rule (sid_current_entry);
809
	@item             = item_create (sid_current_entry);
810
	rule_defined (sid_current.rule);
811
	item_inlinable (@item);
812
	types_copy (item_param (@item), rule_param (@saved_rule));
813
	types_append_copy (item_param (@item), alt_names (@saved_alt));
814
	types_copy (rule_param (sid_current.rule), item_param (@item));
815
	types_make_references (rule_param (sid_current.rule),
816
			       item_param (@item));
817
	alt_add_item (@saved_alt, @item);
818
    } else {
819
	sid_current_entry = NIL (EntryP);
820
    }
821
@};
822
 
823
<restore>:
824
    (saved_entry, saved_rule, saved_alt, saved_internal, item) -> () = @{
825
    if ((@saved_entry) && (@saved_alt)) {
826
	rule_compute_result_intersect (sid_current.rule);
827
	types_copy (item_result (@item), rule_result (sid_current.rule));
828
	types_add_new_names (alt_names (@saved_alt), item_result (@item),
829
			     sid_unique_pred_id);
830
    }
831
    sid_internal_rule = @saved_internal;
832
    sid_current_alt   = @saved_alt;
833
    sid_current.rule  = @saved_rule;
834
    sid_current_entry = @saved_entry;
835
@};
836
 
837
<prod-action>: (string) -> () = @{
838
    if ((sid_current_entry) && (sid_current_alt)) {
839
	EntryP entry = scope_stack_get_action (&sid_scope_stack,
840
					       sid_current_table, @&string);
841
 
842
	if (entry) {
843
	    sid_current_item = item_create (entry);
844
	} else {
845
	    E_unknown_action (@&string);
846
	    sid_current_item = NIL (ItemP);
847
	    (void) alt_deallocate (sid_current_alt);
848
	    sid_current_alt  = NIL (AltP);
849
	}
850
    } else {
851
	sid_current_item = NIL (ItemP);
852
    }
853
    nstring_destroy (&@=string);
854
@};
855
 
856
<x-prod-action> = @{
857
    if (sid_current_item) {
858
	BoolT   errored = FALSE;
859
	EntryP  entry   = item_entry (sid_current_item);
860
	ActionP action  = entry_get_action (entry);
861
 
862
	if (types_resolve (&sid_current_type, rule_param (sid_current.rule),
863
			   alt_names (sid_current_alt), E_undefined_name,
864
			   entry_key (sid_external_rule), sid_alternative)) {
865
	    if (types_equal (&sid_current_type, action_param (action))) {
866
		item_add_param (sid_current_item, &sid_current_type);
867
	    } else {
868
		E_action_param_call_mismatch (entry_key (entry),
869
					      action_param (action),
870
					      &sid_current_type);
871
		types_destroy (&sid_current_type);
872
		errored = TRUE;
873
	    }
874
	} else {
875
	    types_destroy (&sid_current_type);
876
	    errored = TRUE;
877
	}
878
	if (types_disjoint_names (&sid_saved_type)) {
879
	    if (types_check_undefined (&sid_saved_type,
880
				       rule_param (sid_current.rule),
881
				       alt_names (sid_current_alt),
882
				       E_redefined_name,
883
				       entry_key (sid_external_rule),
884
				       sid_alternative)) {
885
		if (types_fillin_types (&sid_saved_type,
886
					action_result (action))) {
887
		    types_add_new_names (alt_names (sid_current_alt),
888
					 &sid_saved_type, sid_unique_pred_id);
889
		    if (sid_saved_pred_id) {
890
			BoolT  reference;
891
			EntryP type = types_find_name_type (&sid_saved_type,
892
							    sid_saved_pred_id,
893
							    &reference);
894
 
895
			ASSERT ((type != NIL (EntryP)) && (!reference));
896
			if (sid_predicate_type) {
897
			    if (type != sid_predicate_type) {
898
				E_predicate_type (sid_predicate_type, type);
899
			    }
900
			} else {
901
			    grammar_set_predicate_type (sid_current_grammar,
902
							type);
903
			    sid_predicate_type = type;
904
			}
905
			item_to_predicate (sid_current_item);
906
		    }
907
		    item_add_result (sid_current_item, &sid_saved_type);
908
		} else {
909
		    E_action_result_call_mismatch (entry_key (entry),
910
						   action_result (action),
911
						   &sid_saved_type);
912
		    types_destroy (&sid_saved_type);
913
		    errored = TRUE;
914
		}
915
	    } else {
916
		types_destroy (&sid_saved_type);
917
		errored = TRUE;
918
	    }
919
	} else {
920
	    E_action_result_call_clash (entry_key (entry), &sid_saved_type);
921
	    types_destroy (&sid_saved_type);
922
	    errored = TRUE;
923
	}
924
	if (errored) {
925
	    (void) item_deallocate (sid_current_item);
926
	    sid_current_item = NIL (ItemP);
927
	    (void) alt_deallocate (sid_current_alt);
928
	    sid_current_alt  = NIL (AltP);
929
	} else {
930
	    alt_add_item (sid_current_alt, sid_current_item);
931
	}
932
    } else {
933
	types_destroy (&sid_saved_type);
934
	types_destroy (&sid_current_type);
935
    }
936
@};
937
 
938
<x-identity> = @{
939
    if ((sid_current_entry) && (sid_current_alt)) {
940
	EntryP entry = table_add_rename (sid_current_table);
941
 
942
	if (types_resolve (&sid_current_type, rule_param (sid_current.rule),
943
			   alt_names (sid_current_alt), E_undefined_name,
944
			   entry_key (sid_external_rule), sid_alternative)) {
945
	    if (types_contains_references (&sid_current_type)) {
946
		E_identity_param_has_refs (&sid_current_type,
947
					   entry_key (sid_external_rule),
948
					   sid_alternative);
949
		types_destroy (&sid_current_type);
950
		sid_current_item = NIL (ItemP);
951
	    } else {
952
		sid_current_item = item_create (entry);
953
		item_add_param (sid_current_item, &sid_current_type);
954
	    }
955
	} else {
956
	    types_destroy (&sid_current_type);
957
	    sid_current_item = NIL (ItemP);
958
	}
959
	if (types_disjoint_names (&sid_saved_type)) {
960
	    if (types_check_undefined (&sid_saved_type,
961
				       rule_param (sid_current.rule),
962
				       alt_names (sid_current_alt),
963
				       E_redefined_name,
964
				       entry_key (sid_external_rule),
965
				       sid_alternative)) {
966
		if (sid_current_item) {
967
		    if (types_fillin_types (&sid_saved_type,
968
					    item_param (sid_current_item))) {
969
			types_add_new_names (alt_names (sid_current_alt),
970
					     &sid_saved_type,
971
					     sid_unique_pred_id);
972
			if (sid_saved_pred_id) {
973
			    E_predicate ();
974
			}
975
			item_add_result (sid_current_item, &sid_saved_type);
976
			alt_add_item (sid_current_alt, sid_current_item);
977
		    } else {
978
			E_identity_mismatch (item_param (sid_current_item),
979
					     &sid_saved_type);
980
			types_destroy (&sid_saved_type);
981
			(void) item_deallocate (sid_current_item);
982
			sid_current_item = NIL (ItemP);
983
		    }
984
		}
985
	    } else {
986
		types_destroy (&sid_saved_type);
987
		if (sid_current_item) {
988
		    (void) item_deallocate (sid_current_item);
989
		    sid_current_item = NIL (ItemP);
990
		}
991
	    }
992
	} else {
993
	    E_identity_result_clash (&sid_saved_type);
994
	    types_destroy (&sid_saved_type);
995
	    if (sid_current_item) {
996
		(void) item_deallocate (sid_current_item);
997
		sid_current_item = NIL (ItemP);
998
	    }
999
	}
1000
	if (sid_current_item == NIL (ItemP)) {
1001
	    (void) alt_deallocate (sid_current_alt);
1002
	    sid_current_alt = NIL (AltP);
1003
	}
1004
    } else {
1005
	types_destroy (&sid_saved_type);
1006
	types_destroy (&sid_current_type);
1007
    }
1008
@};
1009
 
1010
<x-prod-rule>: (string) -> () = @{
1011
    TypeTupleP param  = NIL (TypeTupleP);
1012
    TypeTupleP result = NIL (TypeTupleP);
1013
    EntryP     entry  = NIL (EntryP);
1014
    RuleP      rule;
1015
    BasicP     basic;
1016
 
1017
    if ((sid_current_entry) && (sid_current_alt)) {
1018
	entry = scope_stack_get_rule (&sid_scope_stack, sid_current_table,
1019
				      @&string);
1020
	if (entry) {
1021
	    sid_current_item = item_create (entry);
1022
	    rule             = entry_get_rule (entry);
1023
	    param            = rule_param (rule);
1024
	    result           = rule_result (rule);
1025
	} else {
1026
	    entry = table_get_basic (sid_current_table, @&string);
1027
	    if (entry) {
1028
		sid_current_item = item_create (entry);
1029
		basic            = entry_get_basic (entry);
1030
		param            = NIL (TypeTupleP);
1031
		result           = basic_result (basic);
1032
		if (basic_get_ignored (basic)) {
1033
		    E_ignored_basic_call (@&string);
1034
		}
1035
	    } else {
1036
		E_unknown_rule_or_basic (@&string);
1037
		sid_current_item = NIL (ItemP);
1038
	    }
1039
	}
1040
    } else {
1041
	sid_current_item = NIL (ItemP);
1042
    }
1043
    nstring_destroy (&@=string);
1044
    if (sid_current_item) {
1045
	BoolT errored = FALSE;
1046
	KeyP  key     = entry_key (entry);
1047
 
1048
	if (types_resolve (&sid_current_type, rule_param (sid_current.rule),
1049
			   alt_names (sid_current_alt), E_undefined_name,
1050
			   entry_key (sid_external_rule), sid_alternative)) {
1051
	    if (param) {
1052
		if (types_equal (&sid_current_type, param)) {
1053
		    item_add_param (sid_current_item, &sid_current_type);
1054
		} else {
1055
		    E_rule_param_call_mismatch (key, param, &sid_current_type);
1056
		    types_destroy (&sid_current_type);
1057
		    errored = TRUE;
1058
		}
1059
	    } else {
1060
		if (!types_equal_zero_tuple (&sid_current_type)) {
1061
		    E_basic_param_call_mismatch (key, &sid_current_type);
1062
		    types_destroy (&sid_current_type);
1063
		    errored = TRUE;
1064
		}
1065
	    }
1066
	} else {
1067
	    types_destroy (&sid_current_type);
1068
	    errored = TRUE;
1069
	}
1070
	if (types_disjoint_names (&sid_saved_type)) {
1071
	    if (types_check_undefined (&sid_saved_type,
1072
				       rule_param (sid_current.rule),
1073
				       alt_names (sid_current_alt),
1074
				       E_redefined_name,
1075
				       entry_key (sid_external_rule),
1076
				       sid_alternative)) {
1077
		if (types_fillin_types (&sid_saved_type, result)) {
1078
		    types_add_new_names (alt_names (sid_current_alt),
1079
					 &sid_saved_type, sid_unique_pred_id);
1080
		    if (sid_saved_pred_id) {
1081
			E_predicate ();
1082
		    }
1083
		    item_add_result (sid_current_item, &sid_saved_type);
1084
		} else {
1085
		    if (param) {
1086
			E_rule_result_call_mismatch (key, result,
1087
						     &sid_saved_type);
1088
		    } else {
1089
			E_basic_result_call_mismatch (key, result,
1090
						      &sid_saved_type);
1091
		    }
1092
		    types_destroy (&sid_saved_type);
1093
		    errored = TRUE;
1094
		}
1095
	    } else {
1096
		types_destroy (&sid_saved_type);
1097
		errored = TRUE;
1098
	    }
1099
	} else {
1100
	    if (param) {
1101
		E_rule_result_call_clash (key, &sid_saved_type);
1102
	    } else {
1103
		E_basic_result_call_clash (key, &sid_saved_type);
1104
	    }
1105
	    types_destroy (&sid_saved_type);
1106
	    errored = TRUE;
1107
	}
1108
	if (errored) {
1109
	    (void) item_deallocate (sid_current_item);
1110
	    sid_current_item = NIL (ItemP);
1111
	    (void) alt_deallocate (sid_current_alt);
1112
	    sid_current_alt  = NIL (AltP);
1113
	} else {
1114
	    alt_add_item (sid_current_alt, sid_current_item);
1115
	}
1116
    } else {
1117
	if (sid_current_alt) {
1118
	    (void) alt_deallocate (sid_current_alt);
1119
	    sid_current_alt = NIL (AltP);
1120
	}
1121
	types_destroy (&sid_saved_type);
1122
	types_destroy (&sid_current_type);
1123
    }
1124
@};
1125
 
1126
<x-prod-rule-or-identity>: (string) -> () = @{
1127
    EntryP     name_entry = table_get_entry (sid_current_table, @&string);
1128
    EntryP     entry      = NIL (EntryP);
1129
    TypeTupleP param      = NIL (TypeTupleP);
1130
    TypeTupleP result     = NIL (TypeTupleP);
1131
    RuleP      rule;
1132
    BasicP     basic;
1133
 
1134
    if ((sid_current_entry) && (sid_current_alt)) {
1135
	if ((name_entry != NIL (EntryP)) &&
1136
	    (!types_contains (alt_names (sid_current_alt), name_entry)) &&
1137
	    (!types_contains (rule_param (sid_current.rule), name_entry))) {
1138
	    name_entry = NIL (EntryP);
1139
	}
1140
	entry = scope_stack_get_rule (&sid_scope_stack, sid_current_table,
1141
				      @&string);
1142
	if (entry) {
1143
	    sid_current_item = item_create (entry);
1144
	    rule             = entry_get_rule (entry);
1145
	    param            = rule_param (rule);
1146
	    result           = rule_result (rule);
1147
	} else {
1148
	    entry = table_get_basic (sid_current_table, @&string);
1149
	    if (entry) {
1150
		sid_current_item = item_create (entry);
1151
		basic            = entry_get_basic (entry);
1152
		param            = NIL (TypeTupleP);
1153
		result           = basic_result (basic);
1154
		if ((name_entry == NIL (EntryP)) &&
1155
		    basic_get_ignored (basic)) {
1156
		    E_ignored_basic_call (@&string);
1157
		}
1158
	    }
1159
	}
1160
	if ((entry == NIL (EntryP)) && (name_entry == NIL (EntryP))) {
1161
	    NStringT scope;
1162
 
1163
	    name_entry = scope_stack_get_non_local (&sid_scope_stack,
1164
						    sid_current_table,
1165
						    @&string, &scope);
1166
	    if (name_entry) {
1167
		if (nstring_length (&scope) >
1168
		    nstring_length (&sid_maximum_scope)) {
1169
		    nstring_destroy (&sid_maximum_scope);
1170
		    nstring_assign (&sid_maximum_scope, &scope);
1171
		} else {
1172
		    nstring_destroy (&scope);
1173
		}
1174
	    } else {
1175
		E_unknown_rule_or_basic (@&string);
1176
	    }
1177
	} else if ((entry != NIL (EntryP)) && (name_entry != NIL (EntryP))) {
1178
	    E_ambiguous_call (@&string);
1179
	    entry      = NIL (EntryP);
1180
	    name_entry = NIL (EntryP);
1181
	}
1182
    } else {
1183
	name_entry = NIL (EntryP);
1184
    }
1185
    nstring_destroy (&@=string);
1186
    if (entry) {
1187
	BoolT errored = FALSE;
1188
	KeyP  key     = entry_key (entry);
1189
 
1190
	if (types_resolve (&sid_current_type, rule_param (sid_current.rule),
1191
			   alt_names (sid_current_alt), E_undefined_name,
1192
			   entry_key (sid_external_rule), sid_alternative)) {
1193
	    if (param) {
1194
		if (types_equal (&sid_current_type, param)) {
1195
		    item_add_param (sid_current_item, &sid_current_type);
1196
		} else {
1197
		    E_rule_param_call_mismatch (key, param, &sid_current_type);
1198
		    types_destroy (&sid_current_type);
1199
		    errored = TRUE;
1200
		}
1201
	    } else {
1202
		if (!types_equal_zero_tuple (&sid_current_type)) {
1203
		    E_basic_param_call_mismatch (key, &sid_current_type);
1204
		    types_destroy (&sid_current_type);
1205
		    errored = TRUE;
1206
		}
1207
	    }
1208
	} else {
1209
	    types_destroy (&sid_current_type);
1210
	    errored = TRUE;
1211
	}
1212
	if (types_disjoint_names (&sid_saved_type)) {
1213
	    if (types_check_undefined (&sid_saved_type,
1214
				       rule_param (sid_current.rule),
1215
				       alt_names (sid_current_alt),
1216
				       E_redefined_name,
1217
				       entry_key (sid_external_rule),
1218
				       sid_alternative)) {
1219
		if (types_fillin_types (&sid_saved_type, result)) {
1220
		    types_add_new_names (alt_names (sid_current_alt),
1221
					 &sid_saved_type, sid_unique_pred_id);
1222
		    if (sid_saved_pred_id) {
1223
			E_predicate ();
1224
		    }
1225
		    item_add_result (sid_current_item, &sid_saved_type);
1226
		} else {
1227
		    if (param) {
1228
			E_rule_result_call_mismatch (key, result,
1229
						     &sid_saved_type);
1230
		    } else {
1231
			E_basic_result_call_mismatch (key, result,
1232
						      &sid_saved_type);
1233
		    }
1234
		    types_destroy (&sid_saved_type);
1235
		    errored = TRUE;
1236
		}
1237
	    } else {
1238
		types_destroy (&sid_saved_type);
1239
		errored = TRUE;
1240
	    }
1241
	} else {
1242
	    if (param) {
1243
		E_rule_result_call_clash (key, &sid_saved_type);
1244
	    } else {
1245
		E_basic_result_call_clash (key, &sid_saved_type);
1246
	    }
1247
	    types_destroy (&sid_saved_type);
1248
	    errored = TRUE;
1249
	}
1250
	if (errored) {
1251
	    (void) item_deallocate (sid_current_item);
1252
	    sid_current_item = NIL (ItemP);
1253
	    (void) alt_deallocate (sid_current_alt);
1254
	    sid_current_alt  = NIL (AltP);
1255
	} else {
1256
	    alt_add_item (sid_current_alt, sid_current_item);
1257
	}
1258
    } else if (name_entry) {
1259
	types_add_name_entry (&sid_current_type, name_entry);
1260
	entry = table_add_rename (sid_current_table);
1261
	if (types_resolve (&sid_current_type, rule_param (sid_current.rule),
1262
			   alt_names (sid_current_alt), E_undefined_name,
1263
			   entry_key (sid_external_rule), sid_alternative)) {
1264
	    if (types_contains_references (&sid_current_type)) {
1265
		E_identity_param_has_refs (&sid_current_type,
1266
					   entry_key (sid_external_rule),
1267
					   sid_alternative);
1268
		types_destroy (&sid_current_type);
1269
		sid_current_item = NIL (ItemP);
1270
	    } else {
1271
		sid_current_item = item_create (entry);
1272
		item_add_param (sid_current_item, &sid_current_type);
1273
	    }
1274
	} else {
1275
	    types_destroy (&sid_current_type);
1276
	    sid_current_item = NIL (ItemP);
1277
	}
1278
	if (types_disjoint_names (&sid_saved_type)) {
1279
	    if (types_check_undefined (&sid_saved_type,
1280
				       rule_param (sid_current.rule),
1281
				       alt_names (sid_current_alt),
1282
				       E_redefined_name,
1283
				       entry_key (sid_external_rule),
1284
				       sid_alternative)) {
1285
		if (sid_current_item) {
1286
		    if (types_fillin_types (&sid_saved_type,
1287
					    item_param (sid_current_item))) {
1288
			types_add_new_names (alt_names (sid_current_alt),
1289
					     &sid_saved_type,
1290
					     sid_unique_pred_id);
1291
			if (sid_saved_pred_id) {
1292
			    E_predicate ();
1293
			}
1294
			item_add_result (sid_current_item, &sid_saved_type);
1295
			alt_add_item (sid_current_alt, sid_current_item);
1296
		    } else {
1297
			E_identity_mismatch (item_param (sid_current_item),
1298
					     &sid_saved_type);
1299
			types_destroy (&sid_saved_type);
1300
			(void) item_deallocate (sid_current_item);
1301
			sid_current_item = NIL (ItemP);
1302
		    }
1303
		}
1304
	    } else {
1305
		types_destroy (&sid_saved_type);
1306
		if (sid_current_item) {
1307
		    (void) item_deallocate (sid_current_item);
1308
		    sid_current_item = NIL (ItemP);
1309
		}
1310
	    }
1311
	} else {
1312
	    E_identity_result_clash (&sid_saved_type);
1313
	    types_destroy (&sid_saved_type);
1314
	    if (sid_current_item) {
1315
		(void) item_deallocate (sid_current_item);
1316
		sid_current_item = NIL (ItemP);
1317
	    }
1318
	}
1319
	if (sid_current_item == NIL (ItemP)) {
1320
	    (void) alt_deallocate (sid_current_alt);
1321
	    sid_current_alt = NIL (AltP);
1322
	}
1323
    } else {
1324
	if (sid_current_alt) {
1325
	    (void) alt_deallocate (sid_current_alt);
1326
	    sid_current_alt = NIL (AltP);
1327
	}
1328
	types_destroy (&sid_saved_type);
1329
	types_destroy (&sid_current_type);
1330
    }
1331
@};
1332
 
1333
<add-entry>: (string) -> () = @{
1334
    EntryP entry = table_get_rule (sid_current_table, @&string);
1335
 
1336
    if (entry) {
1337
	if (entry_list_contains (sid_current_entry_list, entry)) {
1338
	    E_mult_entry (entry_key (entry));
1339
	} else {
1340
	    entry_list_add (sid_current_entry_list, entry);
1341
	    rule_required (entry_get_rule (entry));
1342
	}
1343
    } else {
1344
	E_unknown_rule (@&string);
1345
    }
1346
    nstring_destroy (&@=string);
1347
@};
1348
 
1349
// Error recovery stuff:
1350
 
1351
<unhandled-syntax-error> = @{
1352
    UNREACHED;
1353
@};
1354
 
1355
<expected-typemark> = @{
1356
    if (!sid_propagating_error) {
1357
	E_expected_typemark ();
1358
    }
1359
@};
1360
 
1361
<expected-identifier> = @{
1362
    if (!sid_propagating_error) {
1363
	E_expected_identifier ();
1364
    }
1365
@};
1366
 
1367
<expected-tuple-defn> = @{
1368
    if (!sid_propagating_error) {
1369
	E_expected_tuple_defn ();
1370
    }
1371
@};
1372
 
1373
<expected-terminal-decn> = @{
1374
    if (!sid_propagating_error) {
1375
	E_expected_terminal_decn ();
1376
    }
1377
@};
1378
 
1379
<expected-separator> = @{
1380
    if (!sid_propagating_error) {
1381
	E_expected_separator ();
1382
    }
1383
@};
1384
 
1385
<expected-open-tuple> = @{
1386
    if (!sid_propagating_error) {
1387
	E_expected_open_tuple ();
1388
    }
1389
@};
1390
 
1391
<expected-close-tuple> = @{
1392
    if (!sid_propagating_error) {
1393
	E_expected_close_tuple ();
1394
    }
1395
@};
1396
 
1397
<expected-arrow> = @{
1398
    if (!sid_propagating_error) {
1399
	E_expected_arrow ();
1400
    }
1401
@};
1402
 
1403
<expected-terminator> = @{
1404
    if (!sid_propagating_error) {
1405
	E_expected_terminator ();
1406
    }
1407
@};
1408
 
1409
<expected-lhs-name> = @{
1410
    if (!sid_propagating_error) {
1411
	E_expected_lhs_name ();
1412
    }
1413
@};
1414
 
1415
<expected-rhs-name> = @{
1416
    if (!sid_propagating_error) {
1417
	E_expected_rhs_name ();
1418
    }
1419
@};
1420
 
1421
<expected-begin-action> = @{
1422
    if (!sid_propagating_error) {
1423
	E_expected_begin_action ();
1424
    }
1425
@};
1426
 
1427
<expected-end-action> = @{
1428
    if (!sid_propagating_error) {
1429
	E_expected_end_action ();
1430
    }
1431
@};
1432
 
1433
<expected-end-scope> = @{
1434
    if (!sid_propagating_error) {
1435
	E_expected_end_scope ();
1436
    }
1437
@};
1438
 
1439
<expected-tuple-or-terminator> = @{
1440
    if (!sid_propagating_error) {
1441
	E_expected_tuple_or_term ();
1442
    }
1443
@};
1444
 
1445
<expected-item-rhs> = @{
1446
    if (!sid_propagating_error) {
1447
	E_expected_item_rhs ();
1448
    }
1449
@};
1450
 
1451
<expected-define> = @{
1452
    if (!sid_propagating_error) {
1453
	E_expected_define ();
1454
    }
1455
@};
1456
 
1457
<expected-tuple-or-define-or-terminator> = @{
1458
    if (!sid_propagating_error) {
1459
	E_expected_tuple_def_or_term ();
1460
    }
1461
@};
1462
 
1463
<expected-begin-rule> = @{
1464
    if (!sid_propagating_error) {
1465
	E_expected_begin_rule ();
1466
    }
1467
@};
1468
 
1469
<expected-end-rule> = @{
1470
    if (!sid_propagating_error) {
1471
	E_expected_end_rule ();
1472
    }
1473
@};
1474
 
1475
<expected-item> = @{
1476
    if (!sid_propagating_error) {
1477
	E_expected_item ();
1478
    }
1479
@};
1480
 
1481
<expected-alternative> = @{
1482
    if (!sid_propagating_error) {
1483
	E_expected_alternative ();
1484
    }
1485
@};
1486
 
1487
<expected-other-defn> = @{
1488
    if (!sid_propagating_error) {
1489
	E_expected_other_defn ();
1490
    }
1491
@};
1492
 
1493
<expected-production-defn> = @{
1494
    if (!sid_propagating_error) {
1495
	E_expected_production_defn ();
1496
    }
1497
@};
1498
 
1499
<expected-blt-types> = @{
1500
    if (!sid_propagating_error) {
1501
	E_expected_blt_types ();
1502
    }
1503
@};
1504
 
1505
<expected-blt-terminals> = @{
1506
    if (!sid_propagating_error) {
1507
	E_expected_blt_terminals ();
1508
    }
1509
@};
1510
 
1511
<expected-blt-productions> = @{
1512
    if (!sid_propagating_error) {
1513
	E_expected_blt_productions ();
1514
    }
1515
@};
1516
 
1517
<expected-blt-entry> = @{
1518
    if (!sid_propagating_error) {
1519
	E_expected_blt_entry ();
1520
    }
1521
@};
1522
 
1523
<expected-eof> = @{
1524
    if (!sid_propagating_error) {
1525
	E_expected_eof ();
1526
    }
1527
@};
1528
 
1529
<expected-terminator-or-define> = @{
1530
    if (!sid_propagating_error) {
1531
	E_expected_terminator_or_define ();
1532
    }
1533
@};
1534
 
1535
<destroy-string>: (string) -> () = @{
1536
    nstring_destroy (&@=string);
1537
@};
1538
 
1539
<skip-to-end-of-tuple-defn> = @{
1540
    if (sid_finished_terminals) {
1541
	while ((@. != LEXER_TOK_EOF) &&
1542
	       (@. != LEXER_TOK_DEFINE) &&
1543
	       (@. != LEXER_TOK_BEGIN_SCOPE) &&
1544
	       (@. != LEXER_TOK_BEGIN_RULE) &&
1545
	       (@. != LEXER_TOK_SEPARATOR) &&
1546
	       (@. != LEXER_TOK_CLOSE_TUPLE) &&
1547
	       (@. != LEXER_TOK_TERMINATOR) &&
1548
	       (@. != LEXER_TOK_BLT_ENTRY)) {
1549
	    if (@. == LEXER_TOK_IDENTIFIER) {
1550
		nstring_destroy (lexer_string_value (sid_current_stream));
1551
	    }
1552
	    @>;
1553
	}
1554
	if (@. == LEXER_TOK_IDENTIFIER) {
1555
	    nstring_destroy (lexer_string_value (sid_current_stream));
1556
	}
1557
	if (@. != LEXER_TOK_EOF) {
1558
	    @>;
1559
	}
1560
    } else {
1561
	while ((@. != LEXER_TOK_EOF) &&
1562
	       (@. != LEXER_TOK_SEPARATOR) &&
1563
	       (@. != LEXER_TOK_CLOSE_TUPLE) &&
1564
	       (@. != LEXER_TOK_TERMINATOR) &&
1565
	       (@. != LEXER_TOK_BLT_PRODUCTIONS) &&
1566
	       (@. != LEXER_TOK_BLT_ENTRY)) {
1567
	    if (@. == LEXER_TOK_IDENTIFIER) {
1568
		nstring_destroy (lexer_string_value (sid_current_stream));
1569
	    }
1570
	    @>;
1571
	}
1572
	if (@. == LEXER_TOK_IDENTIFIER) {
1573
	    nstring_destroy (lexer_string_value (sid_current_stream));
1574
	}
1575
	if (@. != LEXER_TOK_EOF) {
1576
	    @>;
1577
	}
1578
    }
1579
    sid_propagating_error = TRUE;
1580
@};
1581
 
1582
<skip-to-end-of-terminal-decn> = @{
1583
    while ((@. != LEXER_TOK_EOF) &&
1584
	   (@. != LEXER_TOK_TERMINATOR) &&
1585
	   (@. != LEXER_TOK_BLT_PRODUCTIONS) &&
1586
	   (@. != LEXER_TOK_BLT_ENTRY)) {
1587
	if (@. == LEXER_TOK_IDENTIFIER) {
1588
	    nstring_destroy (lexer_string_value (sid_current_stream));
1589
	}
1590
	@>;
1591
    }
1592
    if (@. == LEXER_TOK_IDENTIFIER) {
1593
	nstring_destroy (lexer_string_value (sid_current_stream));
1594
    }
1595
    if (@. != LEXER_TOK_EOF) {
1596
	@>;
1597
    }
1598
    sid_propagating_error = TRUE;
1599
@};
1600
 
1601
<skip-to-end-of-lhs-name> = @{
1602
    while ((@. != LEXER_TOK_EOF) &&
1603
	   (@. != LEXER_TOK_TERMINATOR) &&
1604
	   (@. != LEXER_TOK_BLT_PRODUCTIONS) &&
1605
	   (@. != LEXER_TOK_BLT_ENTRY)) {
1606
	if (@. == LEXER_TOK_IDENTIFIER) {
1607
	    nstring_destroy (lexer_string_value (sid_current_stream));
1608
	}
1609
	@>;
1610
    }
1611
    if (@. == LEXER_TOK_IDENTIFIER) {
1612
	nstring_destroy (lexer_string_value (sid_current_stream));
1613
    }
1614
    if (@. != LEXER_TOK_EOF) {
1615
	@>;
1616
    }
1617
    sid_propagating_error = TRUE;
1618
@};
1619
 
1620
<skip-to-end-of-rhs-name> = @{
1621
    while ((@. != LEXER_TOK_EOF) &&
1622
	   (@. != LEXER_TOK_TERMINATOR) &&
1623
	   (@. != LEXER_TOK_BLT_PRODUCTIONS) &&
1624
	   (@. != LEXER_TOK_BLT_ENTRY)) {
1625
	if (@. == LEXER_TOK_IDENTIFIER) {
1626
	    nstring_destroy (lexer_string_value (sid_current_stream));
1627
	}
1628
	@>;
1629
    }
1630
    if (@. == LEXER_TOK_IDENTIFIER) {
1631
	nstring_destroy (lexer_string_value (sid_current_stream));
1632
    }
1633
    if (@. != LEXER_TOK_EOF) {
1634
	@>;
1635
    }
1636
    sid_propagating_error = TRUE;
1637
@};
1638
 
1639
<skip-to-end-of-action-decn> = @{
1640
    while ((@. != LEXER_TOK_EOF) &&
1641
	   (@. != LEXER_TOK_TERMINATOR) &&
1642
	   (@. != LEXER_TOK_END_SCOPE) &&
1643
	   (@. != LEXER_TOK_BLT_PRODUCTIONS) &&
1644
	   (@. != LEXER_TOK_BLT_ENTRY)) {
1645
	if (@. == LEXER_TOK_IDENTIFIER) {
1646
	    nstring_destroy (lexer_string_value (sid_current_stream));
1647
	}
1648
	@>;
1649
    }
1650
    if (@. == LEXER_TOK_IDENTIFIER) {
1651
	nstring_destroy (lexer_string_value (sid_current_stream));
1652
    }
1653
    if (@. != LEXER_TOK_EOF) {
1654
	@>;
1655
    }
1656
    sid_propagating_error = TRUE;
1657
@};
1658
 
1659
<skip-to-end-of-item> = @{
1660
    while ((@. != LEXER_TOK_EOF) &&
1661
	   (@. != LEXER_TOK_TERMINATOR) &&
1662
	   (@. != LEXER_TOK_ALT_SEP) &&
1663
	   (@. != LEXER_TOK_HANDLER_SEP) &&
1664
	   (@. != LEXER_TOK_BEGIN_RULE) &&
1665
	   (@. != LEXER_TOK_END_RULE) &&
1666
	   (@. != LEXER_TOK_END_SCOPE) &&
1667
	   (@. != LEXER_TOK_BLT_PRODUCTIONS) &&
1668
	   (@. != LEXER_TOK_BLT_ENTRY)) {
1669
	if (@. == LEXER_TOK_IDENTIFIER) {
1670
	    nstring_destroy (lexer_string_value (sid_current_stream));
1671
	}
1672
	@>;
1673
    }
1674
    if (@. == LEXER_TOK_IDENTIFIER) {
1675
	nstring_destroy (lexer_string_value (sid_current_stream));
1676
    }
1677
    if (@. != LEXER_TOK_EOF) {
1678
	@>;
1679
    }
1680
    sid_propagating_error = TRUE;
1681
@};
1682
 
1683
<skip-to-end-of-alternative> = @{
1684
    while ((@. != LEXER_TOK_EOF) &&
1685
	   (@. != LEXER_TOK_ALT_SEP) &&
1686
	   (@. != LEXER_TOK_HANDLER_SEP) &&
1687
	   (@. != LEXER_TOK_END_RULE) &&
1688
	   (@. != LEXER_TOK_END_SCOPE) &&
1689
	   (@. != LEXER_TOK_BLT_PRODUCTIONS) &&
1690
	   (@. != LEXER_TOK_BLT_ENTRY)) {
1691
	if (@. == LEXER_TOK_IDENTIFIER) {
1692
	    nstring_destroy (lexer_string_value (sid_current_stream));
1693
	}
1694
	@>;
1695
    }
1696
    if (@. == LEXER_TOK_IDENTIFIER) {
1697
	nstring_destroy (lexer_string_value (sid_current_stream));
1698
    }
1699
    if (@. != LEXER_TOK_EOF) {
1700
	@>;
1701
    }
1702
    sid_propagating_error = TRUE;
1703
@};
1704
 
1705
<skip-to-end-of-other-defn> = @{
1706
    while ((@. != LEXER_TOK_EOF) &&
1707
	   (@. != LEXER_TOK_TERMINATOR) &&
1708
	   (@. != LEXER_TOK_END_SCOPE) &&
1709
	   (@. != LEXER_TOK_END_RULE) &&
1710
	   (@. != LEXER_TOK_BLT_PRODUCTIONS) &&
1711
	   (@. != LEXER_TOK_BLT_ENTRY)) {
1712
	if (@. == LEXER_TOK_IDENTIFIER) {
1713
	    nstring_destroy (lexer_string_value (sid_current_stream));
1714
	}
1715
	@>;
1716
    }
1717
    if (@. == LEXER_TOK_IDENTIFIER) {
1718
	nstring_destroy (lexer_string_value (sid_current_stream));
1719
    }
1720
    if (@. != LEXER_TOK_EOF) {
1721
	@>;
1722
    }
1723
    sid_propagating_error = TRUE;
1724
@};
1725
 
1726
<skip-to-end-of-production-defn> = @{
1727
    while ((@. != LEXER_TOK_EOF) &&
1728
	   (@. != LEXER_TOK_TERMINATOR) &&
1729
	   (@. != LEXER_TOK_END_SCOPE) &&
1730
	   (@. != LEXER_TOK_END_RULE) &&
1731
	   (@. != LEXER_TOK_BLT_PRODUCTIONS) &&
1732
	   (@. != LEXER_TOK_BLT_ENTRY)) {
1733
	if (@. == LEXER_TOK_IDENTIFIER) {
1734
	    nstring_destroy (lexer_string_value (sid_current_stream));
1735
	}
1736
	@>;
1737
    }
1738
    if (@. == LEXER_TOK_IDENTIFIER) {
1739
	nstring_destroy (lexer_string_value (sid_current_stream));
1740
    }
1741
    if (@. != LEXER_TOK_EOF) {
1742
	@>;
1743
    }
1744
    sid_propagating_error = TRUE;
1745
@};
1746
 
1747
<skip-to-end-of-entry-list> = @{
1748
    while ((@. != LEXER_TOK_EOF) &&
1749
	   (@. != LEXER_TOK_TERMINATOR) &&
1750
	   (@. != LEXER_TOK_SEPARATOR)) {
1751
	if (@. == LEXER_TOK_IDENTIFIER) {
1752
	    nstring_destroy (lexer_string_value (sid_current_stream));
1753
	}
1754
	@>;
1755
    }
1756
    if (@. == LEXER_TOK_IDENTIFIER) {
1757
	nstring_destroy (lexer_string_value (sid_current_stream));
1758
    }
1759
    if (@. != LEXER_TOK_EOF) {
1760
	@>;
1761
    }
1762
    sid_propagating_error = TRUE;
1763
@};
1764
 
1765
<skip-recover> = @{
1766
    sid_propagating_error = FALSE;
1767
@};
1768
 
1769
<is-blt-entry-or-end-scope-or-eof>: () -> (predicate) = @{
1770
    @predicate = ((@. == LEXER_TOK_EOF) ||
1771
		  (@. == LEXER_TOK_END_SCOPE) ||
1772
		  (@. == LEXER_TOK_BLT_ENTRY));
1773
@};
1774
 
1775
<is-close-tuple-or-skipped-or-eof>: () -> (predicate) = @{
1776
    @predicate = ((@. == LEXER_TOK_CLOSE_TUPLE) ||
1777
		  (@. == LEXER_TOK_EOF) ||
1778
		  (sid_propagating_error));
1779
@};
1780
 
1781
<is-terminator>: () -> (predicate) = @{
1782
    @predicate = (@. == LEXER_TOK_TERMINATOR);
1783
@};
1784
 
1785
<is-not-separator>: () -> (predicate) = @{
1786
    @predicate = (@. != LEXER_TOK_SEPARATOR);
1787
@};
1788
 
1789
%trailer% @{
1790
@}, @{
1791
@};