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/make_err/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 "errors.h"
33
#include "error.h"
34
#include "lex.h"
35
#include "syntax.h"
36
#include "xalloc.h"
37
 
38
 
39
/*
40
    INPUT FILE
41
 
42
    This is the file from which the lexical routine read their input.
43
*/
44
 
45
static FILE *lex_input ;
46
 
47
 
48
/*
49
    PENDING BUFFER
50
 
51
    Pending characters are dealt with by means of this buffer.  pending
52
    is set to the start of the buffer to indicate that there are no
53
    characters pending, otherwise the pending characters are stored in
54
    the buffer.  The buffer may need increasing in size if the look-ahead
55
    required by the lexical analyser increases.
56
*/
57
 
58
static int pending_buff [12] = { '?' } ;
59
static int *pending = pending_buff ;
60
 
61
 
62
/*
63
    MAPPINGS AND DECLARATIONS FOR AUTOMATICALLY GENERATED SECTION
64
 
65
    These macros give the mappings between the actions used in the
66
    automatically generated lexical analyser and the routines defined
67
    in this file.
68
*/
69
 
70
static int read_char PROTO_S ( ( void ) ) ;
71
static int read_comment PROTO_S ( ( void ) ) ;
72
static int read_identifier PROTO_S ( ( int ) ) ;
73
static int read_string PROTO_S ( ( void ) ) ;
74
 
75
#define get_comment( A, B )	read_comment ()
76
#define get_identifier( A )	read_identifier ( ( A ) )
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
*/
132
 
133
static int read_identifier
134
    PROTO_N ( ( a ) )
135
    PROTO_T ( int a )
136
{
137
    int c = a, cl ;
138
    char *t = token_buff ;
139
    do {
140
	*( t++ ) = ( char ) c ;
141
	if ( t == token_end ) error ( ERROR_FATAL, "Buffer overflow" ) ;
142
	c = read_char () ;
143
	cl = lookup_char ( c ) ;
144
    } while ( is_alphanum ( cl ) ) ;
145
    *t = 0 ;
146
    unread_char ( c ) ;
147
 
148
    /* Deal with keywords */
149
    t = token_buff ;
150
#define MAKE_KEYWORD( A, B )\
151
    if ( streq ( t, ( A ) ) ) return ( B ) ;
152
#include "keyword.h"
153
    return ( lex_identifier ) ;
154
}
155
 
156
 
157
/*
158
    READ A STRING
159
 
160
    This routine reads a string.  It is entered after the initial quote has
161
    been read.  Note that new line characters are allowed in strings.
162
*/
163
 
164
static int read_string
165
    PROTO_Z ()
166
{
167
    int c ;
168
    int escaped = 0 ;
169
    char *t = token_buff ;
170
    while ( c = read_char (), ( c != '"' || escaped ) ) {
171
	if ( c == LEX_EOF ) {
172
	    error ( ERROR_SERIOUS, "Unexpected end of string" ) ;
173
	    break ;
174
	}
175
	*( t++ ) = ( char ) c ;
176
	if ( t == token_end ) error ( ERROR_FATAL, "Buffer overflow" ) ;
177
	if ( escaped ) {
178
	    escaped = 0 ;
179
	} else {
180
	    if ( c == '\\' ) escaped = 1 ;
181
	}
182
    }
183
    *t = 0 ;
184
    return ( lex_string ) ;
185
}
186
 
187
 
188
/*
189
    READ A COMMENT
190
 
191
    This routine reads a C style comment, returning the lexical token
192
    immediately following.  It is entered after the first two characters
193
    have been read.
194
*/
195
 
196
static int read_comment
197
    PROTO_Z ()
198
{
199
    int state = 0 ;
200
    char *t = token_buff ;
201
    *( t++ ) = '/' ;
202
    *( t++ ) = '*' ;
203
    while ( state != 2 ) {
204
	int c = read_char () ;
205
	if ( c == LEX_EOF ) {
206
	    error ( ERROR_SERIOUS, "End of file in comment" ) ;
207
	    return ( lex_eof ) ;
208
	}
209
	if ( c == '*' ) {
210
	    state = 1 ;
211
	} else if ( state == 1 && c == '/' ) {
212
	    state = 2 ;
213
	} else {
214
	    state = 0 ;
215
	}
216
	*( t++ ) = ( char ) c ;
217
	if ( t == token_end ) t = token_buff + 2 ;
218
    }
219
    if ( first_comment == NULL ) first_comment = xstrcpy ( token_buff ) ;
220
    return ( read_token () ) ;
221
}
222
 
223
 
224
/*
225
    CURRENT TOKEN
226
 
227
    These variables are used by the parser to hold the current and former
228
    lexical tokens.
229
*/
230
 
231
int crt_lex_token ;
232
int saved_lex_token ;
233
 
234
 
235
/*
236
    PROCESS FILE
237
 
238
    This routine processes the input file nm.  If nm is the null string
239
    then the standard input is used.
240
*/
241
 
242
void process_file
243
    PROTO_N ( ( nm ) )
244
    PROTO_T ( char *nm )
245
{
246
    crt_line_no = 1 ;
247
    if ( nm == NULL || streq ( nm, "-" ) ) {
248
	crt_file_name = "stdin" ;
249
	lex_input = stdin ;
250
	nm = NULL ;
251
    } else {
252
	crt_file_name = nm ;
253
	lex_input = fopen ( nm, "r" ) ;
254
	if ( lex_input == NULL ) {
255
	    error ( ERROR_SERIOUS, "Can't open input file, '%s'", nm ) ;
256
	    return ;
257
	}
258
    }
259
    ADVANCE_LEXER ;
260
    read_errors () ;
261
    if ( nm != NULL ) fclose_v ( lex_input ) ;
262
    return ;
263
}