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
7 7u83 3
 
2 7u83 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:-
7 7u83 12
 
2 7u83 13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
7 7u83 15
 
2 7u83 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;
7 7u83 19
 
2 7u83 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;
7 7u83 23
 
2 7u83 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 correspond to those generated by the calculus.  In addition,
37
    ID represents an identifier name and STRING represents a string.
38
*/
39
 
40
ID ;
41
STRING ;
42
 
43
ENTRY ;
44
KEY ;
45
MAP ;
46
MSG ;
47
NAME ;
48
PARAM ;
49
PROP ;
50
TYPE ;
51
USAGE ;
52
 
53
LIST-ENTRY ;
54
LIST-MAP ;
55
LIST-MSG ;
56
LIST-NAME ;
57
LIST-PARAM ;
58
LIST-PROP ;
59
 
60
 
61
%terminals%
62
 
63
/*
64
    TERMINALS
65
 
66
    These terminals give the various terminals identified by the lexical
67
    analysis routines.
68
*/
69
 
70
identifier : () -> ( :ID ) ;
71
string : () -> ( :STRING ) ;
72
 
73
alt-name ;
74
db-name ;
75
entries ;
76
key ;
77
keys ;
78
prefix ;
79
properties ;
80
rig ;
81
types ;
82
usage ;
83
 
84
comp-output ;
85
from-comp ;
86
from-db ;
87
 
88
arrow ;
89
colon ;
90
comma ;
91
equal ;
92
or ;
93
open-round ;
94
close-round ;
95
open-brace ;
96
close-brace ;
97
eof ;
98
!unknown ;
99
 
100
 
101
%productions%
102
 
103
 
104
/*
105
    MESSAGE LIST
106
 
107
    A message consists of a list of parameter names and strings.
108
*/
109
 
110
<find_param> : ( :ID, :LIST-PARAM ) -> ( :PARAM ) ;
111
<message_param> : ( :PARAM ) -> ( :MSG ) ;
112
<message_string> : ( :STRING ) -> ( :MSG ) ;
113
<empty_message_list> : () -> ( :LIST-MSG ) ;
114
<cons_message_list> : ( :MSG, :LIST-MSG ) -> ( :LIST-MSG ) ;
115
 
116
message-list : ( s : LIST-PARAM ) -> ( p : LIST-MSG ) = {
117
	a = identifier ;
118
	n = <find_param> ( a, s ) ;
119
	m = <message_param> ( n ) ;
120
	q = message-list ( s ) ;
121
	p = <cons_message_list> ( m, q ) ;
122
    ||
123
	a = string ;
124
	m = <message_string> ( a ) ;
125
	q = message-list ( s ) ;
126
	p = <cons_message_list> ( m, q ) ;
127
    ||
128
	p = <empty_message_list> ;
129
} ;
130
 
131
 
132
/*
133
    MAPPING LIST
134
 
135
    A mapping consists of a message list and an associated key.
136
*/
137
 
138
<find_key> : ( :ID ) -> ( :KEY ) ;
139
<make_map> : ( :KEY, :LIST-MSG, :LIST-MSG ) -> ( :MAP ) ;
140
<empty_map_list> : () -> ( :LIST-MAP ) ;
141
<cons_map_list> : ( :MAP, :LIST-MAP ) -> ( :LIST-MAP ) ;
142
 
143
map-list : ( s : LIST-PARAM ) -> ( p : LIST-MAP ) = {
144
	key ; open-round ; a = identifier ; close-round ;
145
	k = <find_key> ( a ) ;
146
	m1 = message-list ( s ) ;
147
	{
148
		or ; m2 = message-list ( s ) ;
149
	    ||
150
		m2 = m1 ;
151
	} ;
152
	n = <make_map> ( k, m1, m2 ) ;
153
	q = map-list ( s ) ;
154
	p = <cons_map_list> ( n, q ) ;
155
    ||
156
	p = <empty_map_list> ;
157
} ;
158
 
159
 
160
/*
161
    PROPERTIES LIST
162
 
163
    A properties list is a non-empty, comma-separated list of properties.
164
*/
165
 
166
<find_props> : ( :ID ) -> ( :PROP ) ;
167
<empty_props_list> : () -> ( :LIST-PROP ) ;
168
<cons_props_list> : ( :PROP, :LIST-PROP ) -> ( :LIST-PROP ) ;
169
 
170
props-list : () -> ( p : LIST-PROP ) = {
171
	a = identifier ;
172
	b = <find_props> ( a ) ;
173
	{
174
		comma ; q = props-list ;
175
	    ||	q = <empty_props_list> ;
176
	} ;
177
	p = <cons_props_list> ( b, q ) ;
178
} ;
179
 
180
 
181
/*
182
    SIGNATURE
183
 
184
    A message signature consists of an optional list of types and parameter
185
    names.
186
*/
187
 
188
<find_type> : ( :ID ) -> ( :TYPE ) ;
189
<make_param> : ( :TYPE, :ID ) -> ( :PARAM ) ;
190
<empty_param_list> : () -> ( :LIST-PARAM ) ;
191
<cons_param_list> : ( :PARAM, :LIST-PARAM ) -> ( :LIST-PARAM ) ;
192
 
193
param-list : () -> ( p : LIST-PARAM ) = {
194
	a = identifier ; t = <find_type> ( a ) ; colon ;
195
	b = identifier ;
196
	c = <make_param> ( t, b ) ;
197
	{
198
		comma ; q = param-list ;
199
	    ||	q = <empty_param_list> ;
200
	} ;
201
	p = <cons_param_list> ( c, q ) ;
202
} ;
203
 
204
signature : () -> ( p : LIST-PARAM ) = {
205
	p = param-list ;
206
    ||	p = <empty_param_list> ;
207
} ;
208
 
209
 
210
/*
211
    DATABASE ENTRY
212
 
213
    This rule describes the main component of the input, an individual
214
    database entry.
215
*/
216
 
217
<null_identifier> : () -> ( :ID ) ;
218
<find_usage> : ( :ID ) -> ( :USAGE ) ;
219
<null_usage> : () -> ( :USAGE ) ;
220
<make_entry> : ( :ID, :ID, :LIST-PARAM, :USAGE, :USAGE, :LIST-PROP,
221
		 :LIST-MAP ) -> ( :ENTRY ) ;
222
 
223
entry : () -> ( e : ENTRY ) = {
224
	a = identifier ; open-round ; s = signature ; close-round ;
225
	open-brace ;
226
	{
227
		alt-name ; colon ; b = identifier ;
228
	    ||	b = <null_identifier> ;
229
	} ;
230
	{
231
		usage ; colon ; c = identifier ;
232
		u = <find_usage> ( c ) ;
233
		{
234
			or ; d = identifier ;
235
			w = <find_usage> ( d ) ;
236
		    ||
237
			w = u ;
238
		} ;
239
		v = w ;
240
	    ||
241
		u = <null_usage> ;
242
		v = <null_usage> ;
243
	} ;
244
	{
245
		properties ; colon ;
246
		{
247
			q = props-list ;
248
		    ||	q = <empty_props_list> ;
249
		} ;
250
		p = q ;
251
	    ||
252
		p = <empty_props_list> ;
253
	} ;
254
	m = map-list ( s ) ;
255
	close-brace ;
256
	e = <make_entry> ( a, b, s, u, v, p, m ) ;
257
} ;
258
 
259
 
260
/*
261
    ENTRIES LIST
262
 
263
    The main component of the top level unit is a list of entries.
264
*/
265
 
266
<empty_entry_list> : () -> ( :LIST-ENTRY ) ;
267
<cons_entry_list> : ( :ENTRY, :LIST-ENTRY ) -> ( :LIST-ENTRY ) ;
268
 
269
entries-list : () -> ( p : LIST-ENTRY ) = {
270
	a = entry ;
271
	q = entries-list ;
272
	p = <cons_entry_list> ( a, q ) ;
273
    ||
274
	p = <empty_entry_list> ;
275
} ;
276
 
277
 
278
/*
279
    IDENTIFIER LIST
280
 
281
    The various lists of types, properties etc. in the top level unit are
282
    just simple lists of identifiers.
283
*/
284
 
285
<empty_name_list> : () -> ( :LIST-NAME ) ;
286
<make_name> : ( :ID ) -> ( :NAME ) ;
287
<make_name_aux> : ( :ID ) -> ( :NAME ) ;
288
<cons_name_list> : ( :NAME, :LIST-NAME ) -> ( :LIST-NAME ) ;
289
<join_name_list> : ( :NAME, :LIST-NAME ) -> ( :LIST-NAME ) ;
290
 
291
name-seq : () -> ( p : LIST-NAME, q : LIST-NAME, r : LIST-NAME ) = {
292
	a = identifier ;
293
	n = <make_name> ( a ) ;
294
	{
295
		equal ; b = identifier ;
296
		m = <make_name_aux> ( b ) ;
297
		{
298
			or ; c = identifier ;
299
			k1 = <make_name_aux> ( c ) ;
300
		    ||
301
			k1 = m ;
302
		} ;
303
		k = k1 ;
304
	    ||
305
		m = n ;
306
		k = n ;
307
	} ;
308
	{
309
		comma ; ( p1, q1, r1 ) = name-seq ;
310
	    ||
311
		p1 = <empty_name_list> ;
312
		q1 = <empty_name_list> ;
313
		r1 = <empty_name_list> ;
314
	} ;
315
	p = <cons_name_list> ( n, p1 ) ;
316
	q = <join_name_list> ( m, q1 ) ;
317
	r = <join_name_list> ( k, r1 ) ;
318
} ;
319
 
320
name-list : () -> ( p : LIST-NAME, q : LIST-NAME, r : LIST-NAME ) = {
321
	( p, q, r ) = name-seq ;
322
    ||
323
	p = <empty_name_list> ;
324
	q = <empty_name_list> ;
325
	r = <empty_name_list> ;
326
} ;
327
 
328
 
329
/*
330
    COMPLETE UNIT
331
 
332
    The input consists of various standard information plus lists of
333
    types, properties, keys, usages and entries.
334
*/
335
 
336
<set_db> : ( :ID, :ID ) -> () ;
337
<set_rig> : ( :ID ) -> () ;
338
<set_prefix> : ( :ID, :ID, :ID ) -> () ;
339
<set_types> : ( :LIST-NAME, :LIST-NAME, :LIST-NAME ) -> () ;
340
<set_props> : ( :LIST-NAME, :LIST-NAME, :LIST-NAME ) -> () ;
341
<set_keys> : ( :LIST-NAME, :LIST-NAME, :LIST-NAME ) -> () ;
342
<set_usages> : ( :LIST-NAME, :LIST-NAME, :LIST-NAME ) -> () ;
343
<set_entries> : ( :LIST-ENTRY ) -> () ;
344
<syntax_error> : () -> () ;
345
 
346
unit : () -> () = {
347
	/* Database name */
348
	{
349
		db-name ; colon ; d = identifier ;
350
		{
351
			or ; e = identifier ;
352
		    ||	e = d ;
353
		} ;
354
		<set_db> ( d, e ) ;
355
	    ||
356
		$ ;
357
	} ;
358
	{
359
		rig ; colon ; r = identifier ;
360
		<set_rig> ( r ) ;
361
	    ||
362
		$ ;
363
	} ;
364
 
365
	/* Standard prefixes */
366
	{
367
		prefix ; colon ;
368
		{
369
			comp-output ; arrow ; q1 = identifier ;
370
		    ||	q1 = <null_identifier> ;
371
		} ;
372
		{
373
			from-comp ; arrow ; q2 = identifier ;
374
		    ||	q2 = <null_identifier> ;
375
		} ;
376
		{
377
			from-db ; arrow ; q3 = identifier ;
378
		    ||	q3 = <null_identifier> ;
379
		} ;
380
		<set_prefix> ( q1, q2, q3 ) ;
381
	    ||
382
		q1 = <null_identifier> ;
383
		q2 = <null_identifier> ;
384
		q3 = <null_identifier> ;
385
		<set_prefix> ( q1, q2, q3 ) ;
386
	} ;
387
 
388
	/* List of types */
389
	{
390
		types ; colon ; ( t1, t2, t3 ) = name-list ;
391
	    ||
392
		t1 = <empty_name_list> ;
393
		t2 = <empty_name_list> ;
394
		t3 = <empty_name_list> ;
395
	} ;
396
	<set_types> ( t1, t2, t3 ) ;
397
 
398
	/* List of properties */
399
	{
400
		properties ; colon ; ( p1, p2, p3 ) = name-list ;
401
	    ||
402
		p1 = <empty_name_list> ;
403
		p2 = <empty_name_list> ;
404
		p3 = <empty_name_list> ;
405
	} ;
406
	<set_props> ( p1, p2, p3 ) ;
407
 
408
	/* List of keys */
409
	{
410
		keys ; colon ; ( k1, k2, k3 ) = name-list ;
411
	    ||
412
		k1 = <empty_name_list> ;
413
		k2 = <empty_name_list> ;
414
		k3 = <empty_name_list> ;
415
	} ;
416
	<set_keys> ( k1, k2, k3 ) ;
417
 
418
	/* List of usages */
419
	{
420
		usage ; colon ; ( u1, u2, u3 ) = name-list ;
421
	    ||
422
		u1 = <empty_name_list> ;
423
		u2 = <empty_name_list> ;
424
		u3 = <empty_name_list> ;
425
	} ;
426
	<set_usages> ( u1, u2, u3 ) ;
427
 
428
	/* List of entries */
429
	{
430
		entries ; colon ; e = entries-list ;
431
	    ||	e = <empty_entry_list> ;
432
	} ;
433
	<set_entries> ( e ) ;
434
	eof ;
435
    ##
436
	<syntax_error> ;
437
}  ;
438
 
439
%entry% unit ;