Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251
WebSVN – tendra.SVN – Diff – /branches/tendra5/src/utilities/calculus/lex.c – Rev 5 and 6

Subversion Repositories tendra.SVN

Rev

Rev 5 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5 Rev 6
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
    
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
36
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
37
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
38
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
39
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
40
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
41
    shall be deemed to be acceptance of the following conditions:-
12
    
42
 
13
        (1) Its Recipients shall ensure that this Notice is
43
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
44
        reproduced upon any copies or amended versions of it;
15
    
45
 
16
        (2) Any amended version of it shall be clearly marked to
46
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
47
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
48
        for the relevant amendment or amendments;
19
    
49
 
20
        (3) Its onward transfer from a recipient to another
50
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
51
        party shall be deemed to be that party's acceptance of
22
        these conditions;
52
        these conditions;
23
    
53
 
24
        (4) DERA gives no warranty or assurance as to its
54
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
55
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
56
        no liability whatsoever in relation to any use to which
27
        it may be put.
57
        it may be put.
28
*/
58
*/
Line 33... Line 63...
33
#include "error.h"
63
#include "error.h"
34
#include "lex.h"
64
#include "lex.h"
35
#include "syntax.h"
65
#include "syntax.h"
36
#include "xalloc.h"
66
#include "xalloc.h"
37
 
67
 
147
 
175
 
148
 
176
 
149
/*
177
/*
150
    GET THE NEXT CHARACTER
178
 * GET THE NEXT CHARACTER
-
 
179
 *
-
 
180
 * This routine reads the next character, either from the pending buffer
-
 
181
 * or from the input file.
-
 
182
 */
151
 
183
 
152
    This routine reads the next character, either from the pending buffer
-
 
153
    or from the input file.
-
 
154
*/
-
 
155
 
-
 
156
static int read_char
184
static int
157
    PROTO_Z ()
185
read_char(void)
158
{
186
{
159
    int c ;
187
    int c;
160
    if ( pending != pending_buff ) {
188
    if (pending != pending_buff) {
161
	c = *( pending-- ) ;
189
	c = *(pending--);
162
    } else {
190
    } else {
163
	c = fgetc ( lex_input ) ;
191
	c = fgetc(lex_input);
164
	if ( c == '\n' ) crt_line_no++ ;
192
	if (c == '\n')crt_line_no++;
165
	if ( c == EOF ) return ( LEX_EOF ) ;
193
	if (c == EOF) return(LEX_EOF);
166
	c &= 0xff ;
194
	c &= 0xff;
167
    }
195
    }
168
    return ( c ) ;
196
    return(c);
169
}
197
}
170
 
198
 
171
 
199
 
172
/*
200
/*
173
    TOKEN BUFFER
201
 * TOKEN BUFFER
174
 
202
 *
175
    This buffer is used by read_token to hold the values of identifiers
203
 * This buffer is used by read_token to hold the values of identifiers
176
    and strings.  The variable token_value is also used to hold the
204
 * and strings.  The variable token_value is also used to hold the
177
    values of numbers.
205
 * values of numbers.
178
*/
206
 */
179
 
207
 
180
char token_buff [2000] ;
208
char token_buff[2000];
181
static char *token_end = token_buff + sizeof ( token_buff ) ;
209
static char *token_end = token_buff + sizeof(token_buff);
182
char *first_comment = NULL ;
210
char *first_comment = NULL;
183
number token_value ;
211
number token_value;
184
 
212
 
185
 
213
 
186
/*
214
/*
187
    READ AN IDENTIFIER
215
 * READ AN IDENTIFIER
188
 
216
 *
189
    This routine reads an identifier beginning with a, returning the
217
 * This routine reads an identifier beginning with a, returning the
190
    corresponding lexical token.  Keywords are dealt with locally.
218
 * corresponding lexical token.  Keywords are dealt with locally.
191
*/
219
 */
192
 
220
 
193
static int read_identifier
221
static int
194
    PROTO_N ( ( a ) )
-
 
195
    PROTO_T ( int a )
222
read_identifier(int a)
196
{
223
{
197
    int c = a, cl ;
224
    int c = a, cl;
198
    char *t = token_buff ;
225
    char *t = token_buff;
199
    do {
226
    do {
200
	*( t++ ) = ( char ) c ;
227
	*(t++) = (char)c;
-
 
228
	if (t == token_end) {
201
	if ( t == token_end ) error ( ERROR_FATAL, "Buffer overflow" ) ;
229
		error(ERROR_FATAL, "Buffer overflow");
-
 
230
	}
202
	c = read_char () ;
231
	c = read_char();
203
	cl = lookup_char ( c ) ;
232
	cl = lookup_char(c);
204
    } while ( is_alphanum ( cl ) ) ;
233
    } while (is_alphanum(cl));
205
    *t = 0 ;
234
    *t = 0;
206
    unread_char ( c ) ;
235
    unread_char(c);
207
 
236
 
208
    /* Check for keywords */
237
    /* Check for keywords */
209
    t = token_buff ;
238
    t = token_buff;
210
#define MAKE_KEYWORD( A, B )\
239
#define MAKE_KEYWORD(A, B)\
211
    if ( streq ( t, ( A ) ) ) return ( B ) ;
240
    if (streq(t,(A))) return(B);
212
#include "keyword.h"
241
#include "keyword.h"
213
    return ( lex_identifier ) ;
242
    return(lex_identifier);
214
}
243
}
215
 
244
 
216
 
245
 
217
/*
246
/*
218
    READ A NUMBER
247
 * READ A NUMBER
219
 
-
 
220
    This routine reads a number beginning with a, returning the
-
 
221
    corresponding lexical token.  The actual value of the number is built
-
 
222
    up in token_value.
-
 
223
*/
-
 
224
 
-
 
225
static int read_number
-
 
226
    PROTO_N ( ( a ) )
-
 
227
    PROTO_T ( int a )
-
 
228
{
-
 
229
    int c = a, cl ;
-
 
230
    number n = 0 ;
-
 
231
    do {
-
 
232
	n = 10 * n + ( number ) ( c - '0' ) ;
-
 
233
	c = read_char () ;
-
 
234
	cl = lookup_char ( c ) ;
-
 
235
    } while ( is_digit ( cl ) ) ;
-
 
236
    unread_char ( c ) ;
-
 
237
    token_value = n ;
-
 
238
    return ( lex_number ) ;
-
 
239
}
-
 
240
 
-
 
241
 
-
 
242
/*
248
 *
243
    READ A HEXADECIMAL NUMBER
-
 
244
 
-
 
245
    This routine reads a hexadecimal number beginning with a, returning the
249
 * This routine reads a number beginning with a, returning the
246
    corresponding lexical token.  The actual value of the number is built
250
 * corresponding lexical token.  The actual value of the number is built
247
    up in token_value.
251
 * up in token_value.
248
*/
252
 */
249
 
253
 
250
static int read_hex
254
static int
251
    PROTO_N ( ( a ) )
-
 
252
    PROTO_T ( int a )
255
read_number(int a)
253
{
256
{
254
    int c = a, cl ;
257
    int c = a, cl;
255
    number n = 0 ;
258
    number n = 0;
256
    do {
259
    do {
257
	number d ;
-
 
258
	if ( c >= '0' && c <= '9' ) {
-
 
259
	    d = ( number  ) ( c - '0' ) ;
260
	n = 10 * n + (number)(c - '0');
260
	} else if ( c >= 'A' && c <= 'Z' ) {
-
 
261
	    d = ( number ) ( c - 'A' ) + 10 ;
-
 
262
	} else {
-
 
263
	    d = ( number ) ( c - 'a' ) + 10 ;
-
 
264
	}
-
 
265
	n = 16 * n + d ;
-
 
266
	c = read_char () ;
261
	c = read_char();
267
	cl = lookup_char ( c ) ;
262
	cl = lookup_char(c);
268
    } while ( is_hexdigit ( cl ) ) ;
263
    } while (is_digit(cl));
269
    unread_char ( c ) ;
264
    unread_char(c);
270
    token_value = n ;
265
    token_value = n;
271
    return ( lex_number ) ;
266
    return(lex_number);
272
}
267
}
273
 
268
 
274
 
269
 
275
/*
270
/*
276
    READ A STRING
271
 * READ A HEXADECIMAL NUMBER
277
 
272
 *
278
    This routine reads a string.  It is entered after the initial
273
 * This routine reads a hexadecimal number beginning with a, returning the
279
    quote has been read.  Note that there are no escape sequences.
274
 * corresponding lexical token.  The actual value of the number is built
-
 
275
 * up in token_value.
280
*/
276
 */
281
 
277
 
282
static int read_string
278
static int
283
    PROTO_Z ()
279
read_hex(int a)
284
{
280
{
285
    int c ;
281
    int c = a, cl;
286
    char *t = token_buff ;
282
    number n = 0;
-
 
283
    do {
-
 
284
	number d;
287
    while ( c = read_char (), c != '"' ) {
285
	if (c >= '0' && c <= '9') {
-
 
286
	    d = (number )(c - '0');
288
	if ( c == '\n' || c == LEX_EOF ) {
287
	} else if (c >= 'A' && c <= 'Z') {
289
	    error ( ERROR_SERIOUS, "Unexpected end of string" ) ;
288
	    d = (number)(c - 'A') + 10;
290
	    break ;
289
	} else {
-
 
290
	    d = (number)(c - 'a') + 10;
291
	}
291
	}
-
 
292
	n = 16 * n + d;
-
 
293
	c = read_char();
292
	*( t++ ) = ( char ) c ;
294
	cl = lookup_char(c);
293
	if ( t == token_end ) error ( ERROR_FATAL, "Buffer overflow" ) ;
295
    } while (is_hexdigit(cl));
294
    }
296
    unread_char(c);
295
    *t = 0 ;
297
    token_value = n;
296
    return ( lex_string ) ;
298
    return(lex_number);
297
}
299
}
298
 
300
 
299
 
301
 
300
/*
302
/*
301
    READ A COMMENT
303
 * READ A STRING
-
 
304
 *
-
 
305
 * This routine reads a string.  It is entered after the initial
-
 
306
 * quote has been read.  Note that there are no escape sequences.
-
 
307
 */
302
 
308
 
303
    This routine reads a C style comment, returning the lexical token
-
 
304
    immediately following.  It is entered after the first two characters
-
 
305
    have been read.
-
 
306
*/
-
 
307
 
-
 
308
static int read_comment
309
static int
309
    PROTO_Z ()
310
read_string(void)
310
{
311
{
311
    int state = 0 ;
312
    int c;
312
    char *t = token_buff ;
313
    char *t = token_buff;
313
    *( t++ ) = '/' ;
-
 
314
    *( t++ ) = '*' ;
-
 
315
    while ( state != 2 ) {
314
    while (c = read_char(), c != '"') {
316
	int c = read_char () ;
-
 
317
	if ( c == LEX_EOF ) {
315
	if (c == '\n' || c == LEX_EOF) {
318
	    error ( ERROR_SERIOUS, "End of file in comment" ) ;
316
	    error(ERROR_SERIOUS, "Unexpected end of string");
319
	    return ( lex_eof ) ;
317
	    break;
320
	}
318
	}
-
 
319
	*(t++) = (char)c;
-
 
320
	if (t == token_end) {
-
 
321
		error(ERROR_FATAL, "Buffer overflow");
-
 
322
	}
-
 
323
    }
-
 
324
    *t = 0;
-
 
325
    return(lex_string);
-
 
326
}
-
 
327
 
-
 
328
 
-
 
329
/*
-
 
330
 * READ A COMMENT
-
 
331
 *
-
 
332
 * This routine reads a C style comment, returning the lexical token
-
 
333
 * immediately following.  It is entered after the first two characters
-
 
334
 * have been read.
-
 
335
 */
-
 
336
 
-
 
337
static int
-
 
338
read_comment(void)
-
 
339
{
-
 
340
    int state = 0;
-
 
341
    char *t = token_buff;
-
 
342
    *(t++) = '/';
-
 
343
    *(t++) = '*';
-
 
344
    while (state != 2) {
-
 
345
	int c = read_char();
-
 
346
	if (c == LEX_EOF) {
-
 
347
	    error(ERROR_SERIOUS, "End of file in comment");
-
 
348
	    return(lex_eof);
-
 
349
	}
321
	if ( c == '*' ) {
350
	if (c == '*') {
322
	    state = 1 ;
351
	    state = 1;
323
	} else if ( state == 1 && c == '/' ) {
352
	} else if (state == 1 && c == '/') {
324
	    state = 2 ;
353
	    state = 2;
325
	} else {
354
	} else {
326
	    state = 0 ;
355
	    state = 0;
-
 
356
	}
-
 
357
	*(t++) = (char)c;
-
 
358
	if (t == token_end) {
-
 
359
		t = token_buff + 2;
327
	}
360
	}
328
	*( t++ ) = ( char ) c ;
-
 
329
	if ( t == token_end ) t = token_buff + 2 ;
-
 
330
    }
361
    }
331
    *t = 0 ;
362
    *t = 0;
-
 
363
    if (first_comment == NULL) {
332
    if ( first_comment == NULL ) first_comment = xstrcpy ( token_buff ) ;
364
	    first_comment = xstrcpy(token_buff);
-
 
365
    }
333
    return ( read_token () ) ;
366
    return(read_token());
334
}
367
}
335
 
368
 
336
 
369
 
337
/*
370
/*
338
    CURRENT TOKEN
371
 * CURRENT TOKEN
339
 
372
 *
340
    These variables are used by the parser to hold the current and former
373
 * These variables are used by the parser to hold the current and former
341
    lexical tokens.
374
 * lexical tokens.
342
*/
375
 */
343
 
376
 
344
int crt_lex_token ;
377
int crt_lex_token;
345
int saved_lex_token ;
378
int saved_lex_token;
346
 
379
 
347
 
380
 
348
/*
381
/*
349
    PROCESS FILE
382
 * PROCESS FILE
350
 
383
 *
351
    This routine processes the input file nm.  If r is true then it is
384
 * This routine processes the input file nm.  If r is true then it is
352
    processed using read_calculus, otherwise extra_calculus is used.
385
 * processed using read_calculus, otherwise extra_calculus is used.
353
*/
386
 */
354
 
387
 
355
void process_file
388
void
356
    PROTO_N ( ( nm, r ) )
-
 
357
    PROTO_T ( char *nm X int r )
389
process_file(char *nm, int r)
358
{
390
{
359
    crt_line_no = 1 ;
391
    crt_line_no = 1;
360
    crt_file_name = nm ;
392
    crt_file_name = nm;
361
    lex_input = fopen ( nm, "r" ) ;
393
    lex_input = fopen(nm, "r");
362
    if ( lex_input == NULL ) {
394
    if (lex_input == NULL) {
363
	error ( ERROR_SERIOUS, "Can't open input file, '%s'", nm ) ;
395
	error(ERROR_SERIOUS, "Can't open input file, '%s'", nm);
364
	return ;
396
	return;
365
    }
397
    }
366
    ADVANCE_LEXER ;
398
    ADVANCE_LEXER;
367
    if ( r ) {
399
    if (r) {
368
	read_calculus () ;
400
	read_calculus();
369
    } else {
401
    } else {
370
	extra_calculus () ;
402
	extra_calculus();
371
    }
403
    }
372
    if ( crt_lex_token != lex_eof ) {
404
    if (crt_lex_token != lex_eof) {
373
	error ( ERROR_SERIOUS, "Terminating due to syntax error" ) ;
405
	error(ERROR_SERIOUS, "Terminating due to syntax error");
374
    }
406
    }
375
    fclose_v ( lex_input ) ;
407
    fclose_v(lex_input);
376
    return ;
408
    return;
377
}
409
}