Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra4/src/utilities/lexi/lex.c – Rev 2

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
/*
2
    		 Crown Copyright (c) 1997
3
 
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:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
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;
19
 
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;
23
 
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
#include "config.h"
32
#include "error.h"
33
#include "lex.h"
34
#include "syntax.h"
35
#include "xalloc.h"
36
 
37
 
38
/*
39
    INPUT FILE
40
 
41
    This is the file from which the lexical routine read their input.
42
*/
43
 
44
static FILE *lex_input ;
45
 
46
 
47
/*
48
    PENDING BUFFER
49
 
50
    Pending characters are dealt with by means of this buffer.  pending
51
    is set to the start of the buffer to indicate that there are no
52
    characters pending, otherwise the pending characters are stored in
53
    the buffer.  The buffer may need increasing in size if the look-ahead
54
    required by the lexical analyser increases.
55
*/
56
 
57
static int pending_buff [12] = { '?' } ;
58
static int *pending = pending_buff ;
59
 
60
 
61
/*
62
    MAPPINGS AND DECLARATIONS FOR AUTOMATICALLY GENERATED SECTION
63
 
64
    These macros give the mappings between the actions used in the
65
    automatically generated lexical analyser and the routines defined
66
    in this file.
67
*/
68
 
69
static int read_char PROTO_S ( ( void ) ) ;
70
static int read_comment PROTO_S ( ( void ) ) ;
71
static int read_identifier PROTO_S ( ( int, int ) ) ;
72
static int read_string PROTO_S ( ( void ) ) ;
73
 
74
#define get_comment( A, B )	read_comment ()
75
#define get_identifier( A )	read_identifier ( ( A ), 0 )
76
#define get_sid_ident( A, B )	read_identifier ( ( B ), 1 )
77
#define get_string( A )		read_string ()
78
#define unknown_token( A )	lex_unknown
79
#define unread_char( A )	*( ++pending ) = ( A )
80
 
81
 
82
/*
83
    AUTOMATICALLY GENERATED SECTION
84
 
85
    The main body of the lexical analyser is automatically generated.
86
*/
87
 
88
#include "lexer.h"
89
 
90
 
91
/*
92
    GET THE NEXT CHARACTER
93
 
94
    This routine reads the next character, either from the pending buffer
95
    or from the input file.
96
*/
97
 
98
static int read_char
99
    PROTO_Z ()
100
{
101
    int c ;
102
    if ( pending != pending_buff ) {
103
	c = *( pending-- ) ;
104
    } else {
105
	c = fgetc ( lex_input ) ;
106
	if ( c == '\n' ) crt_line_no++ ;
107
	if ( c == EOF ) return ( LEX_EOF ) ;
108
	c &= 0xff ;
109
    }
110
    return ( c ) ;
111
}
112
 
113
 
114
/*
115
    TOKEN BUFFER
116
 
117
    This buffer is used by read_token to hold the values of identifiers
118
    and strings.
119
*/
120
 
121
char token_buff [2000] ;
122
static char *token_end = token_buff + sizeof ( token_buff ) ;
123
char *first_comment = NULL ;
124
 
125
 
126
/*
127
    READ AN IDENTIFIER
128
 
129
    This routine reads an identifier beginning with a, returning the
130
    corresponding lexical token.  Keywords are dealt with locally.
131
    The sid flag indicates whether a sid-style identifier is expected.
132
*/
133
 
134
static int read_identifier
135
    PROTO_N ( ( a, sid ) )
136
    PROTO_T ( int a X int sid )
137
{
138
    int c = a, cl ;
139
    int e = ( sid ? '-' : 'x' ) ;
140
    char *t = token_buff ;
141
    do {
142
	*( t++ ) = ( char ) c ;
143
	if ( t == token_end ) error ( ERROR_FATAL, "Buffer overflow" ) ;
144
	c = read_char () ;
145
	cl = lookup_char ( c ) ;
146
    } while ( is_alphanum ( cl ) || c == e ) ;
147
    *t = 0 ;
148
    unread_char ( c ) ;
149
 
150
    /* Deal with keywords */
151
    if ( sid ) return ( lex_sid_Hidentifier ) ;
152
    t = token_buff ;
153
#define MAKE_KEYWORD( A, B )\
154
    if ( streq ( t, ( A ) ) ) return ( B ) ;
155
#include "keyword.h"
156
    return ( lex_identifier ) ;
157
}
158
 
159
 
160
/*
161
    READ A STRING
162
 
163
    This routine reads a string.  It is entered after the initial
164
    quote has been read.
165
*/
166
 
167
static int read_string
168
    PROTO_Z ()
169
{
170
    int c ;
171
    int escaped = 0 ;
172
    char *t = token_buff ;
173
    while ( c = read_char (), ( c != '"' || escaped ) ) {
174
	if ( c == '\n' || c == LEX_EOF ) {
175
	    error ( ERROR_SERIOUS, "Unexpected end of string" ) ;
176
	    break ;
177
	}
178
	*( t++ ) = ( char ) c ;
179
	if ( t == token_end ) error ( ERROR_FATAL, "Buffer overflow" ) ;
180
	if ( escaped ) {
181
	    escaped = 0 ;
182
	} else {
183
	    if ( c == '\\' ) escaped = 1 ;
184
	}
185
    }
186
    *t = 0 ;
187
    return ( lex_string ) ;
188
}
189
 
190
 
191
/*
192
    READ A COMMENT
193
 
194
    This routine reads a C style comment, returning the lexical token
195
    immediately following.  It is entered after the first two characters
196
    have been read.
197
*/
198
 
199
static int read_comment
200
    PROTO_Z ()
201
{
202
    int state = 0 ;
203
    char *t = token_buff ;
204
    *( t++ ) = '/' ;
205
    *( t++ ) = '*' ;
206
    while ( state != 2 ) {
207
	int c = read_char () ;
208
	if ( c == LEX_EOF ) {
209
	    error ( ERROR_SERIOUS, "End of file in comment" ) ;
210
	    return ( lex_eof ) ;
211
	}
212
	if ( c == '*' ) {
213
	    state = 1 ;
214
	} else if ( state == 1 && c == '/' ) {
215
	    state = 2 ;
216
	} else {
217
	    state = 0 ;
218
	}
219
	*( t++ ) = ( char ) c ;
220
	if ( t == token_end ) t = token_buff + 2 ;
221
    }
222
    *t = 0 ;
223
    if ( first_comment == NULL ) first_comment = xstrcpy ( token_buff ) ;
224
    return ( read_token () ) ;
225
}
226
 
227
 
228
/*
229
    CURRENT TOKEN
230
 
231
    These variables are used by the parser to hold the current and former
232
    lexical tokens.
233
*/
234
 
235
int crt_lex_token ;
236
int saved_lex_token ;
237
 
238
 
239
/*
240
    PROCESS FILE
241
 
242
    This routine processes the input file nm.
243
*/
244
 
245
void process_file
246
    PROTO_N ( ( nm ) )
247
    PROTO_T ( char *nm )
248
{
249
    crt_line_no = 1 ;
250
    if ( nm == NULL || streq ( nm, "-" ) ) {
251
	crt_file_name = "<stdin>" ;
252
	lex_input = stdin ;
253
	nm = NULL ;
254
    } else {
255
	crt_file_name = nm ;
256
	lex_input = fopen ( nm, "r" ) ;
257
	if ( lex_input == NULL ) {
258
	    error ( ERROR_SERIOUS, "Can't open input file, '%s'", nm ) ;
259
	    return ;
260
	}
261
    }
262
    ADVANCE_LEXER ;
263
    read_lex () ;
264
    if ( nm ) fclose_v ( lex_input ) ;
265
    return ;
266
}