Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | 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 the grammar is given by unit.
13
*/
14
 
15
unit -> read_errors ;
16
 
17
 
18
/*
19
    TYPE MAPPINGS
20
 
21
    These mappings give the correspondences between syntax types and
22
    C types.
23
*/
24
 
25
ID -> string ;
26
STRING -> string ;
27
ENTRY -> ENTRY ;
28
KEY -> KEY ;
29
MAP -> MAP ;
30
MSG -> MESSAGE ;
31
NAME -> NAME ;
32
PARAM -> PARAM ;
33
PROP -> PROPERTY ;
34
TYPE -> TYPE ;
35
USAGE -> USAGE ;
36
LIST-ENTRY -> LIST_ENTRY ;
37
LIST-MAP -> LIST_MAP ;
38
LIST-MSG -> LIST_MESSAGE ;
39
LIST-NAME -> LIST_NAME ;
40
LIST-PARAM -> LIST_PARAM ;
41
LIST-PROP -> LIST_PROPERTY ;
42
 
43
 
44
%header% @{
45
/*
46
    		 Crown Copyright (c) 1997
47
 
48
    This TenDRA(r) Computer Program is subject to Copyright
49
    owned by the United Kingdom Secretary of State for Defence
50
    acting through the Defence Evaluation and Research Agency
51
    (DERA).  It is made available to Recipients with a
52
    royalty-free licence for its use, reproduction, transfer
53
    to other parties and amendment for any purpose not excluding
54
    product development provided that any such use et cetera
55
    shall be deemed to be acceptance of the following conditions:-
56
 
57
        (1) Its Recipients shall ensure that this Notice is
58
        reproduced upon any copies or amended versions of it;
59
 
60
        (2) Any amended version of it shall be clearly marked to
61
        show both the nature of and the organisation responsible
62
        for the relevant amendment or amendments;
63
 
64
        (3) Its onward transfer from a recipient to another
65
        party shall be deemed to be that party's acceptance of
66
        these conditions;
67
 
68
        (4) DERA gives no warranty or assurance as to its
69
        quality or suitability for any purpose and DERA accepts
70
        no liability whatsoever in relation to any use to which
71
        it may be put.
72
*/
73
 
74
 
75
#include "config.h"
76
#include "errors.h"
77
#include "entry_ops.h"
78
#include "map_ops.h"
79
#include "msg_ops.h"
80
#include "name_ops.h"
81
#include "param_ops.h"
82
#include "error.h"
83
#include "lex.h"
84
#include "process.h"
85
#include "syntax.h"
86
#include "xalloc.h"
87
 
88
 
89
/*
90
    PARSER TYPES
91
 
92
    These types give the implementation of the types used in the syntax.
93
*/
94
 
95
typedef LIST ( ENTRY ) LIST_ENTRY ;
96
typedef LIST ( MAP ) LIST_MAP ;
97
typedef LIST ( MESSAGE ) LIST_MESSAGE ;
98
typedef LIST ( NAME ) LIST_NAME ;
99
typedef LIST ( PARAM ) LIST_PARAM ;
100
typedef LIST ( PROPERTY ) LIST_PROPERTY ;
101
 
102
 
103
/*
104
    COUNTER VARIABLE
105
 
106
    This variable is used to keep count of the position in a name or
107
    parameter list.
108
*/
109
 
110
static int counter = 0 ;
111
 
112
 
113
/*
114
    FIND A NAME
115
 
116
    This routine searches the name list p for an identifier matching id.
117
    The null name is returned if no matching name is found.
118
*/
119
 
120
static NAME find_name
121
    PROTO_N ( ( p, id ) )
122
    PROTO_T ( LIST ( NAME ) p X string id )
123
{
124
    while ( !IS_NULL_list ( p ) ) {
125
	NAME a = DEREF_name ( HEAD_list ( p ) ) ;
126
	string nm = DEREF_string ( name_id ( a ) ) ;
127
	if ( streq ( nm, id ) ) return ( a ) ;
128
	p = TAIL_list ( p ) ;
129
    }
130
    return ( NULL_name ) ;
131
}
132
 
133
 
134
/*
135
    FIND A PARAMETER
136
 
137
    This routine searches the parameter list p for an identifier matching
138
    id.  The null parameter is returned if no matching parameter is found.
139
*/
140
 
141
static PARAM find_param
142
    PROTO_N ( ( p, id ) )
143
    PROTO_T ( LIST ( PARAM ) p X string id )
144
{
145
    while ( !IS_NULL_list ( p ) ) {
146
	PARAM a = DEREF_param ( HEAD_list ( p ) ) ;
147
	string nm = DEREF_string ( param_name ( a ) ) ;
148
	if ( streq ( nm, id ) ) return ( a ) ;
149
	p = TAIL_list ( p ) ;
150
    }
151
    return ( NULL_param ) ;
152
}
153
 
154
 
155
/*
156
    COMPILATION MODE
157
 
158
    We allow unreached code and switch off the variable analysis in the
159
    automatically generated sections.
160
*/
161
 
162
#if FS_TENDRA
163
#pragma TenDRA begin
164
#pragma TenDRA variable analysis off
165
#ifndef OLD_PRODUCER
166
#pragma TenDRA unreachable code allow
167
#endif
168
#endif
169
 
170
 
171
@}, @{
172
/*
173
    		 Crown Copyright (c) 1997
174
 
175
    This TenDRA(r) Computer Program is subject to Copyright
176
    owned by the United Kingdom Secretary of State for Defence
177
    acting through the Defence Evaluation and Research Agency
178
    (DERA).  It is made available to Recipients with a
179
    royalty-free licence for its use, reproduction, transfer
180
    to other parties and amendment for any purpose not excluding
181
    product development provided that any such use et cetera
182
    shall be deemed to be acceptance of the following conditions:-
183
 
184
        (1) Its Recipients shall ensure that this Notice is
185
        reproduced upon any copies or amended versions of it;
186
 
187
        (2) Any amended version of it shall be clearly marked to
188
        show both the nature of and the organisation responsible
189
        for the relevant amendment or amendments;
190
 
191
        (3) Its onward transfer from a recipient to another
192
        party shall be deemed to be that party's acceptance of
193
        these conditions;
194
 
195
        (4) DERA gives no warranty or assurance as to its
196
        quality or suitability for any purpose and DERA accepts
197
        no liability whatsoever in relation to any use to which
198
        it may be put.
199
*/
200
 
201
 
202
#ifndef SYNTAX_INCLUDED
203
#define SYNTAX_INCLUDED
204
 
205
@};
206
 
207
 
208
%terminals%
209
 
210
 
211
/*
212
    IDENTIFIER TERMINAL
213
 
214
    This action gives the terminal for identifiers.  The identifier text
215
    is built up in token_buff by the lexical routines.
216
*/
217
 
218
identifier : () -> ( i : ID ) = @{
219
    @i = xstrcpy ( token_buff ) ;
220
@} ;
221
 
222
 
223
/*
224
    STRING TERMINAL
225
 
226
    This action gives the terminal for strings.  The string text is built
227
    up in token_buff by the lexical routines.
228
*/
229
 
230
string : () -> ( s : STRING ) = @{
231
    @s = xstrcpy ( token_buff ) ;
232
@} ;
233
 
234
 
235
%actions%
236
 
237
 
238
/*
239
    NULL IDENTIFIER
240
 
241
    This action describes the null identifier.
242
*/
243
 
244
<null_identifier> : () -> ( id : ID ) = @{
245
    @id = NULL ;
246
@} ;
247
 
248
 
249
/*
250
    LIST CONSTRUCTION ACTIONS
251
 
252
    These actions give the empty lists and cons operations for the various
253
    list types used in the grammar.  They basically map directly onto the
254
    various calculus constructs, except that checks are made for duplicate
255
    entries in some cases.
256
*/
257
 
258
<empty_message_list> : () -> ( p : LIST-MSG ) = @{
259
    @p = NULL_list ( MESSAGE ) ;
260
@} ;
261
 
262
<cons_message_list> : ( a : MSG, q : LIST-MSG ) -> ( p : LIST-MSG ) = @{
263
    CONS_msg ( @a, @q, @p ) ;
264
@} ;
265
 
266
<empty_map_list> : () -> ( p : LIST-MAP ) = @{
267
    @p = NULL_list ( MAP ) ;
268
@} ;
269
 
270
<cons_map_list> : ( a : MAP, q : LIST-MAP ) -> ( p : LIST-MAP ) = @{
271
    CONS_map ( @a, @q, @p ) ;
272
@} ;
273
 
274
<empty_props_list> : () -> ( p : LIST-PROP ) = @{
275
    @p = NULL_list ( PROPERTY ) ;
276
@} ;
277
 
278
<cons_props_list> : ( a : PROP, q : LIST-PROP ) -> ( p : LIST-PROP ) = @{
279
    CONS_name ( @a, @q, @p ) ;
280
@} ;
281
 
282
<empty_param_list> : () -> ( p : LIST-PARAM ) = @{
283
    @p = NULL_list ( PARAM ) ;
284
@} ;
285
 
286
<cons_param_list> : ( a : PARAM, q : LIST-PARAM ) -> ( p : LIST-PARAM ) = @{
287
    string id = DEREF_string ( param_name ( @a ) ) ;
288
    PARAM b = find_param ( @q, id ) ;
289
    if ( !IS_NULL_param ( b ) ) {
290
	error ( ERROR_SERIOUS, "Parameter '%s' defined twice", id ) ;
291
    }
292
    CONS_param ( @a, @q, @p ) ;
293
@} ;
294
 
295
<empty_entry_list> : () -> ( p : LIST-ENTRY ) = @{
296
    @p = NULL_list ( ENTRY ) ;
297
@} ;
298
 
299
<cons_entry_list> : ( a : ENTRY, q : LIST-ENTRY ) -> ( p : LIST-ENTRY ) = @{
300
    CONS_entry ( @a, @q, @p ) ;
301
@} ;
302
 
303
<empty_name_list> : () -> ( p : LIST-NAME ) = @{
304
    @p = NULL_list ( NAME ) ;
305
@} ;
306
 
307
<cons_name_list> : ( a : NAME, q : LIST-NAME ) -> ( p : LIST-NAME ) = @{
308
    string id = DEREF_string ( name_id ( @a ) ) ;
309
    NAME b = find_name ( @q, id ) ;
310
    if ( !IS_NULL_name ( b ) ) {
311
	error ( ERROR_SERIOUS, "Name '%s' given twice in list", id ) ;
312
    }
313
    CONS_name ( @a, @q, @p ) ;
314
@} ;
315
 
316
<join_name_list> : ( a : NAME, q : LIST-NAME ) -> ( p : LIST-NAME ) = @{
317
    CONS_name ( @a, @q, @p ) ;
318
@} ;
319
 
320
 
321
/*
322
    NAME LOOK-UP ACTIONS
323
 
324
    These actions are used to look up an identifier in various circumstances.
325
    They map directly onto the routines find_name and find_param defined
326
    above.
327
*/
328
 
329
<find_key> : ( id : ID ) -> ( k : KEY ) = @{
330
    NAME n = find_name ( all_keys, @id ) ;
331
    if ( IS_NULL_name ( n ) ) {
332
	error ( ERROR_SERIOUS, "Key '%s' not defined", @id ) ;
333
    }
334
    @k = n ;
335
@} ;
336
 
337
<find_props> : ( id : ID ) -> ( p : PROP ) = @{
338
    NAME n = find_name ( all_props, @id ) ;
339
    if ( IS_NULL_name ( n ) ) {
340
	error ( ERROR_SERIOUS, "Property '%s' not defined", @id ) ;
341
	MAKE_name_basic ( @id, 0, n ) ;
342
    }
343
    @p = n ;
344
@} ;
345
 
346
<find_type> : ( id : ID ) -> ( t : TYPE ) = @{
347
    NAME n = find_name ( all_types, @id ) ;
348
    if ( IS_NULL_name ( n ) ) {
349
	error ( ERROR_SERIOUS, "Type '%s' not defined", @id ) ;
350
	MAKE_name_basic ( @id, 0, n ) ;
351
    }
352
    @t = n ;
353
@} ;
354
 
355
<find_usage> : ( id : ID ) -> ( u : USAGE ) = @{
356
    NAME n = find_name ( all_usages, @id ) ;
357
    if ( IS_NULL_name ( n ) ) {
358
	error ( ERROR_SERIOUS, "Usage '%s' not defined", @id ) ;
359
	MAKE_name_basic ( @id, 0, n ) ;
360
    }
361
    @u = n ;
362
@} ;
363
 
364
<find_param> : ( id : ID, s : LIST-PARAM ) -> ( p : PARAM ) = @{
365
    PARAM a = find_param ( @s, @id ) ;
366
    if ( IS_NULL_param ( a ) ) {
367
	error ( ERROR_SERIOUS, "Parameter '%s' not defined", @id ) ;
368
    }
369
    @p = a ;
370
@} ;
371
 
372
 
373
/*
374
    OBJECT CONSTRUCTION ACTIONS
375
 
376
    These actions are used to construct various objects from their
377
    components.  They map directly onto the calculus construction routines.
378
*/
379
 
380
<null_usage> : () -> ( u : USAGE ) = @{
381
    @u = NULL_name ;
382
@} ;
383
 
384
<make_name> : ( id : ID ) -> ( n : NAME ) = @{
385
    MAKE_name_basic ( @id, counter, @n ) ;
386
    counter++ ;
387
@} ;
388
 
389
<make_name_aux> : ( id : ID ) -> ( n : NAME ) = @{
390
    MAKE_name_basic ( @id, 0, @n ) ;
391
@} ;
392
 
393
<make_param> : ( t : TYPE, id : ID ) -> ( p : PARAM ) = @{
394
    MAKE_param_basic ( @t, @id, counter, @p ) ;
395
    counter++ ;
396
@} ;
397
 
398
<message_param> : ( p : PARAM ) -> ( m : MSG ) = @{
399
    if ( !IS_NULL_param ( @p ) ) {
400
	MAKE_msg_param ( @p, @m ) ;
401
    } else {
402
	MAKE_msg_text ( "<error>", @m ) ;
403
    }
404
@} ;
405
 
406
<message_string> : ( s : STRING ) -> ( m : MSG ) = @{
407
    MAKE_msg_text ( @s, @m ) ;
408
@} ;
409
 
410
<make_map> : ( k : KEY, p : LIST-MSG, q : LIST-MSG ) -> ( m : MAP ) = @{
411
    MAKE_map_basic  ( @k, @p, @q, @m ) ;
412
@} ;
413
 
414
<make_entry> : ( a : ID, b : ID, s : LIST-PARAM, u : USAGE, v : USAGE,
415
		 p : LIST-PROP, m : LIST-MAP ) -> ( e : ENTRY ) = @{
416
    MAKE_entry_basic ( @a, @b, @s, @u, @v, @p, @m, @e ) ;
417
    counter = 0 ;
418
@} ;
419
 
420
 
421
/*
422
    GLOBAL ASSIGNMENT ACTIONS
423
 
424
    These actions assign the lists and strings constructed by the parser
425
    to the various global variables designed to hold this information.
426
*/
427
 
428
<set_db> : ( r : ID, s : ID ) -> () = @{
429
    db_name = @r ;
430
    db_name_alt = @s ;
431
@} ;
432
 
433
<set_rig> : ( r : ID ) -> () = @{
434
    rig_name = @r ;
435
@} ;
436
 
437
<set_prefix> : ( a : ID, b : ID, c : ID ) -> () = @{
438
    if ( @a ) rig_comp_output = @a ;
439
    if ( @b ) rig_from_comp = @b ;
440
    if ( @c ) rig_from_db = @c ;
441
@} ;
442
 
443
<set_types> : ( p : LIST-NAME, q : LIST-NAME, r : LIST-NAME ) -> () = @{
444
    all_types = @p ;
445
    all_types_aux = @q ;
446
    all_types_alt = @r ;
447
    counter = 0 ;
448
@} ;
449
 
450
<set_props> : ( p : LIST-NAME, q : LIST-NAME, r : LIST-NAME ) -> () = @{
451
    all_props = @p ;
452
    all_props_aux = @q ;
453
    all_props_alt = @r ;
454
    counter = 0 ;
455
@} ;
456
 
457
<set_keys> : ( p : LIST-NAME, q : LIST-NAME, r : LIST-NAME ) -> () = @{
458
    all_keys = @p ;
459
    all_keys_aux = @q ;
460
    all_keys_alt = @r ;
461
    counter = 0 ;
462
@} ;
463
 
464
<set_usages> : ( p : LIST-NAME, q : LIST-NAME, r : LIST-NAME ) -> () = @{
465
    all_usages = @p ;
466
    all_usages_aux = @q ;
467
    all_usages_alt = @r ;
468
    counter = 0 ;
469
@} ;
470
 
471
<set_entries> : ( p : LIST-ENTRY ) -> () = @{
472
    all_entries = @p ;
473
    counter = 0 ;
474
@} ;
475
 
476
 
477
/*
478
    SYNTAX ERROR ACTION
479
 
480
    This action is used to signal a syntax error.
481
*/
482
 
483
<syntax_error> : () -> () = @{
484
    error ( ERROR_SERIOUS, "Syntax error" ) ;
485
@} ;
486
 
487
 
488
%trailer% @{
489
@}, @{
490
#endif
491
@} ;