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
%prefixes%
2
 
3
terminal = lex_ ;
4
 
5
 
6
%maps%
7
 
8
 
9
/*
10
    ENTRY POINT
11
 
12
    The main entry point for is mapped onto a function named read_spec.
13
*/
14
 
15
specification -> read_spec ;
16
 
17
 
18
/*
19
    TYPE MAPPINGS
20
 
21
    These maps give the relationship between the types used in the syntax
22
    and in the C implementation.
23
*/
24
 
25
BOOLEAN -> int ;
26
COMMAND -> SID_COMMAND ;
27
COMMAND_KEY -> int ;
28
IDENTIFIER -> SID_IDENTIFIER ;
29
STRING -> SID_STRING ;
30
SUBSET_KEY -> SID_STRING ;
31
TYPE -> SID_TYPE ;
32
TYPE_KEY -> int ;
33
TYPE_LIST -> SID_TYPE ;
34
TYPE_QUAL -> unsigned ;
35
TYPE_SPEC -> unsigned ;
36
VERSION -> int ;
37
 
38
 
39
%header% @{
40
/*
41
    		 Crown Copyright (c) 1997
42
 
43
    This TenDRA(r) Computer Program is subject to Copyright
44
    owned by the United Kingdom Secretary of State for Defence
45
    acting through the Defence Evaluation and Research Agency
46
    (DERA).  It is made available to Recipients with a
47
    royalty-free licence for its use, reproduction, transfer
48
    to other parties and amendment for any purpose not excluding
49
    product development provided that any such use et cetera
50
    shall be deemed to be acceptance of the following conditions:-
51
 
52
        (1) Its Recipients shall ensure that this Notice is
53
        reproduced upon any copies or amended versions of it;
54
 
55
        (2) Any amended version of it shall be clearly marked to
56
        show both the nature of and the organisation responsible
57
        for the relevant amendment or amendments;
58
 
59
        (3) Its onward transfer from a recipient to another
60
        party shall be deemed to be that party's acceptance of
61
        these conditions;
62
 
63
        (4) DERA gives no warranty or assurance as to its
64
        quality or suitability for any purpose and DERA accepts
65
        no liability whatsoever in relation to any use to which
66
        it may be put.
67
*/
68
 
69
 
70
#include "config.h"
71
#include "object.h"
72
#include "hash.h"
73
#include "lex.h"
74
#include "name.h"
75
#include "syntax.h"
76
#include "type.h"
77
#include "utility.h"
78
#include "variable.h"
79
 
80
 
81
/*
82
    PARSER TYPES
83
 
84
    These types give the implementations of the various types used
85
    in the syntax.
86
*/
87
 
88
typedef char *SID_STRING ;
89
typedef type *SID_TYPE ;
90
 
91
typedef struct {
92
    char *iname ;
93
    char *ename ;
94
    int ivers ;
95
    int evers ;
96
} SID_IDENTIFIER ;
97
 
98
 
99
/*
100
    CURRENT FIELD NAME
101
 
102
    The name of the current structure is stored during a +FIELD
103
    construct.
104
*/
105
 
106
static char *crt_field_name = null ;
107
static int anon_no = 0 ;
108
 
109
 
110
/*
111
    CV-QUALIFIER NAMES
112
 
113
    This table gives the mapping between the values used to represent
114
    cv-qualifiers in the parser and the qualifier names used in the
115
    internal representation.
116
*/
117
 
118
static char *cv_qualifier [] = {
119
    null, "const", "volatile", "const volatile"
120
} ;
121
 
122
/*
123
    COMPILATION MODE
124
 
125
    We allow unreached code in the automatically generated sections.
126
*/
127
 
128
#if FS_TENDRA
129
#pragma TenDRA begin
130
#pragma TenDRA unreachable code allow
131
#pragma TenDRA variable analysis off
132
#endif
133
 
134
 
135
@}, @{
136
/*
137
    		 Crown Copyright (c) 1997
138
 
139
    This TenDRA(r) Computer Program is subject to Copyright
140
    owned by the United Kingdom Secretary of State for Defence
141
    acting through the Defence Evaluation and Research Agency
142
    (DERA).  It is made available to Recipients with a
143
    royalty-free licence for its use, reproduction, transfer
144
    to other parties and amendment for any purpose not excluding
145
    product development provided that any such use et cetera
146
    shall be deemed to be acceptance of the following conditions:-
147
 
148
        (1) Its Recipients shall ensure that this Notice is
149
        reproduced upon any copies or amended versions of it;
150
 
151
        (2) Any amended version of it shall be clearly marked to
152
        show both the nature of and the organisation responsible
153
        for the relevant amendment or amendments;
154
 
155
        (3) Its onward transfer from a recipient to another
156
        party shall be deemed to be that party's acceptance of
157
        these conditions;
158
 
159
        (4) DERA gives no warranty or assurance as to its
160
        quality or suitability for any purpose and DERA accepts
161
        no liability whatsoever in relation to any use to which
162
        it may be put.
163
*/
164
 
165
 
166
#ifndef SYNTAX_INCLUDED
167
#define SYNTAX_INCLUDED
168
 
169
typedef object *SID_COMMAND ;
170
@} ;
171
 
172
 
173
%terminals%
174
 
175
 
176
/*
177
    TERMINALS
178
 
179
    The mapping of the terminals is trivial.
180
*/
181
 
182
name : () -> ( s ) = @{ @s = token_value ; @} ;
183
number : () -> ( s ) = @{ @s = token_value ; @} ;
184
string : () -> ( s ) = @{ @s = token_value ; @} ;
185
variable : () -> ( s ) = @{ @s = token_value ; @} ;
186
comment : () -> ( s ) = @{ @s = token_value ; @} ;
187
insert : () -> ( s ) = @{ @s = token_value ; @} ;
188
build-insert : () -> ( s ) = @{ @s = token_value ; @} ;
189
 
190
 
191
%actions%
192
 
193
 
194
/*
195
    BOOLEAN CONSTANTS
196
 
197
    These actions describe the boolean constants.
198
*/
199
 
200
<bool_false> : () -> ( b ) = @{ @b = 0 ; @} ;
201
<bool_true> : () -> ( b ) = @{ @b = 1 ; @} ;
202
 
203
 
204
/*
205
    BASIC TYPE SPECIFIERS
206
 
207
    These actions describe the basic type specifiers.
208
*/
209
 
210
<btype_char> : () -> ( b ) = @{ @b = BTYPE_CHAR ; @} ;
211
<btype_short> : () -> ( b ) = @{ @b = BTYPE_SHORT ; @} ;
212
<btype_int> : () -> ( b ) = @{ @b = BTYPE_INT ; @} ;
213
<btype_long> : () -> ( b ) = @{ @b = BTYPE_LONG ; @} ;
214
<btype_signed> : () -> ( b ) = @{ @b = BTYPE_SIGNED ; @} ;
215
<btype_unsigned> : () -> ( b ) = @{ @b = BTYPE_UNSIGNED ; @} ;
216
<btype_float> : () -> ( b ) = @{ @b = BTYPE_FLOAT ; @} ;
217
<btype_double> : () -> ( b ) = @{ @b = BTYPE_DOUBLE ; @} ;
218
<btype_void> : () -> ( b ) = @{ @b = BTYPE_VOID ; @} ;
219
 
220
<btype_join> : ( a, b ) -> ( c ) = @{
221
    while ( @a & @b ) {
222
	if ( @a == BTYPE_LONG && allow_long_long ) {
223
	    @a = BTYPE_LLONG ;
224
	} else {
225
	    error ( ERR_SERIOUS, "Duplicate type specifier" ) ;
226
	    break ;
227
	}
228
    }
229
    @c = ( @a | @b ) ;
230
@} ;
231
 
232
 
233
/*
234
    TYPE KEYS
235
 
236
    These actions describe the type keys.
237
*/
238
 
239
<key_type> : () -> ( t ) = @{ @t = TYPE_GENERIC ; @} ;
240
<key_struct_tag> : () -> ( t ) = @{ @t = TYPE_STRUCT_TAG ; @} ;
241
<key_union_tag> : () -> ( t ) = @{ @t = TYPE_UNION_TAG ; @} ;
242
<key_enum_tag> : () -> ( t ) = @{ @t = TYPE_ENUM_TAG ; @} ;
243
<key_struct> : () -> ( t ) = @{ @t = TYPE_STRUCT ; @} ;
244
<key_union> : () -> ( t ) = @{ @t = TYPE_UNION ; @} ;
245
<key_enum> : () -> ( t ) = @{ @t = TYPE_ENUM ; @} ;
246
<key_int> : () -> ( t ) = @{ @t = TYPE_INT ; @} ;
247
<key_signed> : () -> ( t ) = @{ @t = TYPE_SIGNED ; @} ;
248
<key_unsigned> : () -> ( t ) = @{ @t = TYPE_UNSIGNED ; @} ;
249
<key_float> : () -> ( t ) = @{ @t = TYPE_FLOAT ; @} ;
250
<key_arith> : () -> ( t ) = @{ @t = TYPE_ARITH ; @} ;
251
<key_scalar> : () -> ( t ) = @{ @t = TYPE_SCALAR ; @} ;
252
<key_lvalue> : () -> ( t ) = @{ @t = TYPE_LVALUE ; @} ;
253
<key_rvalue> : () -> ( t ) = @{ @t = TYPE_RVALUE ; @} ;
254
 
255
<key_exp> : ( c, a ) -> ( t ) = @{
256
    if ( @c == OBJ_CONST ) {
257
	if ( @a == TYPE_LVALUE ) {
258
	    error ( ERR_SERIOUS, "Constant can't be an lvalue" ) ;
259
	}
260
	@t = TYPE_RVALUE ;
261
    } else if ( @c == OBJ_EXTERN ) {
262
	@t = TYPE_LVALUE ;
263
    } else {
264
	@t = @a ;
265
    }
266
@} ;
267
 
268
 
269
/*
270
    TYPE QUALIFIERS
271
 
272
    These actions describe the type qualifiers.  const is represented by 1
273
    and volatile by 2.
274
*/
275
 
276
<cv_none> : () -> ( c ) = @{
277
    @c = 0 ;
278
@} ;
279
 
280
<cv_const> : ( a ) -> ( c ) = @{
281
    if ( @a & 1 ) error ( ERR_SERIOUS, "Duplicate type qualifier" ) ;
282
    @c = ( @a | 1 ) ;
283
@} ;
284
 
285
<cv_volatile> : ( a ) -> ( c ) = @{
286
    if ( @a & 2 ) error ( ERR_SERIOUS, "Duplicate type qualifier" ) ;
287
    @c = ( @a | 2 ) ;
288
@} ;
289
 
290
 
291
/*
292
    TYPE CONSTRUCTORS
293
 
294
    These actions describe the type constructors.
295
*/
296
 
297
<type_none> : () -> ( t ) = @{
298
    @t = null ;
299
@} ;
300
 
301
<type_builtin> : ( b ) -> ( t ) = @{
302
    @t = basic_type ( @b ) ;
303
@} ;
304
 
305
<type_name> : ( s, tag ) -> ( t ) = @{
306
    @t = find_type ( @s, any_version, @tag, 1 ) ;
307
@} ;
308
 
309
<type_special> : ( s ) -> ( t ) = @{
310
    @t = special_type ( @s ) ;
311
@} ;
312
 
313
<type_inject> : ( s, p ) -> ( t ) = @{
314
    @t = inject_type ( @s, @p ) ;
315
@} ;
316
 
317
<type_ptr> : ( c ) -> ( t ) = @{
318
    @t = make_subtype ( ( type * ) null, TYPE_PTR ) ;
319
    @t->v.str = cv_qualifier [ @c ] ;
320
@} ;
321
 
322
<type_array> : ( a ) -> ( t ) = @{
323
    @t = make_subtype ( ( type * ) null, TYPE_ARRAY ) ;
324
    @t->v.str = @a ;
325
@} ;
326
 
327
<type_bitfield> : ( a ) -> ( t ) = @{
328
    @t = make_subtype ( ( type * ) null, TYPE_BITFIELD ) ;
329
    @t->v.str = @a ;
330
@} ;
331
 
332
<type_func> : ( p ) -> ( t ) = @{
333
    @t = make_subtype ( ( type * ) null, TYPE_PROC ) ;
334
    @t->v.next = @p ;
335
@} ;
336
 
337
<type_macro> : ( p ) -> ( t ) = @{
338
    @t = make_subtype ( ( type * ) null, TYPE_PROC ) ;
339
    @t->v.next = @p ;
340
@} ;
341
 
342
<type_qualify> : ( s, c ) -> ( t ) = @{
343
    @t = make_subtype ( @s, TYPE_QUALIFIER ) ;
344
    @t->v.str = cv_qualifier [ @c ] ;
345
@} ;
346
 
347
<type_lvalue> : ( s, lv ) -> ( t ) = @{
348
    @t = make_subtype ( @s, @lv ) ;
349
@} ;
350
 
351
 
352
/*
353
    TYPE LISTS
354
 
355
    These actions describe the parameter type lists.
356
*/
357
 
358
<type_list_none> : () -> ( p ) = @{
359
    @p = null ;
360
@} ;
361
 
362
<type_list_empty> : () -> ( p ) = @{
363
    error ( ERR_WARNING, "Empty parameter list" ) ;
364
    @p = null ;
365
@} ;
366
 
367
<type_list_cons> : ( t, q ) -> ( p ) = @{
368
    @p = make_subtype ( @t, TYPE_LIST ) ;
369
    @p->v.next = @q ;
370
@} ;
371
 
372
<type_list_ellipsis> : () -> ( p ) = @{
373
    @p = make_subtype ( type_ellipsis, TYPE_LIST ) ;
374
    @p->v.next = null ;
375
@} ;
376
 
377
<param_name> : ( nm ) -> () = @{
378
    UNUSED ( @nm ) ;
379
@} ;
380
 
381
 
382
/*
383
    CONSTANT EXPRESSIONS
384
 
385
    These actions describe the constant expressions.
386
*/
387
 
388
<value_none> : () -> ( s ) = @{
389
    @s = "" ;
390
@} ;
391
 
392
<value_negate> : ( a ) -> ( s ) = @{
393
    @s = string_concat ( "-", @a ) ;
394
@} ;
395
 
396
<value_not> : ( a ) -> ( s ) = @{
397
    @s = string_concat ( "!", @a ) ;
398
@} ;
399
 
400
<value_nat> : ( a ) -> ( s ) = @{
401
    object *p = search_hash ( exps, @a, any_version ) ;
402
    if ( p == null ) {
403
	error ( ERR_SERIOUS, "Undefined NAT, '%s'", @a ) ;
404
    } else if ( p->objtype != OBJ_NAT ) {
405
	error ( ERR_SERIOUS, "'%s' is not a NAT", @a ) ;
406
    }
407
    @s = @a ;
408
@} ;
409
 
410
 
411
/*
412
    CONDITIONAL COMPILATION MACROS 
413
 
414
    These rules describe the special macros which can be used in
415
    conditional compilation.
416
*/
417
 
418
<cond_building> : () -> ( s ) = @{
419
    @s = BUILDING_MACRO ;
420
@} ;
421
 
422
<cond_protect> : ( a, b ) -> ( s ) = @{
423
    @s = macro_name ( PROTECT_PREFIX, @a, @b, null_str ) ;
424
@} ;
425
 
426
 
427
/*
428
    MACRO DEFINITION PARAMETERS
429
 
430
    These rules describe the macro definition parameter lists.
431
*/
432
 
433
<param_none> : () -> ( p ) = @{ @p = null ; @} ;
434
<param_empty> : () -> ( p ) = @{ @p = "" ; @} ;
435
 
436
<param_join> : ( n, q ) -> ( p ) = @{
437
    @p = string_printf ( "%s, %s", @n, @q ) ;
438
@} ;
439
 
440
 
441
/*
442
    IDENTIFIERS
443
 
444
    These actions describe the identifier names.
445
*/
446
 
447
<name_none> : () -> ( nm ) = @{
448
    @nm = null ;
449
@} ;
450
 
451
<field_name> : ( fnm ) -> ( nm ) = @{
452
    if ( crt_field_name ) {
453
	@nm = string_printf ( "%s.%s", crt_field_name, @fnm ) ;
454
    } else {
455
	@nm = @fnm ;
456
    }
457
@} ;
458
 
459
<token_name> : ( tnm ) -> ( nm ) = @{
460
    @nm = token_name ( @tnm ) ;
461
@} ;
462
 
463
<make_id> : ( a, va, b, vb ) -> ( id ) = @{
464
    @id.iname = @a ;
465
    @id.ivers = @va ;
466
    @id.ename = @b ;
467
    @id.evers = @vb ;
468
@} ;
469
 
470
<id_anon> : () -> ( id ) = @{
471
    char *nm = string_printf ( "%s%d", HIDDEN_NAME, anon_no++ ) ;
472
    if ( crt_field_name ) {
473
	nm = string_printf ( "%s.%s", crt_field_name, nm ) ;
474
    }
475
    @id.iname = nm ;
476
    @id.ivers = no_version ;
477
    @id.ename = token_name ( nm ) ;
478
    @id.evers = no_version ;
479
@} ;
480
 
481
<version_none> : () -> ( v ) = @{
482
    @v = no_version ;
483
@} ;
484
 
485
<version_number> : ( n ) -> ( v ) = @{
486
    @v = atoi ( @n ) ;
487
@} ;
488
 
489
 
490
/*
491
    SUBSET NAMES
492
 
493
    These actions describe the subset names.
494
*/
495
 
496
<subset_none> : () -> ( s ) = @{ @s = "00" ; @} ;
497
<subset_first> : () -> ( s ) = @{ @s = "10" ; @} ;
498
<subset_second> : () -> ( s ) = @{ @s = "01" ; @} ;
499
<subset_both> : () -> ( s ) = @{ @s = "11" ; @} ;
500
<subset_next> : ( a ) -> ( s ) = @{ @s = string_concat ( @a, "G" ) ; @} ;
501
 
502
<api_name> : ( a ) -> ( s ) = @{
503
    @s = subset_name ( @a, null_str, null_str ) ;
504
@} ;
505
 
506
<file_name> : ( a, b ) -> ( s ) = @{
507
    @s = subset_name ( @a, @b, null_str ) ;
508
@} ;
509
 
510
<subset_name> : ( a, b, c ) -> ( s ) = @{
511
    if ( @b [0] == 0 ) @b = null ;
512
    @s = subset_name ( @a, @b, @c ) ;
513
@} ;
514
 
515
 
516
/*
517
    COMMAND KEYS
518
 
519
    These actions describe the command keys.
520
*/
521
 
522
<cmd_constant> : () -> ( c ) = @{ @c = OBJ_CONST ; @} ;
523
<cmd_exp> : () -> ( c ) = @{ @c = OBJ_EXP ; @} ;
524
<cmd_exp_extern> : () -> ( c ) = @{ @c = OBJ_EXTERN ; @} ;
525
<cmd_func> : () -> ( c ) = @{ @c = OBJ_FUNC ; @} ;
526
<cmd_func_extern> : () -> ( c ) = @{ @c = OBJ_EXTERN ; @} ;
527
<cmd_func_weak> : () -> ( c ) = @{ @c = OBJ_WEAK ; @} ;
528
<cmd_implement> : () -> ( c ) = @{ @c = OBJ_IMPLEMENT ; @} ;
529
<cmd_use> : () -> ( c ) = @{ @c = OBJ_USE ; @} ;
530
 
531
 
532
/*
533
    COMMANDS
534
 
535
    These actions describe the basic command constructs.
536
*/
537
 
538
<command_none> : () -> ( c ) = @{
539
    @c = null ;
540
@} ;
541
 
542
<command_join> : ( a, b ) -> ( c ) = @{
543
    @c = join_object ( @a, @b ) ;
544
@} ;
545
 
546
<begin_subset> : ( s ) -> ( c ) = @{
547
    object *p = make_subset ( @s ) ;
548
    info *i = p->u.u_info ;
549
    if ( i->subset ) {
550
	char *nm = subset_name ( i->api, i->file, null_str ) ;
551
	object *q = search_hash ( subsets, nm, no_version ) ;
552
	update_time ( p, q ) ;
553
    }
554
    @c = crt_object ;
555
    crt_object = p ;
556
@} ;
557
 
558
<end_subset> : ( a, b ) -> ( c ) = @{
559
    object *p = crt_object ;
560
    if ( p ) p->u.u_info->elements = @b ;
561
    @c = make_object ( null_str, OBJ_SET ) ;
562
    @c->u.u_obj = p ;
563
    crt_object = @a ;
564
@} ;
565
 
566
<include_subset> : ( cmd, s, key ) -> ( c ) = @{
567
    object *p = make_subset ( @s ) ;
568
    update_time ( crt_object, p ) ;
569
    @c = make_object ( @key, @cmd ) ;
570
    @c->u.u_obj = p ;
571
@} ;
572
 
573
 
574
/*
575
    VARIABLE COMMANDS
576
 
577
    These commands describe the variable assignment commands.
578
*/
579
 
580
<variable_string> : ( a, b ) -> () = @{
581
    set_string ( @a, @b ) ;
582
@} ;
583
 
584
<variable_plus> : ( a, b ) -> () = @{
585
    set_integer ( @a, atoi ( @b ) ) ;
586
@} ;
587
 
588
<variable_minus> : ( a, b ) -> () = @{
589
    set_integer ( @a, -atoi ( @b ) ) ;
590
@} ;
591
 
592
 
593
/*
594
    SPECIFICATION COMMANDS
595
 
596
    These actions describe the constructs for the various specification
597
    commands.
598
*/
599
 
600
<declare_base> : () -> ( c ) = @{
601
    @c = null ;
602
@} ;
603
 
604
<declare_comment> : ( s ) -> ( c ) = @{
605
    @c = make_object ( @s, OBJ_TEXT_INCL ) ;
606
@} ;
607
 
608
<declare_insert> : ( s ) -> ( c ) = @{
609
    @c = make_object ( @s, OBJ_TEXT_INCL ) ;
610
@} ;
611
 
612
<declare_build_insert> : ( s ) -> ( c ) = @{
613
    @c = make_object ( @s, OBJ_TEXT_SRC ) ;
614
@} ;
615
 
616
<declare_define> : ( id, p, def ) -> ( c ) = @{
617
    char *def ;
618
    object *p = make_exp ( @id.iname, @id.ivers, OBJ_DEFINE ) ;
619
    if ( @p ) {
620
	if ( *@p ) {
621
	    def = string_printf ( "( %s ) %s", @p, @def ) ;
622
	} else {
623
	    def = string_printf ( "() %s", @def ) ;
624
	}
625
    } else {
626
	def = string_printf ( " %s", @def ) ;
627
    }
628
    p->u.u_str = def ;
629
    @c = make_token ( @id.ename, @id.evers, p, OBJ_EXTERN ) ;
630
@} ;
631
 
7 7u83 632
<declare_defmin> : ( id, p, def ) -> ( c ) = @{
633
    char *def ;
634
    object *p = make_exp ( @id.iname, @id.ivers, OBJ_DEFMIN ) ;
635
    if ( @p ) {
636
	if ( *@p ) {
637
	    def = string_printf ( "( %s ) %s", @p, @def ) ;
638
	} else {
639
	    def = string_printf ( "() %s", @def ) ;
640
	}
641
    } else {
642
	def = string_printf ( " %s", @def ) ;
643
    }
644
    p->u.u_str = def ;
645
    @c = make_token ( @id.ename, @id.evers, p, OBJ_EXTERN ) ;
646
@} ;
647
 
648
 
2 7u83 649
<declare_enum> : ( tag, id, e ) -> ( c ) = @{
650
    type *t = make_type ( @id.iname, @id.ivers, @tag ) ;
651
    t->v.obj2 = @e ;
652
    @c = make_token ( @id.ename, @id.evers, t->u.obj, OBJ_TYPE ) ;
653
@} ;
654
 
655
<declare_enumerator> : ( id, s ) -> ( c ) = @{
656
    object *p = make_exp ( @id.iname, @id.ivers, OBJ_ENUMVAL ) ;
657
    p->u.u_str = @s ;
658
    @c = make_token ( @id.ename, @id.evers, p, OBJ_EXTERN ) ;
659
@} ;
660
 
661
<declare_exp> : ( cmd, id, t ) -> ( c ) = @{
662
    object *p = make_exp ( @id.iname, @id.ivers, @cmd ) ;
663
    p->u.u_type = check_type ( @t, @cmd ) ;
664
    @c = make_token ( @id.ename, @id.evers, p, @cmd ) ;
665
@} ;
666
 
667
<declare_field> : ( id, m, t ) -> ( c ) = @{
668
    type *t = check_type ( @t, OBJ_FIELD ) ;
669
    field *f = make_field ( @id.iname, @id.ivers, @m, t ) ;
670
    @c = make_token ( @id.ename, @id.evers, f->obj, OBJ_FIELD ) ;
671
@} ;
672
 
673
<declare_func> : ( cmd, id, t ) -> ( c ) = @{
674
    object *p = make_exp ( @id.iname, @id.ivers, @cmd ) ;
675
    p->u.u_type = check_type ( @t, OBJ_FUNC ) ;
676
    @c = make_token ( @id.ename, @id.evers, p, @cmd ) ;
677
@} ;
678
 
679
<declare_macro> : ( id, t ) -> ( c ) = @{
680
    object *p ;
681
    int cmd = OBJ_MACRO ;
682
    if ( @t->id != TYPE_PROC ) cmd = OBJ_EXP ;
683
    p = make_exp ( @id.iname, @id.ivers, cmd ) ;
684
    p->u.u_type = check_type ( @t, cmd ) ;
685
    @c = make_token ( @id.ename, @id.evers, p, cmd ) ;
686
@} ;
687
 
688
<declare_nat> : ( id ) -> ( c ) = @{
689
    object *p = make_exp ( @id.iname, @id.ivers, OBJ_NAT ) ;
690
    @c = make_token ( @id.ename, @id.evers, p, OBJ_NAT ) ;
691
@} ;
692
 
693
<declare_promote> : ( id, t ) -> ( c ) = @{
694
    type *t = make_type ( @id.iname, @id.ivers, TYPE_PROMOTE ) ;
695
    type *s = expand_type ( @t ) ;
696
    switch ( s->id ) {
697
	case TYPE_INT :
698
	case TYPE_SIGNED :
699
	case TYPE_UNSIGNED : {
700
	    break ;
701
	}
702
	default : {
703
	    error ( ERR_SERIOUS, "Non-integral promotion type" ) ;
704
	    break ;
705
	}
706
    }
707
    t->v.next = s ;
708
    @c = make_token ( @id.ename, @id.evers, t->u.obj, OBJ_EXTERN ) ;
709
@} ;
710
 
711
<declare_stmt> : ( id, t ) -> ( c ) = @{
712
    object *p = make_exp ( @id.iname, @id.ivers, OBJ_STATEMENT ) ;
713
    p->u.u_type = check_type ( @t, OBJ_STATEMENT ) ;
714
    @c = make_token ( @id.ename, @id.evers, p, OBJ_STATEMENT ) ;
715
@} ;
716
 
717
<declare_token> : ( id, s ) -> ( c ) = @{
718
    object *p = make_exp ( @id.iname, @id.ivers, OBJ_TOKEN ) ;
719
    p->u.u_str = @s ;
720
    @c = make_token ( @id.ename, @id.evers, p, OBJ_TOKEN ) ;
721
@} ;
722
 
723
<declare_type> : ( tag, id ) -> ( c ) = @{
724
    type *t = make_type ( @id.iname, @id.ivers, @tag ) ;
725
    @c = make_token ( @id.ename, @id.evers, t->u.obj, OBJ_TYPE ) ;
726
@} ;
727
 
728
<declare_typedef> : ( id, t ) -> ( c ) = @{
729
    type *t = make_type ( @id.iname, @id.ivers, TYPE_DEFINED ) ;
730
    t->v.next = check_type ( @t, OBJ_TYPE ) ;
731
    @c = make_token ( @id.ename, @id.evers, t->u.obj, OBJ_EXTERN ) ;
732
@} ;
733
 
734
 
735
/*
736
    FIELD SPECIFICATION COMMANDS
737
 
738
    These actions describe the member specification constructs.
739
*/
740
 
741
<begin_field> : ( id, tag ) -> ( t, c ) = @{
742
    @t = find_type ( @id.iname, any_version, @tag, 0 ) ;
743
    if ( @t == null ) {
744
	@t = make_type ( @id.iname, @id.ivers, @tag ) ;
745
	@c = make_token ( @id.ename, @id.evers, @t->u.obj, OBJ_TYPE ) ;
746
    } else {
747
	@c = null ;
748
    }
749
    @t = expand_type ( @t ) ;
750
    switch ( @t->id ) {
751
	case TYPE_STRUCT :
752
	case TYPE_UNION :
753
	case TYPE_STRUCT_TAG :
754
	case TYPE_UNION_TAG : {
755
	    break ;
756
	}
757
	default : {
758
	    error ( ERR_SERIOUS, "Illegal field type, '%s'", @id.iname ) ;
759
	    break ;
760
	}
761
    }
762
    crt_field_name = @t->u.obj->name ;
763
@} ;
764
 
765
<end_field> : ( t, a, b, e ) -> ( c ) = @{
766
    if ( @e ) {
767
	if ( @t->v.obj2 ) {
768
	    char *nm = crt_field_name ;
769
	    error ( ERR_SERIOUS, "Redefinition of type '%s'", nm ) ;
770
	}
771
	if ( @b == null ) {
772
	    error ( ERR_SERIOUS, "Empty struct/union definition" ) ;
773
	} else {
774
	    @t->v.obj2 = @b ;
775
	}
776
	if ( @a == null ) {
777
	    /* This is a hack, do properly later */
778
	    @c = make_object ( null_str, OBJ_TYPE ) ;
779
	    @c->u.u_type = @t ;
780
	    if ( streq ( @c->filename, @t->u.obj->filename ) ) {
781
		@t->state = 1 ;
782
	    } else {
783
		@t->state = 3 ;
784
	    }
785
	} else {
786
	    @c = @a ;
787
	}
788
    } else {
789
	@c = join_object ( @a, @b ) ;
790
    }
791
    crt_field_name = null ;
792
@} ;
793
 
794
 
795
/*
796
    CONDITIONAL COMPILATION COMMANDS
797
 
798
    These actions describe the conditional compilation constructs.
799
*/
800
 
801
<command_if> : ( s ) -> ( c ) = @{
802
    @c = make_object ( @s, OBJ_IF ) ;
803
    @c->u.u_num = CMD_IF ;
804
@} ;
805
 
806
<command_ifdef> : ( s ) -> ( c ) = @{
807
    @c = make_object ( @s, OBJ_IF ) ;
808
    @c->u.u_num = CMD_IFDEF ;
809
@} ;
810
 
811
<command_ifndef> : ( s ) -> ( c ) = @{
812
    @c = make_object ( @s, OBJ_IF ) ;
813
    @c->u.u_num = CMD_IFNDEF ;
814
@} ;
815
 
816
<command_endif> : ( i, s, a, b ) -> ( c ) = @{
817
    object *p, *q ;
818
    p = join_object ( @i, @a ) ;
819
    if ( @b ) {
820
	q = make_object ( @s, OBJ_IF ) ;
821
	q->u.u_num = CMD_ELSE ;
822
	p = join_object ( p, q ) ;
823
	p = join_object ( p, @b ) ;
824
    }
825
    q = make_object ( @s, OBJ_IF ) ;
826
    q->u.u_num = CMD_ENDIF ;
827
    @c = join_object ( p, q ) ;
828
@} ;
829
 
830
 
831
/*
832
    SYNTAX ERROR
833
 
834
    This action describes the error message which is printed if a parse
835
    error occurs.
836
*/
837
 
838
<syntax_error> : () -> () = @{
839
    error ( ERR_SERIOUS, "Syntax error" ) ;
840
@} ;
841
 
842
 
843
%trailer% @{
844
@}, @{
845
#endif
846
@} ;