Subversion Repositories tendra.SVN

Rev

Details | 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
%types%
32
 
33
/*
34
    TYPES
35
 
36
    The types are fairly self-explanitory.  There are types for each of
37
    the concepts in the syntax, plus list types for most of them.
38
*/
39
 
40
CLASS-ID ;
41
FLAG ;
42
IDENTIFIER ;
43
NUMBER ;
44
TYPE ;
45
STRING ;
46
 
47
ARGUMENT ;
48
COMPONENT ;
49
ECONST ;
50
ENUM ;
51
FIELD ;
52
IDENTITY ;
53
MAP ;
54
PRIMITIVE ;
55
STRUCTURE ;
56
UNION ;
57
 
58
ARGUMENT-LIST ;
59
COMPONENT-LIST ;
60
ECONST-LIST ;
61
ENUM-LIST ;
62
FIELD-LIST ;
63
IDENTITY-LIST ;
64
MAP-LIST ;
65
PRIMITIVE-LIST ;
66
STRUCTURE-LIST ;
67
UNION-LIST ;
68
 
69
 
70
%terminals%
71
 
72
/*
73
    TERMINALS
74
 
75
    The terminals are in three groups, identifiers etc., keywords and
76
    symbols.
77
*/
78
 
79
identifier : () -> ( :IDENTIFIER ) ;
80
number : () -> ( :NUMBER ) ;
81
string : () -> ( :STRING ) ;
82
 
83
algebra ;
84
enum ;
85
struct ;
86
union ;
87
import ;
88
 
89
extras ;
90
identities ;
91
maps ;
92
primitives ;
93
structures ;
94
unions ;
95
with ;
96
 
97
list ;
98
ptr ;
99
stack ;
100
vec ;
101
vec-ptr ;
102
 
103
and ;
104
arrow ;
105
close-brace ;
106
close-round ;
107
close-square ;
108
colon ;
109
colon-colon ;
110
comma ;
111
compl ;
112
div ;
113
dot ;
114
eof ;
115
equal ;
116
exclaim ;
117
hash ;
118
lshift ;
119
minus ;
120
open-brace ;
121
open-round ;
122
open-square ;
123
or ;
124
plus ;
125
question ;
126
rem ;
127
rshift ;
128
semicolon ;
129
star ;
130
xor ;
131
!unknown ;
132
 
133
 
134
%productions%
135
 
136
 
137
/*
138
    ACTION DECLARATIONS
139
 
140
    Only the declarations of the various actions are given here.  They
141
    are described in more detail in the actions definition file.
142
*/
143
 
144
<zero> : () -> ( :FLAG ) ;
145
<one> : () -> ( :FLAG ) ;
146
<two> : () -> ( :FLAG ) ;
147
<three> : () -> ( :FLAG ) ;
148
 
149
<syntax-error> : () -> () ;
150
 
151
<null-string> : () -> ( :STRING ) ;
152
<null-identifier> : () -> ( :IDENTIFIER ) ;
153
 
154
<default-name> : ( :IDENTIFIER ) -> ( :IDENTIFIER ) ;
155
<make-class-id> : ( :IDENTIFIER, :IDENTIFIER, :FLAG ) -> ( :CLASS-ID ) ;
156
 
157
<find-type> : ( :IDENTIFIER ) -> ( :TYPE ) ;
158
<ptr-type> : ( :TYPE ) -> ( :TYPE ) ;
159
<list-type> : ( :TYPE ) -> ( :TYPE ) ;
160
<stack-type> : ( :TYPE ) -> ( :TYPE ) ;
161
<vec-type> : ( :TYPE ) -> ( :TYPE ) ;
162
<vec-ptr-type> : ( :TYPE ) -> ( :TYPE ) ;
163
<quoted-type> : ( :STRING ) -> ( :TYPE ) ;
164
<error-type> : () -> ( :TYPE ) ;
165
 
166
<null-econst> : () -> ( :ECONST-LIST ) ;
167
<make-econst> : ( :IDENTIFIER ) -> ( :ECONST ) ;
168
<join-econst> : ( :ECONST, :ECONST-LIST ) -> ( :ECONST-LIST ) ;
169
<set-econst> : ( :NUMBER ) -> () ;
170
 
171
<null-primitive> : () -> ( :PRIMITIVE-LIST ) ;
172
<make-primitive> : ( :CLASS-ID, :STRING ) -> ( :PRIMITIVE ) ;
173
<join-primitive> : ( :PRIMITIVE, :PRIMITIVE-LIST ) -> ( :PRIMITIVE-LIST ) ;
174
 
175
<null-identity> : () -> ( :IDENTITY-LIST ) ;
176
<make-identity> : ( :CLASS-ID, :TYPE ) -> ( :IDENTITY ) ;
177
<join-identity> : ( :IDENTITY, :IDENTITY-LIST ) -> ( :IDENTITY-LIST ) ;
178
 
179
<exp-crt> : () -> ( :NUMBER ) ;
180
<exp-id> : ( :IDENTIFIER ) -> ( :NUMBER ) ;
181
<exp-neg> : ( :NUMBER ) -> ( :NUMBER ) ;
182
<exp-compl> : ( :NUMBER ) -> ( :NUMBER ) ;
183
<exp-mult> : ( :NUMBER, :NUMBER ) -> ( :NUMBER ) ;
184
<exp-div> : ( :NUMBER, :NUMBER ) -> ( :NUMBER ) ;
185
<exp-rem> : ( :NUMBER, :NUMBER ) -> ( :NUMBER ) ;
186
<exp-plus> : ( :NUMBER, :NUMBER ) -> ( :NUMBER ) ;
187
<exp-minus> : ( :NUMBER, :NUMBER ) -> ( :NUMBER ) ;
188
<exp-lshift> : ( :NUMBER, :NUMBER ) -> ( :NUMBER ) ;
189
<exp-rshift> : ( :NUMBER, :NUMBER ) -> ( :NUMBER ) ;
190
<exp-and> : ( :NUMBER, :NUMBER ) -> ( :NUMBER ) ;
191
<exp-xor> : ( :NUMBER, :NUMBER ) -> ( :NUMBER ) ;
192
<exp-or> : ( :NUMBER, :NUMBER ) -> ( :NUMBER ) ;
193
 
194
<null-enum> : () -> ( :ENUM-LIST ) ;
195
<get-enum> : ( :IDENTIFIER ) -> ( :ECONST-LIST ) ;
196
<make-enum> : ( :CLASS-ID, :FLAG, :ECONST-LIST, :ECONST-LIST ) -> ( :ENUM ) ;
197
<join-enum> : ( :ENUM, :ENUM-LIST ) -> ( :ENUM-LIST ) ;
198
 
199
<null-component> : () -> ( :COMPONENT-LIST ) ;
200
<make-component> : ( :IDENTIFIER, :TYPE, :STRING ) -> ( :COMPONENT ) ;
201
<join-component> : ( :COMPONENT, :COMPONENT-LIST ) -> ( :COMPONENT-LIST ) ;
202
<link-component> : ( :COMPONENT-LIST, :COMPONENT-LIST ) -> ( :COMPONENT-LIST ) ;
203
 
204
<null-structure> : () -> ( :STRUCTURE-LIST ) ;
205
<make-structure> : ( :CLASS-ID, :IDENTIFIER, :COMPONENT-LIST ) -> ( :STRUCTURE ) ;
206
<join-structure> : ( :STRUCTURE, :STRUCTURE-LIST ) -> ( :STRUCTURE-LIST ) ;
207
 
208
<null-field> : () -> ( :FIELD-LIST ) ;
209
<make-field> : ( :IDENTIFIER, :COMPONENT-LIST, :FLAG ) -> ( :FIELD ) ;
210
<join-field> : ( :FIELD, :FIELD-LIST ) -> ( :FIELD-LIST ) ;
211
<link-field> : ( :FIELD-LIST, :FIELD-LIST ) -> ( :FIELD-LIST ) ;
212
<set-field-cmp> : ( :FIELD-LIST, :IDENTIFIER, :COMPONENT-LIST ) -> () ;
213
 
214
<null-argument> : () -> ( :ARGUMENT-LIST ) ;
215
<make-argument> : ( :IDENTIFIER, :TYPE ) -> ( :ARGUMENT ) ;
216
<join-argument> : ( :ARGUMENT, :ARGUMENT-LIST ) -> ( :ARGUMENT-LIST ) ;
217
<link-argument> : ( :ARGUMENT-LIST, :ARGUMENT-LIST ) -> ( :ARGUMENT-LIST ) ;
218
 
219
<null-map> : () -> ( :MAP-LIST ) ;
220
<make-map> : ( :IDENTIFIER, :TYPE, :ARGUMENT-LIST, :FLAG ) -> ( :MAP ) ;
221
<join-map> : ( :MAP, :MAP-LIST ) -> ( :MAP-LIST ) ;
222
 
223
<null-union> : () -> ( :UNION-LIST ) ;
224
<make-union> : ( :CLASS-ID, :IDENTIFIER, :COMPONENT-LIST, :FIELD-LIST, :MAP-LIST ) -> ( :UNION ) ;
225
<join-union> : ( :UNION, :UNION-LIST ) -> ( :UNION-LIST ) ;
226
 
227
<make-extra> : ( :TYPE ) -> () ;
228
 
229
<import-all> : ( :IDENTIFIER ) -> () ;
230
<import-one> : ( :IDENTIFIER, :IDENTIFIER ) -> () ;
231
 
232
<set-main> : ( :IDENTIFIER ) -> () ;
233
<set-version> : ( :NUMBER, :NUMBER ) -> () ;
234
<add-primitive> : ( :PRIMITIVE-LIST ) -> () ;
235
<add-identity> : ( :IDENTITY-LIST ) -> () ;
236
<add-enum> : ( :ENUM-LIST ) -> () ;
237
<add-structure> : ( :STRUCTURE-LIST ) -> () ;
238
<add-union> : ( :UNION-LIST ) -> () ;
239
 
240
<set-old-unit> : () -> () ;
241
<set-new-unit> : () -> () ;
242
 
243
 
244
/*
245
    CLASS IDENTIFIERS
246
 
247
    A class identifier consists of a pair of identifiers (the second of
248
    which is optional) qualified as above.
249
*/
250
 
251
class-id : () -> ( i : CLASS-ID ) = {
252
	{
253
		n = <zero> ;
254
	    ||	hash ; n = <one> ;
255
	    ||	colon ; n = <two> ;
256
	    ||	hash ; colon ; n = <three> ;
257
	} ;
258
	c = identifier ;
259
	{
260
		a = <default-name> ( c ) ;
261
	    ||	open-round ; a = identifier ; close-round ;
262
	} ;
263
	i = <make-class-id> ( c, a, n ) ;
264
} ;
265
 
266
 
267
/*
268
    TYPES
269
 
270
    The basic types are the named types defined in the algebra, plus
271
    those formed by the vector, pointer, list and vector-pointer type
272
    constructors.
273
*/
274
 
275
type : () -> ( t : TYPE ) = {
276
	i = identifier ; t = <find-type> ( i ) ;
277
    ||	list ; s = type ; t = <list-type> ( s ) ;
278
    ||	ptr ; s = type ; t = <ptr-type> ( s ) ;
279
    ||	stack ; s = type ; t = <stack-type> ( s ) ;
280
    ||	vec ; s = type ; t = <vec-type> ( s ) ;
281
    ||	vec-ptr ; s = type ; t = <vec-ptr-type> ( s ) ;
282
    ##	t = <error-type> ;
283
} ;
284
 
285
 
286
/*
287
    EXTENDED TYPES
288
 
289
    In some circumstances types may also be given by means of a quoted
290
    C type.
291
*/
292
 
293
extended-type : () -> ( t : TYPE ) = {
294
	t = type ;
295
    ||	s = string ; t = <quoted-type> ( s ) ;
296
    ##	t = <error-type> ;
297
} ;
298
 
299
 
300
/*
301
    PRIMITIVE DEFINITIONS
302
 
303
    Each primitive consists of a class identifier plus a string giving
304
    the C type corresponding to the primitive.
305
*/
306
 
307
primitive-defn : ( i : CLASS-ID ) -> ( p : PRIMITIVE ) = {
308
	s = string ; semicolon ;
309
	p = <make-primitive> ( i, s ) ;
310
} ;
311
 
312
primitive-list : () -> ( p : PRIMITIVE-LIST ) = {
313
	p = <null-primitive> ;
314
    ||
315
	i = class-id ; colon ; q = primitive-defn ( i ) ;
316
	r = primitive-list ;
317
	p = <join-primitive> ( q, r ) ;
318
} ;
319
 
320
primitive-single : () -> ( p : PRIMITIVE-LIST ) = {
321
	i = class-id ; equal ; q = primitive-defn ( i ) ;
322
	r = <null-primitive> ;
323
	p = <join-primitive> ( q, r ) ;
324
} ;
325
 
326
 
327
/*
328
    IDENTITY DEFINITIONS
329
 
330
    Each identity consists of a class identifier plus a type which forms
331
    the definition of the identity.
332
*/
333
 
334
identity-defn : ( i : CLASS-ID ) -> ( p : IDENTITY ) = {
335
	t = type ; semicolon ;
336
	p = <make-identity> ( i, t ) ;
337
} ;
338
 
339
identity-list : () -> ( p : IDENTITY-LIST ) = {
340
	p = <null-identity> ;
341
    ||
342
	i = class-id ; colon ; q = identity-defn ( i ) ;
343
	r = identity-list ;
344
	p = <join-identity> ( q, r ) ;
345
} ;
346
 
347
identity-single : () -> ( p : IDENTITY-LIST ) = {
348
	i = class-id ; equal ; q = identity-defn ( i ) ;
349
	r = <null-identity> ;
350
	p = <join-identity> ( q, r ) ;
351
} ;
352
 
353
 
354
/*
355
    ENUMERATOR VALUE
356
 
357
    These rules describe the ways of calculating the value of an enumerator.
358
*/
359
 
360
expression : () -> ( :NUMBER ) ;
361
 
362
primary-exp : () -> ( n : NUMBER ) = {
363
	n = number ;
364
    ||	e = identifier ; n = <exp-id> ( e ) ;
365
    ||	question ; n = <exp-crt> ;
366
    ||	open-round ; n = expression ; close-round ;
367
} ;
368
 
369
unary-exp : () -> ( n : NUMBER ) = {
370
	n = primary-exp ;
371
    ||	plus ; n = number ;
372
    ||	minus ; m = number ; n = <exp-neg> ( m ) ;
373
    ||	compl ; m = number ; n = <exp-compl> ( m ) ;
374
} ;
375
 
376
mult-exp : () -> ( n : NUMBER ) = {
377
	n = unary-exp ;
378
    ||	m = mult-exp ; star ; p = unary-exp ; n = <exp-mult> ( m, p ) ;
379
    ||	m = mult-exp ; div ; p = unary-exp ; n = <exp-div> ( m, p ) ;
380
    ||	m = mult-exp ; rem ; p = unary-exp ; n = <exp-rem> ( m, p ) ;
381
} ;
382
 
383
add-exp : () -> ( n : NUMBER ) = {
384
	n = mult-exp ;
385
    ||	m = add-exp ; plus ; p = mult-exp ; n = <exp-plus> ( m, p ) ;
386
    ||	m = add-exp ; minus ; p = mult-exp ; n = <exp-minus> ( m, p ) ;
387
} ;
388
 
389
shift-exp : () -> ( n : NUMBER ) = {
390
	n = add-exp ;
391
    ||	m = shift-exp ; lshift ; p = add-exp ; n = <exp-lshift> ( m, p ) ;
392
    ||	m = shift-exp ; rshift ; p = add-exp ; n = <exp-rshift> ( m, p ) ;
393
} ;
394
 
395
and-exp : () -> ( n : NUMBER ) = {
396
	n = shift-exp ;
397
    ||	m = and-exp ; and ; p = shift-exp ; n = <exp-and> ( m, p ) ;
398
} ;
399
 
400
xor-exp : () -> ( n : NUMBER ) = {
401
	n = and-exp ;
402
    ||	m = xor-exp ; xor ; p = and-exp ; n = <exp-xor> ( m, p ) ;
403
} ;
404
 
405
or-exp : () -> ( n : NUMBER ) = {
406
	n = xor-exp ;
407
    ||	m = or-exp ; or ; p = xor-exp ; n = <exp-or> ( m, p ) ;
408
} ;
409
 
410
expression : () -> ( n : NUMBER ) = {
411
	n = or-exp ;
412
} ;
413
 
414
 
415
/*
416
    ENUMERATOR LIST
417
 
418
    An enumerator is just an identifier.  A comma separated list of
419
    enumerators is used to define an enumeration.
420
*/
421
 
422
enumerator-list : () -> ( p : ECONST-LIST ) = {
423
	p = <null-econst> ;
424
    ||
425
	s = identifier ;
426
	{
427
	    	equal ; n = expression ; <set-econst> ( n ) ;
428
	    ||	$ ;
429
	} ;
430
	q = <make-econst> ( s ) ;
431
	{
432
		r = <null-econst> ;
433
	    ||	comma ; r = enumerator-list ;
434
	} ;
435
	p = <join-econst> ( q, r ) ;
436
} ;
437
 
438
 
439
/*
440
    ENUMERATION DEFINITIONS
441
 
442
    Each enumeration consists of a class identifier plus a list of
443
    enumerators which comprise the enumeration.
444
*/
445
 
446
enum-single : () -> ( p : ENUM-LIST ) = {
447
	enum ;
448
	{
449
		l = <one> ;
450
	    ||	exclaim ; l = <zero> ;
451
	} ;
452
	i = class-id ; equal ;
453
	{
454
	    	j = identifier ; f = <get-enum> ( j ) ; plus ;
455
	    ||	f = <null-econst> ;
456
	} ;
457
	open-brace ; e = enumerator-list ; close-brace ; semicolon ;
458
	q = <make-enum> ( i, l, f, e ) ;
459
	r = <null-enum> ;
460
	p = <join-enum> ( q, r ) ;
461
} ;
462
 
463
 
464
/*
465
    STRUCTURE COMPONENT DECLARATOR
466
 
467
    A structure component declarator consists of a comma separated list
468
    of identifiers, all of which are declared to have the given type t.
469
*/
470
 
471
component-decl : ( t : TYPE ) -> ( p : COMPONENT-LIST ) = {
472
	i = identifier ;
473
	{
474
		v = <null-string> ;
475
	    ||	equal ; v = string ;
476
	} ;
477
	q = <make-component> ( i, t, v ) ;
478
	{
479
		r = <null-component> ;
480
	    ||	comma ; r = component-decl ( t ) ;
481
	} ;
482
	p = <join-component> ( q, r ) ;
483
} ;
484
 
485
 
486
/*
487
    STRUCTURE COMPONENTS
488
 
489
    Each structure component consists of a component type plus a list
490
    of component declarators which are declared to be of that type.
491
*/
492
 
493
component-list : () -> ( p : COMPONENT-LIST ) = {
494
	p = <null-component> ;
495
    ||
496
	t = type ; q = component-decl ( t ) ; semicolon ;
497
	r = component-list ;
498
	p = <link-component> ( q, r ) ;
499
} ;
500
 
501
 
502
/*
503
    GROUP OF STRUCTURE COMPONENTS
504
 
505
    The definition of a structure consists of a list of structure components
506
    enclosed in braces.
507
*/
508
 
509
component-group : () -> ( p : COMPONENT-LIST ) = {
510
	open-brace ; p = component-list ; close-brace ;
511
} ;
512
 
513
 
514
/*
515
    STRUCTURE DEFINITIONS
516
 
517
    Each structure consists of a class identifier plus a list of the
518
    components comprising the structure.
519
*/
520
 
521
structure-defn : ( i : CLASS-ID, j : IDENTIFIER ) -> ( p : STRUCTURE ) = {
522
	c = component-group ; semicolon ;
523
	p = <make-structure> ( i, j, c ) ;
524
} ;
525
 
526
structure-list : () -> ( p : STRUCTURE-LIST ) = {
527
	p = <null-structure> ;
528
    ||
529
	i = class-id ; j = <null-identifier> ;
530
	q = structure-defn ( i, j ) ;
531
	r = structure-list ;
532
	p = <join-structure> ( q, r ) ;
533
} ;
534
 
535
structure-single : () -> ( p : STRUCTURE-LIST ) = {
536
	struct ; i = class-id ; equal ;
537
	{
538
		j = identifier ; plus ;
539
	    ||	j = <null-identifier> ;
540
	} ;
541
	q = structure-defn ( i, j ) ;
542
	r = <null-structure> ;
543
	p = <join-structure> ( q, r ) ;
544
} ;
545
 
546
 
547
/*
548
    UNION FIELD DEFINITIONS
549
 
550
    Each union field component consists of a list of field identifiers
551
    (qualified by nought, one or two hash symbols) and a list of
552
    structure components.
553
*/
554
 
555
field-id-list : ( n : FLAG ) -> ( p : FIELD-LIST ) = {
556
	i = identifier ;
557
	c = <null-component> ;
558
	q = <make-field> ( i, c, n ) ;
559
	{
560
		r = <null-field> ;
561
	    ||	comma ; r = field-id-list ( n ) ;
562
	} ;
563
	p = <join-field> ( q, r ) ;
564
} ;
565
 
566
field-list : () -> ( p : FIELD-LIST ) = {
567
	{
568
		n = <zero> ;
569
	    ||	hash ; n = <one> ;
570
	    ||	hash ; hash ; n = <two> ;
571
	} ;
572
	q = field-id-list ( n ) ; arrow ;
573
	{
574
		j = identifier ; plus ;
575
	    ||	j = <null-identifier> ;
576
	} ;
577
	c = component-group ;
578
	<set-field-cmp> ( q, j, c ) ;
579
	{
580
		r = <null-field> ;
581
	    ||	comma ; r = field-list ;
582
	} ;
583
	p = <link-field> ( q, r ) ;
584
} ;
585
 
586
 
587
/*
588
    MAP ARGUMENT DECLARATORS
589
 
590
    A map argument declarator consists of a list of identifiers, each of
591
    which is declared as a argument of the given type t.
592
*/
593
 
594
argument-decl : ( t : TYPE ) -> ( p : ARGUMENT-LIST ) = {
595
	i = identifier ;
596
	q = <make-argument> ( i, t ) ;
597
	{
598
		r = <null-argument> ;
599
	    ||	comma ; r = argument-decl ( t ) ;
600
	} ;
601
	p = <join-argument> ( q, r ) ;
602
} ;
603
 
604
 
605
/*
606
    MAP ARGUMENT LISTS
607
 
608
    Each map argument consists of a type (which may be a quoted C type)
609
    followed by a list of argument declarators which declare arguments
610
    of that type.
611
*/
612
 
613
argument-list : () -> ( p : ARGUMENT-LIST ) = {
614
	t = extended-type ;
615
	q = argument-decl ( t ) ;
616
	{
617
		r = <null-argument> ;
618
	    ||	semicolon ; r = argument-list ;
619
	} ;
620
	p = <link-argument> ( q, r ) ;
621
} ;
622
 
623
 
624
/*
625
    UNION MAP DEFINITIONS
626
 
627
    Each union map consists of a map return type, followed by the map
628
    identifier (which may be qualified by a hash symbol), and a list
629
    of map arguments.
630
*/
631
 
632
map-list : () -> ( p : MAP-LIST ) = {
633
	p = <null-map> ;
634
    ||
635
	t = extended-type ;
636
	{
637
		n = <zero> ;
638
	    ||	hash ; n = <one> ;
639
	} ;
640
	i = identifier ;
641
	open-round ;
642
	{
643
		a = <null-argument> ;
644
	    ||	a = argument-list ;
645
	} ;
646
	close-round ;
647
	q = <make-map> ( i, t, a, n ) ;
648
	r = map-list ;
649
	p = <join-map> ( q, r ) ;
650
} ;
651
 
652
 
653
/*
654
    OLD-STYLE UNION DEFINITION BODY
655
 
656
    Both old and new style union definitions give the same information.
657
    There is an optional list of structure components, which are common
658
    to all forms of the union.  This is followed by a list of union
659
    fields, describing the components which are particular to each form.
660
    Finally there is a list of union maps.
661
*/
662
 
663
union-defn-old : ( i : CLASS-ID ) -> ( p : UNION ) = {
664
	{
665
		c = <null-component> ;
666
	    ||	c = component-group ;
667
	} ;
668
	{
669
		f = <null-field> ;
670
	    ||	f = field-list ;
671
	} ;
672
	with ; maps ; open-square ; m = map-list ; close-square ;
673
	j = <null-identifier> ;
674
	p = <make-union> ( i, j, c, f, m ) ;
675
} ;
676
 
677
 
678
/*
679
    NEW-STYLE UNION DEFINITION BODY
680
 
681
    New-style union definitions convey the same information as the
682
    old-style, only differently punctuated.
683
*/
684
 
685
union-defn-new : ( i : CLASS-ID ) -> ( p : UNION ) = {
686
	equal ;
687
	{
688
		c = component-group ; j = <null-identifier> ;
689
	    ||	c = <null-component> ; j = identifier ;
690
	} ;
691
	plus ; open-brace ; f = field-list ; close-brace ;
692
	{
693
		m = <null-map> ;
694
	    ||	colon ; open-square ; m = map-list ; close-square ;
695
	} ;
696
	semicolon ;
697
	p = <make-union> ( i, j, c, f, m ) ;
698
} ;
699
 
700
 
701
/*
702
    UNION DEFINITIONS
703
 
704
    Each union consists of a class identifier plus a further section
705
    of information.  This information is expressed differently depending
706
    on whether the new-style or the old-style syntax is being used.
707
*/
708
 
709
union-list : () -> ( p : UNION-LIST ) = {
710
	p = <null-union> ;
711
    ||
712
	i = class-id ; q = union-defn-old ( i ) ;
713
	r = union-list ;
714
	p = <join-union> ( q, r ) ;
715
} ;
716
 
717
union-single : () -> ( p : UNION-LIST ) = {
718
	union ; i = class-id ; q = union-defn-new ( i ) ;
719
	r = <null-union> ;
720
	p = <join-union> ( q, r ) ;
721
} ;
722
 
723
 
724
/*
725
    EXTRA DEFINITIONS
726
 
727
    The extra components are just a list of types.
728
*/
729
 
730
extra-list : () -> () = {
731
	$ ;
732
    ||
733
	t = type ; semicolon ;
734
	<make-extra> ( t ) ;
735
	extra-list ;
736
} ;
737
 
738
 
739
/*
740
    IMPORT ITEM
741
 
742
    This rule gives the different type of import rules.
743
*/
744
 
745
import-item : () -> () = {
746
	a = identifier ;
747
	<import-all> ( a ) ;
748
    ||
749
	a = identifier ; colon-colon ; i = identifier ;
750
	<import-one> ( a, i ) ;
751
} ;
752
 
753
 
754
/*
755
    OLD UNIT DEFINITION
756
 
757
    This rule gives the old form of the syntax.  Each section has a fixed
758
    position, and the algebra is terminated by a final hash symbol.
759
*/
760
 
761
old-unit : () -> () = {
762
	m = identifier ; <set-main> ( m ) ; colon ;
763
	primitives ; colon ; p = primitive-list ; <add-primitive> ( p ) ;
764
	identities ; colon ; i = identity-list ; <add-identity> ( i ) ;
765
	structures ; colon ; s = structure-list ; <add-structure> ( s ) ;
766
	unions ; colon ; u = union-list ; <add-union> ( u ) ;
767
	extras ; colon ; extra-list ;
768
	hash ;
769
} ;
770
 
771
 
772
/*
773
    NEW UNIT DEFINITION
774
 
775
    This rule gives the new form of the syntax.  After the initial name
776
    section, the subsequent sections may appear in any order (and more
777
    than once).
778
*/
779
 
780
new-item-list : () -> () = {
781
	$ ;
782
    ||
783
	{
784
		p = primitive-single ; <add-primitive> ( p ) ;
785
	    ||	i = identity-single ; <add-identity> ( i ) ;
786
	    ||	e = enum-single ; <add-enum> ( e ) ;
787
	    ||	s = structure-single ; <add-structure> ( s ) ;
788
	    ||	u = union-single ; <add-union> ( u ) ;
789
	    ||	import ; import-item ; semicolon ;
790
	} ;
791
	new-item-list ;
792
} ;
793
 
794
new-unit : () -> () = {
795
	algebra ; <set-new-unit> ; m = identifier ; <set-main> ( m ) ;
796
	{
797
		$ ;
798
	    ||
799
		open-round ; a = number ; dot ; b = number ; close-round ;
800
		<set-version> ( a, b ) ;
801
	} ;
802
	colon ;
803
	new-item-list ;
804
} ;
805
 
806
 
807
/*
808
    UNIT DEFINITION
809
 
810
    This rule is the main entry point.  The input consists of either an
811
    old-style or a new-style unit.
812
*/
813
 
814
unit : () -> () = {
815
	<set-old-unit> ;
816
	{
817
		old-unit ;
818
	    ||	new-unit ;
819
	} ;
820
	eof ;
821
    ##
822
	<syntax-error> ;
823
} ;
824
 
825
 
826
/*
827
    EXTRA UNIT DEFINITION
828
 
829
    This rule is the auxilliary entry point for extra types.
830
*/
831
 
832
extra-unit : () -> () = {
833
	extra-list ;
834
	eof ;
835
    ##
836
	<syntax-error> ;
837
} ;
838
 
839
%entry% unit, extra-unit ;