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
%types%
32
 
33
/*
34
    TYPES
35
 
36
    The types are fairly self-explanitory.  Note that distinctions are
37
    made in the parser type system which do not exist in the underlying
38
    program.
39
*/
40
 
41
BOOLEAN ;
42
COMMAND ;
43
COMMAND_KEY ;
44
IDENTIFIER ;
45
STRING ;
46
SUBSET_KEY ;
47
TYPE ;
48
TYPE_KEY ;
49
TYPE_LIST ;
50
TYPE_QUAL ;
51
TYPE_SPEC ;
52
VERSION ;
53
 
54
 
55
%terminals%
56
 
57
/*
58
    TERMINALS
59
 
60
    The terminals are arranged in five groups; the names and strings, the
61
    commands (beginning with '+'), the types, the special macro names
62
    (beginning with '~'), and the punctuators and operators.
63
*/
64
 
65
name : () -> ( :STRING ) ;
66
number : () -> ( :STRING ) ;
67
string : () -> ( :STRING ) ;
68
variable : () -> ( :STRING ) ;
69
comment : () -> ( :STRING ) ;
70
insert : () -> ( :STRING ) ;
71
build-insert : () -> ( :STRING ) ;
72
 
73
base-api ; constant ; define ; else ; endif ; enumerate ; exp ;
74
field ; func ; if ; ifdef ; ifndef ; implement ; info ; macro ; nat ;
7 7u83 75
set ; statement ; !subset ; token ; type ; typedef ; use ; defmin ;
2 7u83 76
 
77
arith ; char ; const ; double ; enum ; extern ; float ; int ; long ;
78
lvalue ; scalar ; short ; signed ; struct ; union ; unsigned ; void ;
79
volatile ; weak ;
80
 
81
building ; promote ; protect ; special ;
82
 
83
open-brace ; close-brace ; open-round ; close-round ; open-square ;
84
close-square ; assign ; colon ; comma ; dot ; !dot-dot ; ellipsis ;
85
equal ; exclaim ; minus ; or ; question ; semicolon ; star ; eof ;
86
!unknown ;
87
 
88
 
89
%productions%
90
 
91
 
92
/*
93
    BUILT-IN TYPES
94
 
95
    These rules describe the built-in types.  Illegal combinations of
96
    keywords are detected by the action <type_builtin>.
97
*/
98
 
99
<btype_char> : () -> ( :TYPE_SPEC ) ;
100
<btype_short> : () -> ( :TYPE_SPEC ) ;
101
<btype_int> : () -> ( :TYPE_SPEC ) ;
102
<btype_long> : () -> ( :TYPE_SPEC ) ;
103
<btype_signed> : () -> ( :TYPE_SPEC ) ;
104
<btype_unsigned> : () -> ( :TYPE_SPEC ) ;
105
<btype_float> : () -> ( :TYPE_SPEC ) ;
106
<btype_double> : () -> ( :TYPE_SPEC ) ;
107
<btype_void> : () -> ( :TYPE_SPEC ) ;
108
<btype_join> : ( :TYPE_SPEC, :TYPE_SPEC ) -> ( :TYPE_SPEC ) ;
109
 
110
type-keyword : () -> ( b : TYPE_SPEC ) = {
111
	char ; b = <btype_char> ;
112
    ||	short ; b = <btype_short> ;
113
    ||	int ; b = <btype_int> ;
114
    ||	long ; b = <btype_long> ;
115
    ||	signed ; b = <btype_signed> ;
116
    ||	unsigned ; b = <btype_unsigned> ;
117
    ||	float ; b = <btype_float> ;
118
    ||	double ; b = <btype_double> ;
119
    ||	void ; b = <btype_void> ;
120
} ;
121
 
122
builtin-type : () -> ( b : TYPE_SPEC ) = {
123
	a = type-keyword ;
124
	{
125
		d = builtin-type ; c = <btype_join> ( a, d ) ;
126
	    ||	c = a ;
127
	} ;
128
	b = c ;
129
} ;
130
 
131
 
132
/*
133
    SIMPLE TYPES
134
 
135
    These rules describes the simple, unqualified, types.
136
*/
137
 
138
<type_builtin> : ( :TYPE_SPEC ) -> ( :TYPE ) ;
139
<type_name> : ( :STRING, :TYPE_KEY ) -> ( :TYPE ) ;
140
<key_type> : () -> ( :TYPE_KEY ) ;
141
<key_struct_tag> : () -> ( :TYPE_KEY ) ;
142
<key_union_tag> : () -> ( :TYPE_KEY ) ;
143
<key_enum_tag> : () -> ( :TYPE_KEY ) ;
144
 
145
type-key : () -> ( tag : TYPE_KEY ) = {
146
	tag = <key_type> ;
147
    ||	struct ; tag = <key_struct_tag> ;
148
    ||	union ; tag = <key_union_tag> ;
149
    ||	enum ; tag = <key_enum_tag> ;
150
} ;
151
 
152
simple-type : () -> ( t : TYPE ) = {
153
	b = builtin-type ;
154
	t = <type_builtin> ( b ) ;
155
    ||
156
	tag = type-key ; nm = name ;
157
	t = <type_name> ( nm, tag ) ;
158
} ;
159
 
160
 
161
/*
162
    QUALIFIED TYPES
163
 
164
    These rules describe the type qualifiers and the qualified types.
165
*/
166
 
167
<cv_none> : () -> ( :TYPE_QUAL ) ;
168
<cv_const> : ( :TYPE_QUAL ) -> ( :TYPE_QUAL ) ;
169
<cv_volatile> : ( :TYPE_QUAL ) -> ( :TYPE_QUAL ) ;
170
<type_qualify> : ( :TYPE, :TYPE_QUAL ) -> ( :TYPE ) ;
171
 
172
type-qualifier : () -> ( :TYPE_QUAL ) ;
173
 
174
type-qualifier-opt : () -> ( cv : TYPE_QUAL ) = {
175
	cv = <cv_none> ;
176
    ||	cv = type-qualifier ;
177
} ;
178
 
179
type-qualifier : () -> ( cv : TYPE_QUAL ) = {
180
    	const ; a = type-qualifier-opt ;
181
	cv = <cv_const> ( a ) ;
182
    ||
183
    	volatile ; a = type-qualifier-opt ;
184
	cv = <cv_volatile> ( a ) ;
185
} ;
186
 
187
qualified-type : () -> ( t : TYPE ) = {
188
	t = simple-type ;
189
    ||
190
	cv = type-qualifier ; s = simple-type ;
191
	t = <type_qualify> ( s, cv ) ;
192
    ||
193
	s = simple-type ; cv = type-qualifier ;
194
	t = <type_qualify> ( s, cv ) ;
195
} ;
196
 
197
 
198
/*
199
    LVALUE QUALIFIERS
200
 
201
    This rule describes the lvalue and rvalue type qualifiers.
202
*/
203
 
204
<key_rvalue> : () -> ( :TYPE_KEY ) ;
205
<key_lvalue> : () -> ( :TYPE_KEY ) ;
206
 
207
object-qualifier : () -> ( lv : TYPE_KEY ) = {
208
	lvalue ; lv = <key_lvalue> ;
209
    ||	lv = <key_rvalue> ;
210
} ;
211
 
212
 
213
/*
214
    CONSTANT EXPRESSIONS
215
 
216
    This rule describes the constant expressions.  These comprise the
217
    numbers, the NAT token names, plus some simple operations on these
218
    values.  More complex expressions can be expressed using an insert.
219
*/
220
 
221
<value_none> : () -> ( :STRING ) ;
222
<value_nat> : ( :STRING ) -> ( :STRING ) ;
223
<value_not> : ( :STRING ) -> ( :STRING ) ;
224
<value_negate> : ( :STRING ) -> ( :STRING ) ;
225
 
226
constant-value : () -> ( s : STRING ) = {
227
	s = number ;
228
    ||	s = insert ;
229
    ||	a = name ; s = <value_nat> ( a ) ;
230
    ||  minus ; a = constant-value ; s = <value_negate> ( a ) ;
231
    ||  exclaim ; a = constant-value ; s = <value_not> ( a ) ;
232
} ;
233
 
234
 
235
/*
236
    POINTER TYPE OPERATOR
237
 
238
    This rule describes the pointer type operator.
239
*/
240
 
241
<type_ptr> : ( :TYPE_QUAL ) -> ( :TYPE ) ;
242
 
243
ptr-operator : () -> ( t : TYPE ) = {
244
	star ; cv = type-qualifier-opt ;
245
	t = <type_ptr> ( cv ) ;
246
} ;
247
 
248
 
249
/*
250
    ARRAY TYPE OPERATOR
251
 
252
    This rule describes the array type operator.
253
*/
254
 
255
<type_array> : ( :STRING ) -> ( :TYPE ) ;
256
 
257
array-operator : () -> ( t : TYPE ) = {
258
	open-square ;
259
	{
260
		a = constant-value ;
261
	    ||	a = <value_none> ;
262
	} ;
263
	close-square ;
264
	t = <type_array> ( a ) ;
265
} ;
266
 
267
 
268
/*
269
    BITFIELD TYPE OPERATOR
270
 
271
    This rule describes the bitfield type operator.
272
*/
273
 
274
<type_bitfield> : ( :STRING ) -> ( :TYPE ) ;
275
 
276
bitfield-operator : () -> ( t : TYPE ) = {
277
	colon ; a = constant-value ;
278
	t = <type_bitfield> ( a ) ;
279
} ;
280
 
281
 
282
/*
283
    FUNCTION TYPE OPERATOR
284
 
285
    These rules describe the function type operator.
286
*/
287
 
288
<type_func> : ( :TYPE_LIST ) -> ( :TYPE ) ;
289
<type_inject> : ( :TYPE, :TYPE ) -> ( :TYPE ) ;
290
<type_list_none> : () -> ( :TYPE_LIST ) ;
291
<type_list_empty> : () -> ( :TYPE_LIST ) ;
292
<type_list_ellipsis> : () -> ( :TYPE_LIST ) ;
293
<type_list_cons> : ( :TYPE, :TYPE_LIST ) -> ( :TYPE_LIST ) ;
294
<param_name> : ( :STRING ) -> () ;
295
abstract-declarator : () -> ( :STRING, :TYPE ) ;
296
 
297
parameter-declaration : () -> ( t : TYPE ) = {
298
	s = qualified-type ; ( nm, p ) = abstract-declarator ;
299
	t = <type_inject> ( p, s ) ;
300
	<param_name> ( nm ) ;
301
} ;
302
 
303
parameter-list : () -> ( p : TYPE_LIST ) = {
304
	t = parameter-declaration ;
305
	{
306
		comma ; q = parameter-list ;
307
	    ||	comma ; ellipsis ; q = <type_list_ellipsis> ;
308
	    ||	q = <type_list_none> ;
309
	} ;
310
	p = <type_list_cons> ( t, q ) ;
311
} ;
312
 
313
function-operator : () -> ( t : TYPE ) = {
314
	open-round ; p = parameter-list ; close-round ;
315
	t = <type_func> ( p ) ;
316
    ||
317
	open-round ; close-round ;
318
	p = <type_list_empty> ;
319
	t = <type_func> ( p ) ;
320
} ;
321
 
322
 
323
/*
324
    MACRO TYPE OPERATOR
325
 
326
    These rules describe the macro type operator.  This is similar to the
327
    function type operator except that each parameter may be specified
328
    as an lvalue and there are no ellipsis parameters.
329
*/
330
 
331
<type_lvalue> : ( :TYPE, :TYPE_KEY ) -> ( :TYPE ) ;
332
<type_macro> : ( :TYPE_LIST ) -> ( :TYPE ) ;
333
 
334
macro-param-declaration : () -> ( t : TYPE ) = {
335
	lv = object-qualifier ;
336
	s = qualified-type ; ( nm, p ) = abstract-declarator ;
337
	u = <type_inject> ( p, s ) ;
338
	t = <type_lvalue> ( u, lv ) ;
339
	<param_name> ( nm ) ;
340
} ;
341
 
342
macro-param-list : () -> ( p : TYPE_LIST ) = {
343
	t = macro-param-declaration ;
344
	{
345
		comma ; q = macro-param-list ;
346
	    ||	q = <type_list_none> ;
347
	} ;
348
	p = <type_list_cons> ( t, q ) ;
349
} ;
350
 
351
macro-operator : () -> ( t : TYPE ) = {
352
	open-round ; p = macro-param-list ; close-round ;
353
	t = <type_macro> ( p ) ;
354
    ||
355
	open-round ; close-round ;
356
	p = <type_list_none> ;
357
	t = <type_macro> ( p ) ;
358
} ;
359
 
360
 
361
/*
362
    MACRO DEFINITION PARAMETER LISTS
363
 
364
    These rules describe the macro definition parameter lists.  These
365
    comprise a simple list of identifier names.
366
*/
367
 
368
<param_none> : () -> ( :STRING ) ;
369
<param_empty> : () -> ( :STRING ) ;
370
<param_join> : ( :STRING, :STRING ) -> ( :STRING ) ;
371
 
372
define-param-list : () -> ( p : STRING ) = {
373
	n = name ; comma ; q = define-param-list ;
374
	p = <param_join> ( n, q ) ;
375
    ||
376
	p = name ;
377
} ;
378
 
379
define-param-clause : () -> ( p : STRING ) = {
380
	open-round ; p = define-param-list ; close-round ;
381
    ||	open-round ; close-round ; p = <param_empty> ;
382
    ||	p = <param_none> ;
383
} ;
384
 
385
 
386
/*
387
    OBJECT DECLARATORS
388
 
389
    These rules describe the object declarators.  These consist of an
390
    identifier qualified using pointer, array and function type
391
    operators.
392
*/
393
 
394
<type_none> : () -> ( :TYPE ) ;
395
declarator : () -> ( :IDENTIFIER, :TYPE ) ;
396
identifier : () -> ( :IDENTIFIER ) ;
397
 
398
direct-declarator : () -> ( id : IDENTIFIER, t : TYPE ) = {
399
	id = identifier ; t = <type_none> ;
400
    ||
401
	( id, p ) = direct-declarator ; s = function-operator ;
402
	t = <type_inject> ( p, s ) ;
403
    ||
404
	( id, p ) = direct-declarator ; s = array-operator ;
405
	t = <type_inject> ( p, s ) ;
406
    ||
407
	open-round ; ( id, t ) = declarator ; close-round ;
408
} ;
409
 
410
declarator : () -> ( id : IDENTIFIER, t : TYPE ) = {
411
	( id, t ) = direct-declarator ;
412
    ||
413
	p = ptr-operator ; ( id, s ) = declarator ;
414
	t = <type_inject> ( s, p ) ;
415
} ;
416
 
417
 
418
/*
419
    MACRO DECLARATORS
420
 
421
    These rules describe the macro declarators.  These are a restricted
422
    subset of the declarators in which only pointer operators are allowed.
423
*/
424
 
425
macro-declarator : () -> ( id : IDENTIFIER, t : TYPE ) = {
426
	id = identifier ; t = <type_none> ;
427
    ||
428
	p = ptr-operator ; ( id, s ) = macro-declarator ;
429
	t = <type_inject> ( s, p ) ;
430
} ;
431
 
432
 
433
/*
434
    ABSTRACT DECLARATORS
435
 
436
    These rules describe the abstract declarators, as used in function
437
    parameter declarations.  For simplicity, the case of a list of
438
    function parameters without a declarator has been omitted; function
439
    parameters should be pointers to functions, rather than functions,
440
    anyway.
441
*/
442
 
443
<name_none> : () -> ( :STRING ) ;
444
 
445
direct-abstract-declarator : () -> ( nm : STRING, t : TYPE ) = {
446
	nm = <name_none> ; t = <type_none> ;
447
    ||
448
	nm = name ; t = <type_none> ;
449
    ||
450
	( nm, p ) = direct-abstract-declarator ; s = array-operator ;
451
	t = <type_inject> ( p, s ) ;
452
    ||
453
	open-round ; ( nm, t ) = abstract-declarator ; close-round ;
454
    ||
455
	open-round ; ( nm, p ) = abstract-declarator ; close-round ;
456
	s = function-operator ;
457
	t = <type_inject> ( p, s ) ;
458
} ;
459
 
460
abstract-declarator : () -> ( nm : STRING, t : TYPE ) = {
461
	( nm, t ) = direct-abstract-declarator ;
462
    ||
463
	p = ptr-operator ; ( nm, s ) = abstract-declarator ;
464
	t = <type_inject> ( s, p ) ;
465
} ;
466
 
467
 
468
/*
469
    IDENTIFIER NAMES
470
 
471
    These rules describe the identifier names.  These comprise the actual
472
    internal name, plus an optional external name (the external and internal
473
    names are equal if this is not given).  Either name may have an
474
    associated version number.
475
*/
476
 
477
<field_name> : ( :STRING ) -> ( :STRING ) ;
478
<token_name> : ( :STRING ) -> ( :STRING ) ;
479
<version_none> : () -> ( :VERSION ) ;
480
<version_number> : ( :STRING ) -> ( :VERSION ) ;
481
<make_id> : ( :STRING, :VERSION, :STRING, :VERSION ) -> ( :IDENTIFIER ) ;
482
 
483
name-version : () -> ( v : VERSION ) = {
484
	dot ; n = number ; v = <version_number> ( n ) ;
485
    ||	v = <version_none> ;
486
} ;
487
 
488
internal-name : () -> ( nm : STRING, v : VERSION ) = {
489
	a = name ; v = name-version ;
490
	nm = <field_name> ( a ) ;
491
} ;
492
 
493
external-name : () -> ( nm : STRING, v : VERSION ) = {
494
	a = name ; v = name-version ;
495
	b = <field_name> ( a ) ;
496
	nm = <token_name> ( b ) ;
497
    ||
498
	nm = string ; v = name-version ;
499
} ;
500
 
501
identifier : () -> ( id : IDENTIFIER ) = {
502
	( nm, v ) = internal-name ;
503
	tnm = <token_name> ( nm ) ;
504
	id = <make_id> ( nm, v, tnm, v ) ;
505
    ||
506
	( nm, v ) = internal-name ; or ; ( tnm, tv ) = external-name ;
507
	id = <make_id> ( nm, v, tnm, tv ) ;
508
} ;
509
 
510
 
511
/*
512
    SUBSET NAMES
513
 
514
    These rules describe the specification subset names.  These consist
515
    of between one and three components, giving the API name, the header
516
    file within that API, and the subset of that header.
517
*/
518
 
519
<cmd_implement> : () -> ( :COMMAND_KEY ) ;
520
<cmd_use> : () -> ( :COMMAND_KEY ) ;
521
<api_name> : ( :STRING ) -> ( :STRING ) ;
522
<file_name> : ( :STRING, :STRING ) -> ( :STRING ) ;
523
<subset_name> : ( :STRING, :STRING, :STRING ) -> ( :STRING ) ;
524
 
525
implement-command : () -> ( cmd : COMMAND_KEY ) = {
526
	implement ; cmd = <cmd_implement> ;
527
    ||	use ; cmd = <cmd_use> ;
528
} ;
529
 
530
subset-name : () -> ( s : STRING ) = {
531
	a = string ;
532
	s = <api_name> ( a ) ;
533
    ||
534
	a = string ; comma ; b = string ;
535
	s = <file_name> ( a, b ) ;
536
    ||
537
	a = string ; comma ; b = string ; comma ; c = string ;
538
	s = <subset_name> ( a, b, c ) ;
539
} ;
540
 
541
use-subset-name : () -> ( s : STRING ) = {
542
	open-round ; a = string ; close-round ; comma ; b = string ;
543
	s = <file_name> ( a, b ) ;
544
} ;
545
 
546
 
547
/*
548
    SUBSET USAGE KEYS
549
 
550
    This rule describes the subset usage keys.  These are used to indicate
551
    whether a file inclusion refers to the specification output, the
552
    library building output, or both.
553
*/
554
 
555
<subset_none> : () -> ( :SUBSET_KEY ) ;
556
<subset_first> : () -> ( :SUBSET_KEY ) ;
557
<subset_second> : () -> ( :SUBSET_KEY ) ;
558
<subset_both> : () -> ( :SUBSET_KEY ) ;
559
<subset_next> : ( :SUBSET_KEY ) -> ( :SUBSET_KEY ) ;
560
 
561
subset-key : () -> ( key : SUBSET_KEY ) = {
562
	key = <subset_both> ;
563
    ||
564
	open-round ; question ; question ; close-round ;
565
	key = <subset_none> ;
566
    ||
567
	open-round ; exclaim ; question ; close-round ;
568
	key = <subset_first> ;
569
    ||
570
	open-round ; question ; exclaim ; close-round ;
571
	key = <subset_second> ;
572
    ||
573
	open-round ; exclaim ; exclaim ; close-round ;
574
	key = <subset_both> ;
575
} ;
576
 
577
 
578
/*
579
    CONDITIONAL COMPILATION COMMANDS
580
 
581
    These rules describe the conditional compilation commands.
582
*/
583
 
584
<cond_building> : () -> ( :STRING ) ;
585
<cond_protect> : ( :STRING, :STRING ) -> ( :STRING ) ;
586
<command_if> : ( :STRING ) -> ( :COMMAND ) ;
587
<command_ifdef> : ( :STRING ) -> ( :COMMAND ) ;
588
<command_ifndef> : ( :STRING ) -> ( :COMMAND ) ;
589
<command_endif> : ( :COMMAND, :STRING, :COMMAND, :COMMAND ) -> ( :COMMAND ) ;
590
 
591
ifdef-macro-name : () -> ( c : STRING ) = {
592
	c = name ;
593
    ||
594
	building ;
595
	c = <cond_building> ;
596
    ||
597
	protect ;
598
	open-round ; a = string ; comma ; b = string ; close-round ;
599
	c = <cond_protect> ( a, b ) ;
600
} ;
601
 
602
if-command : () -> ( c : COMMAND, s : STRING ) = {
603
	if ; s = constant-value ;
604
	c = <command_if> ( s ) ;
605
    ||
606
	ifdef ; s = ifdef-macro-name ;
607
	c = <command_ifdef> ( s ) ;
608
    ||
609
	ifndef ; s = ifdef-macro-name ;
610
	c = <command_ifndef> ( s ) ;
611
} ;
612
 
613
 
614
/*
615
    ENUMERATION COMMANDS
616
 
617
    These rules describe the enumeration commands.  Each enumeration type
618
    consists of a list of enumerator namess, each of which may be associated
619
    with a value.
620
*/
621
 
622
<command_none> : () -> ( :COMMAND ) ;
623
<command_join> : ( :COMMAND, :COMMAND ) -> ( :COMMAND ) ;
624
<declare_enumerator> : ( :IDENTIFIER, :STRING ) -> ( :COMMAND ) ;
625
<key_enum> : () -> ( :TYPE_KEY ) ;
626
 
627
enum-command : () -> ( tag : TYPE_KEY ) = {
628
	tag = <key_enum> ;
629
    ||	enum ; tag = <key_enum_tag> ;
630
} ;
631
 
632
enumerator : () -> ( c : COMMAND ) = {
633
	id = identifier ;
634
	{
635
		equal ; s = constant-value ;
636
	    ||	s = <value_none> ;
637
	} ;
638
	c = <declare_enumerator> ( id, s ) ;
639
} ;
640
 
641
enumerator-list : () -> ( c : COMMAND ) = {
642
	a = enumerator ;
643
	{
644
		comma ; b = enumerator-list ;
645
	    ||	b = <command_none> ;
646
	} ;
647
	c = <command_join> ( a, b ) ;
648
} ;
649
 
650
 
651
/*
652
    EXPRESSION COMMANDS
653
 
654
    These rules describe the expression commands.  Each expression command
655
    consists of an lvalue specifier, a qualified type plus a list of
656
    declarators.
657
*/
658
 
659
<cmd_constant> : () -> ( :COMMAND_KEY ) ;
660
<cmd_exp> : () -> ( :COMMAND_KEY ) ;
661
<cmd_exp_extern> : () -> ( :COMMAND_KEY ) ;
662
<declare_exp> : ( :COMMAND_KEY, :IDENTIFIER, :TYPE ) -> ( :COMMAND ) ;
663
 
664
exp-command : () -> ( cmd : COMMAND_KEY ) = {
665
	constant ; cmd = <cmd_constant> ;
666
    ||	exp ; cmd = <cmd_exp> ;
667
    ||	exp ; open-round ; const ; close-round ; cmd = <cmd_constant> ;
668
    ||	exp ; open-round ; extern ; close-round ; cmd = <cmd_exp_extern> ;
669
} ;
670
 
671
exp-declarator-list : ( cmd : COMMAND_KEY, s : TYPE, lv : TYPE_KEY )
672
		    -> ( c : COMMAND ) = {
673
	( id, p ) = declarator ;
674
	u = <type_inject> ( p, s ) ;
675
	t = <type_lvalue> ( u, lv ) ;
676
	a = <declare_exp> ( cmd, id, t ) ;
677
	{
678
		comma ; b = exp-declarator-list ( cmd, s, lv ) ;
679
	    ||	b = <command_none> ;
680
	} ;
681
	c = <command_join> ( a, b ) ;
682
} ;
683
 
684
 
685
/*
686
    FIELD COMMANDS
687
 
688
    These rules describe the field commands.  Each field consists of a
689
    qualified type and a list of declarators.  Conditional compilation
690
    of fields is allowed.
691
*/
692
 
693
<bool_true> : () -> ( :BOOLEAN ) ;
694
<bool_false> : () -> ( :BOOLEAN ) ;
695
<id_anon> : () -> ( :IDENTIFIER ) ;
696
<declare_field> : ( :IDENTIFIER, :TYPE, :TYPE ) -> ( :COMMAND ) ;
697
 
698
field-exact : () -> ( e : BOOLEAN ) = {
699
	assign ; e = <bool_true> ;
700
    ||	e = <bool_false> ;
701
} ;
702
 
703
field-declarator : () -> ( id : IDENTIFIER, t : TYPE ) = {
704
	( id, t ) = declarator ;
705
    ||
706
	id = identifier ; t = bitfield-operator ;
707
    ||
708
	t = bitfield-operator ; id = <id_anon> ;
709
} ;
710
 
711
field-declarator-list : ( m : TYPE, s : TYPE ) -> ( c : COMMAND ) = {
712
	( id, p ) = field-declarator ;
713
	t = <type_inject> ( p, s ) ;
714
	a = <declare_field> ( id, m, t ) ;
715
	{
716
		comma ; b = field-declarator-list ( m, s ) ;
717
	    ||	b = <command_none> ;
718
	} ;
719
	c = <command_join> ( a, b ) ;
720
} ;
721
 
722
field-list : ( m : TYPE ) -> ( c : COMMAND ) = {
723
	c = <command_none> ;
724
    ||
725
	t = qualified-type ;
726
	a = field-declarator-list ( m, t ) ; semicolon ;
727
	b = field-list ( m ) ;
728
	c = <command_join> ( a, b ) ;
729
    ||
730
	( i, s ) = if-command ;
731
	a = field-list ( m ) ;
732
	{
733
		else ; b = field-list ( m ) ;
734
	    ||	b = <command_none> ;
735
	} ;
736
	endif ;
737
	c1 = <command_endif> ( i, s, a, b ) ;
738
	c2 = field-list ( m ) ;
739
	c = <command_join> ( c1, c2 ) ;
740
} ;
741
 
742
 
743
/*
744
    FUNCTION COMMANDS
745
 
746
    This rule describes the various function command keys.
747
*/
748
 
749
<cmd_func> : () -> ( :COMMAND_KEY ) ;
750
<cmd_func_extern> : () -> ( :COMMAND_KEY ) ;
751
<cmd_func_weak> : () -> ( :COMMAND_KEY ) ;
752
 
753
func-command : () -> ( cmd : COMMAND_KEY ) = {
754
	func ; cmd = <cmd_func> ;
755
    ||
756
	func ; open-round ; extern ; close-round ;
757
	cmd = <cmd_func_extern> ;
758
    ||
759
	func ; open-round ; weak ; close-round ;
760
	cmd = <cmd_func_weak> ;
761
} ;
762
 
763
 
764
/*
765
    INTEGER CONSTANT COMMANDS
766
 
767
    This rule describes the integer constant commands.  This consists of
768
    a simple list of identifiers.
769
*/
770
 
771
<declare_nat> : ( :IDENTIFIER ) -> ( :COMMAND ) ;
772
 
773
nat-declarator-list : () -> ( c : COMMAND ) = {
774
	id = identifier ;
775
	a = <declare_nat> ( id ) ;
776
	{
777
		comma ; b = nat-declarator-list ;
778
	    ||	b = <command_none> ;
779
	} ;
780
	c = <command_join> ( a, b ) ;
781
} ;
782
 
783
 
784
/*
785
    TYPE COMMANDS
786
 
787
    These rules describe the type commands.  These comprise a list of
788
    identifiers, each preceeded by an optional type command key.
789
*/
790
 
791
<key_int> : () -> ( :TYPE_KEY ) ;
792
<key_signed> : () -> ( :TYPE_KEY ) ;
793
<key_unsigned> : () -> ( :TYPE_KEY ) ;
794
<key_float> : () -> ( :TYPE_KEY ) ;
795
<key_arith> : () -> ( :TYPE_KEY ) ;
796
<key_scalar> : () -> ( :TYPE_KEY ) ;
797
<key_struct> : () -> ( :TYPE_KEY ) ;
798
<key_union> : () -> ( :TYPE_KEY ) ;
799
<declare_type> : ( :TYPE_KEY, :IDENTIFIER ) -> ( :COMMAND ) ;
800
 
801
type-command : () -> ( tag : TYPE_KEY ) = {
802
	tag = <key_type> ;
803
    ||	open-round ; int ; close-round ; tag = <key_int> ;
804
    ||	open-round ; signed ; close-round ; tag = <key_signed> ;
805
    ||	open-round ; unsigned ; close-round ; tag = <key_unsigned> ;
806
    ||	open-round ; float ; close-round ; tag = <key_float> ;
807
    ||	open-round ; arith ; close-round ; tag = <key_arith> ;
808
    ||	open-round ; scalar ; close-round ; tag = <key_scalar> ;
809
    ||	open-round ; struct ; close-round ; tag = <key_struct> ;
810
    ||	open-round ; union ; close-round ; tag = <key_union> ;
811
    ||	struct ; tag = <key_struct_tag> ;
812
    ||	union ; tag = <key_union_tag> ;
813
} ;
814
 
815
type-declarator-list : () -> ( c : COMMAND ) = {
816
	tag = type-command ; id = identifier ;
817
	a = <declare_type> ( tag, id ) ;
818
	{
819
		comma ; b = type-declarator-list ;
820
	    ||	b = <command_none> ;
821
	} ;
822
	c = <command_join> ( a, b ) ;
823
} ;
824
 
825
 
826
/*
827
    SUBSET COMMAND
828
 
829
    These rules describes the subset command.  This is the main entry point
830
    into the grammar.
831
*/
832
 
833
<begin_subset> : ( :STRING ) -> ( :COMMAND ) ;
834
<end_subset> : ( :COMMAND, :COMMAND ) -> ( :COMMAND ) ;
835
<syntax_error> : () -> () ;
836
command-list : () -> ( :COMMAND ) ;
837
 
838
subset-command : () -> ( c : COMMAND ) = {
839
	set ; s = subset-name ; assign ;
840
	a = <begin_subset> ( s ) ;
841
	open-brace ; b = command-list ; close-brace ;
842
	c = <end_subset> ( a, b ) ;
843
} ;
844
 
845
specification : () -> ( c : COMMAND ) = {
846
	c = subset-command ;
847
	semicolon ; eof ;
848
    ##
849
	<syntax_error> ;
850
	c = <command_none> ;
851
} ;
852
 
853
 
854
/*
855
    SPECIFICATION COMMANDS
856
 
857
    This rule describes the main group of commands; those which introduce
858
    a specification item.
859
*/
860
 
861
<declare_base> : () -> ( :COMMAND ) ;
862
<declare_define> : ( :IDENTIFIER, :STRING, :STRING ) -> ( :COMMAND ) ;
7 7u83 863
<declare_defmin> : ( :IDENTIFIER, :STRING, :STRING ) -> ( :COMMAND ) ;
2 7u83 864
<declare_enum> : ( :TYPE_KEY, :IDENTIFIER, :COMMAND ) -> ( :COMMAND ) ;
865
<declare_func> : ( :COMMAND_KEY, :IDENTIFIER, :TYPE ) -> ( :COMMAND ) ;
866
<declare_macro> : ( :IDENTIFIER, :TYPE ) -> ( :COMMAND ) ;
867
<declare_promote> : ( :IDENTIFIER, :TYPE ) -> ( :COMMAND ) ;
868
<declare_stmt> : ( :IDENTIFIER, :TYPE ) -> ( :COMMAND ) ;
869
<declare_token> : ( :IDENTIFIER, :STRING ) -> ( :COMMAND ) ;
870
<declare_typedef> : ( :IDENTIFIER, :TYPE ) -> ( :COMMAND ) ;
871
<include_subset> : ( :COMMAND_KEY, :STRING, :SUBSET_KEY ) -> ( :COMMAND ) ;
872
<begin_field> : ( :IDENTIFIER, :TYPE_KEY ) -> ( :TYPE, :COMMAND ) ;
873
<end_field> : ( :TYPE, :COMMAND, :COMMAND, :BOOLEAN ) -> ( :COMMAND ) ;
874
<type_special> : ( :STRING ) -> ( :TYPE ) ;
875
<key_exp> : ( :COMMAND_KEY, :TYPE_KEY ) -> ( :TYPE_KEY ) ;
876
 
877
spec-command : () -> ( c : COMMAND ) = {
878
	base-api ;
879
	c = <declare_base> ;
880
    ||
881
	define ; id = identifier ; p = define-param-clause ;
882
	s = constant-value ;
883
	c = <declare_define> ( id, p, s ) ;
884
    ||
7 7u83 885
	defmin ; id = identifier ; p = define-param-clause ;
886
	s = constant-value ;
887
	c = <declare_defmin> ( id, p, s ) ;
888
    ||
2 7u83 889
	enumerate ; tag = enum-command ; id = identifier ; assign ;
890
	open-brace ; e = enumerator-list ; close-brace ;
891
	c = <declare_enum> ( tag, id, e ) ;
892
    ||
893
	cmd = exp-command ; lv1 = object-qualifier ;
894
	lv = <key_exp> ( cmd, lv1 ) ;
895
	t = qualified-type ;
896
	c = exp-declarator-list ( cmd, t, lv ) ;
897
    ||
898
	field ; tag = type-command ; id = identifier ; e = field-exact ;
899
	( t, a ) = <begin_field> ( id, tag ) ;
900
	open-brace ; b = field-list ( t ) ; close-brace ;
901
	c = <end_field> ( t, a, b, e ) ;
902
    ||
903
	cmd = func-command ; s = qualified-type ;
904
	( id, p ) = declarator ;
905
	t = <type_inject> ( p, s ) ;
906
	c = <declare_func> ( cmd, id, t ) ;
907
    ||
908
	macro ; lv = object-qualifier ;
909
	s = qualified-type ;
910
	( id, p ) = macro-declarator ;
911
	u = <type_inject> ( p, s ) ;
912
	v = <type_lvalue> ( u, lv ) ;
913
	{
914
		q = macro-operator ;
915
	    ||	q = <type_none> ;
916
	} ;
917
	t = <type_inject> ( q, v ) ;
918
	c = <declare_macro> ( id, t ) ;
919
    ||
920
	nat ; c = nat-declarator-list ;
921
    ||
922
	statement ; id = identifier ;
923
	{
924
		t = macro-operator ;
925
	    ||	t = <type_none> ;
926
	} ;
927
	c = <declare_stmt> ( id, t ) ;
928
    ||
929
	token ; id = identifier ; s = insert ;
930
	c = <declare_token> ( id, s ) ;
931
    ||
932
	type ; c = type-declarator-list ;
933
    ||
934
	typedef ;
935
	s = qualified-type ; ( id, p ) = declarator ;
936
	t = <type_inject> ( p, s ) ;
937
	c = <declare_typedef> ( id, t ) ;
938
    ||
939
	typedef ;
940
	promote ; open-round ; t = qualified-type ; close-round ;
941
	id = identifier ;
942
	c = <declare_promote> ( id, t ) ;
943
    ||
944
	typedef ;
945
	special ; open-round ; s = string ; close-round ;
946
	t = <type_special> ( s ) ;
947
	id = identifier ;
948
	c = <declare_typedef> ( id, t ) ;
949
    ||
950
	cmd = implement-command ;
951
	s = subset-name ; key = subset-key ;
952
	c = <include_subset> ( cmd, s, key ) ;
953
    ||
954
	use ; cmd = <cmd_use> ;
955
	s = use-subset-name ; key1 = subset-key ;
956
	key = <subset_next> ( key1 ) ;
957
	c = <include_subset> ( cmd, s, key ) ;
958
    ||
959
	c = subset-command ;
960
} ;
961
 
962
 
963
/*
964
    TEXTUAL COMMANDS
965
 
966
    This rule describes the second group of commands; those which are
967
    concerned with textual substitution.
968
*/
969
 
970
<declare_comment> : ( :STRING ) -> ( :COMMAND ) ;
971
<declare_insert> : ( :STRING ) -> ( :COMMAND ) ;
972
<declare_build_insert> : ( :STRING ) -> ( :COMMAND ) ;
973
 
974
text-command : () -> ( c : COMMAND ) = {
975
	( i, s ) = if-command ;
976
	a = command-list ;
977
	{
978
		else ; b = command-list ;
979
	    ||	b = <command_none> ;
980
	} ;
981
	endif ;
982
	c = <command_endif> ( i, s, a, b ) ;
983
    ||
984
	s = comment ;
985
	c = <declare_comment> ( s ) ;
986
    ||
987
	s = insert ;
988
	c = <declare_insert> ( s ) ;
989
    ||
990
	s = build-insert ;
991
	c = <declare_build_insert> ( s ) ;
992
} ;
993
 
994
 
995
/*
996
    VARIABLE COMMANDS
997
 
998
    This rule describes the third group of commands; those which affect the
999
    program environment, but do not actually introduce a specified item.
1000
*/
1001
 
1002
<variable_string> : ( :STRING, :STRING ) -> () ;
1003
<variable_plus> : ( :STRING, :STRING ) -> () ;
1004
<variable_minus> : ( :STRING, :STRING ) -> () ;
1005
 
1006
variable-command : () -> () = {
1007
	info ; s = string ;
1008
    ||
1009
	nm = variable ; equal ; s = string ;
1010
	<variable_string> ( nm, s ) ;
1011
    ||
1012
	nm = variable ; equal ; s = number ;
1013
	<variable_plus> ( nm, s ) ;
1014
    ||
1015
	nm = variable ; equal ; minus ; s = number ;
1016
	<variable_minus> ( nm, s ) ;
1017
} ;
1018
 
1019
 
1020
/*
1021
    COMMAND LISTS
1022
 
1023
    These rules describe the lists of commands.
1024
*/
1025
 
1026
command-list : () -> ( c : COMMAND ) = {
1027
	c = <command_none> ;
1028
    ||
1029
	a = spec-command ; semicolon ;
1030
	b = command-list ;
1031
	c = <command_join> ( a, b ) ;
1032
    ||
1033
	a = text-command ;
1034
	b = command-list ;
1035
	c = <command_join> ( a, b ) ;
1036
    ||
1037
	variable-command ; semicolon ;
1038
	c = command-list ;
1039
} ;
1040
 
1041
 
1042
%entry% specification ;