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