Subversion Repositories tendra.SVN

Rev

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

Rev 2 Rev 7
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 58... Line 88...
58
#include "gen-errors.h"
88
#include "gen-errors.h"
59
#include "syntax.h"
89
#include "syntax.h"
60
 
90
 
61
/*--------------------------------------------------------------------------*/
91
/*--------------------------------------------------------------------------*/
62
 
92
 
63
#define LEXER_READ_ONE_CHAR(istream, redo, eof, id) \
93
#define LEXER_READ_ONE_CHAR(istream, redo, eof, id)\
64
    switch ((id) = ISTREAM_READ_CHAR (istream)) { \
94
    switch ((id) = ISTREAM_READ_CHAR(istream)) { \
65
      case '\0': \
95
      case '\0': \
66
        ISTREAM_HANDLE_NULL ((istream), redo, eof); \
96
        ISTREAM_HANDLE_NULL((istream), redo, eof); \
67
        break; \
97
        break; \
68
      case '\n': \
98
      case '\n': \
69
        istream_inc_line (istream); \
99
        istream_inc_line(istream); \
70
        break; \
100
        break; \
71
      default: \
101
      default: \
72
        break; \
102
        break; \
73
    }
103
    }
74
 
104
 
75
/*--------------------------------------------------------------------------*/
105
/*--------------------------------------------------------------------------*/
76
 
106
 
77
static BoolT
107
static BoolT
78
lexer_skip_bracketed_comment PROTO_N ((istream))
108
lexer_skip_bracketed_comment(IStreamP istream)
79
			     PROTO_T (IStreamP istream)
-
 
80
{
109
{
81
    char c1;
110
    char c1;
82
    char c2;
111
    char c2;
83
 
112
 
84
  redo1:
113
  redo1:
85
    LEXER_READ_ONE_CHAR (istream, redo1, eof, c1);
114
    LEXER_READ_ONE_CHAR(istream, redo1, eof, c1);
86
  redo2:
115
  redo2:
87
    LEXER_READ_ONE_CHAR (istream, redo2, eof, c2);
116
    LEXER_READ_ONE_CHAR(istream, redo2, eof, c2);
88
    for (;;) {
117
    for (;;) {
89
	if ((c1 == '/') && (c2 == '*')) {
118
	if ((c1 == '/') && (c2 == '*')) {
90
	    if (!lexer_skip_bracketed_comment (istream)) {
119
	    if (!lexer_skip_bracketed_comment(istream)) {
91
		goto eof;
120
		goto eof;
92
	    }
121
	    }
93
	  redo3:
122
	  redo3:
94
	    LEXER_READ_ONE_CHAR (istream, redo3, eof, c2);
123
	    LEXER_READ_ONE_CHAR(istream, redo3, eof, c2);
95
	} else if ((c1 == '*') && (c2 == '/')) {
124
	} else if ((c1 == '*') && (c2 == '/')) {
96
	    return (TRUE);
125
	    return(TRUE);
97
	}
126
	}
98
	c1 = c2;
127
	c1 = c2;
99
      redo4:
128
      redo4:
100
	LEXER_READ_ONE_CHAR (istream, redo4, eof, c2);
129
	LEXER_READ_ONE_CHAR(istream, redo4, eof, c2);
101
    }
130
    }
102
  eof:
131
  eof:
103
    return (FALSE);
132
    return(FALSE);
104
}
133
}
105
 
134
 
106
static char
135
static char
107
lexer_skip_white_space PROTO_N ((istream))
136
lexer_skip_white_space(IStreamP istream)
108
		       PROTO_T (IStreamP istream)
-
 
109
{
137
{
110
    for (;;) {
138
    for (;;) {
111
	char c;
139
	char c;
112
 
140
 
113
      redo1:
141
      redo1:
114
	switch (c = ISTREAM_READ_CHAR (istream)) {
142
	switch (c = ISTREAM_READ_CHAR(istream)) {
115
	  case '\0':
143
	  case '\0':
116
	    ISTREAM_HANDLE_NULL (istream, redo1, eof);
144
	    ISTREAM_HANDLE_NULL(istream, redo1, eof);
117
	    break;
145
	    break;
118
	  case '\n':
146
	  case '\n':
119
	    istream_inc_line (istream);
147
	    istream_inc_line(istream);
120
	    break;
148
	    break;
121
	  case '/':
149
	  case '/':
122
	  redo2:
150
	  redo2:
123
	    switch (c = ISTREAM_READ_CHAR (istream)) {
151
	    switch (c = ISTREAM_READ_CHAR(istream)) {
124
	      case '\0':
152
	      case '\0':
125
		ISTREAM_HANDLE_NULL (istream, redo2, eof_in_comment);
153
		ISTREAM_HANDLE_NULL(istream, redo2, eof_in_comment);
126
		goto illegal_in_comment;
154
		goto illegal_in_comment;
127
	      case '\n':
155
	      case '\n':
128
		istream_inc_line (istream);
156
		istream_inc_line(istream);
129
		goto illegal_in_comment;
157
		goto illegal_in_comment;
130
	      case '*':
158
	      case '*':
131
		if (!lexer_skip_bracketed_comment (istream)) {
159
		if (!lexer_skip_bracketed_comment(istream)) {
132
		  eof_in_comment:
160
		  eof_in_comment:
133
		    E_eof_in_comment (istream);
161
		    E_eof_in_comment(istream);
134
		    return ('\0'); /*FOR EOF*/
162
		    return ('\0'); /*FOR EOF*/
135
		}
163
		}
136
		break;
164
		break;
137
	      case '/':
165
	      case '/':
138
		do {
166
		do {
139
		  redo3:
167
		  redo3:
140
		    LEXER_READ_ONE_CHAR (istream, redo3, eof, c);
168
		    LEXER_READ_ONE_CHAR(istream, redo3, eof, c);
141
		} while (c != '\n');
169
		} while (c != '\n');
142
		break;
170
		break;
143
	      default:
171
	      default:
144
	      illegal_in_comment:
172
	      illegal_in_comment:
145
		E_illegal_comment_character (istream, c);
173
		E_illegal_comment_character(istream, c);
146
		break;
174
		break;
147
	    }
175
	    }
148
	    break;
176
	    break;
149
	  default:
177
	  default:
150
	    if (!syntax_is_white_space (c)) {
178
	    if (!syntax_is_white_space(c)) {
151
		return (c);
179
		return(c);
152
	    }
180
	    }
153
	    break;
181
	    break;
154
	}
182
	}
155
    }
183
    }
156
  eof:
184
  eof:
157
    return ('\0'); /*FOR EOF*/
185
    return ('\0'); /*FOR EOF*/
158
}
186
}
159
 
187
 
160
static void
188
static void
161
lexer_read_builtin PROTO_N ((istream, token))
189
lexer_read_builtin(IStreamP istream, LexP token)
162
		   PROTO_T (IStreamP istream X
-
 
163
			    LexP     token)
-
 
164
{
190
{
165
    DStringT dstring;
191
    DStringT dstring;
166
    CStringP cstring;
192
    CStringP cstring;
167
 
193
 
168
    dstring_init (&dstring);
194
    dstring_init(&dstring);
169
    for (;;) {
195
    for (;;) {
170
	char c;
196
	char c;
171
 
197
 
172
      redo:
198
      redo:
173
	switch (c = ISTREAM_READ_CHAR (istream)) {
199
	switch (c = ISTREAM_READ_CHAR(istream)) {
174
	  case '\0':
200
	  case '\0':
175
	    ISTREAM_HANDLE_NULL (istream, redo, eof);
201
	    ISTREAM_HANDLE_NULL(istream, redo, eof);
176
	    E_null_character_in_builtin (istream);
202
	    E_null_character_in_builtin(istream);
177
	    break;
203
	    break;
178
	  case '\n':
204
	  case '\n':
179
	    istream_inc_line (istream);
205
	    istream_inc_line(istream);
180
	    E_newline_in_builtin (istream);
206
	    E_newline_in_builtin(istream);
181
	    goto done;
207
	    goto done;
182
	  case '%':
208
	  case '%':
183
	    goto done;
209
	    goto done;
184
	  default:
210
	  default:
185
	    dstring_append_char (&dstring, c);
211
	    dstring_append_char(&dstring, c);
186
	}
212
	}
187
    }
213
    }
188
  eof:
214
  eof:
189
    E_eof_in_builtin (istream);
215
    E_eof_in_builtin(istream);
190
  done:
216
  done:
191
    cstring = dstring_destroy_to_cstring (&dstring);
217
    cstring = dstring_destroy_to_cstring(&dstring);
192
    if (cstring_ci_equal (cstring, "types")) {
218
    if (cstring_ci_equal(cstring, "types")) {
193
	token->t = LEXER_TOK_BLT_TYPES;
219
	token->t = LEXER_TOK_BLT_TYPES;
194
    } else if (cstring_ci_equal (cstring, "terminals")) {
220
    } else if (cstring_ci_equal(cstring, "terminals")) {
195
	token->t = LEXER_TOK_BLT_TERMINALS;
221
	token->t = LEXER_TOK_BLT_TERMINALS;
196
    } else if (cstring_ci_equal (cstring, "productions")) {
222
    } else if (cstring_ci_equal(cstring, "productions")) {
197
	token->t = LEXER_TOK_BLT_PRODUCTIONS;
223
	token->t = LEXER_TOK_BLT_PRODUCTIONS;
198
    } else if (cstring_ci_equal (cstring, "entry")) {
224
    } else if (cstring_ci_equal(cstring, "entry")) {
199
	token->t = LEXER_TOK_BLT_ENTRY;
225
	token->t = LEXER_TOK_BLT_ENTRY;
200
    } else {
226
    } else {
201
	E_unknown_builtin (istream, cstring);
227
	E_unknown_builtin(istream, cstring);
202
	UNREACHED;
228
	UNREACHED;
203
    }
229
    }
204
    DEALLOCATE (cstring);
230
    DEALLOCATE(cstring);
205
}
231
}
206
 
232
 
207
static void
233
static void
208
lexer_read_identifier PROTO_N ((istream, c, token))
234
lexer_read_identifier(IStreamP istream, char c, LexP token)
209
		      PROTO_T (IStreamP istream X
-
 
210
			       char     c X
-
 
211
			       LexP     token)
-
 
212
{
235
{
213
    DStringT dstring;
236
    DStringT dstring;
214
 
237
 
215
    dstring_init (&dstring);
238
    dstring_init(&dstring);
216
    dstring_append_char (&dstring, c);
239
    dstring_append_char(&dstring, c);
217
    for (;;) {
240
    for (;;) {
218
      redo1:
241
      redo1:
219
	switch (c = ISTREAM_PEEK_CHAR (istream)) {
242
	switch (c = ISTREAM_PEEK_CHAR(istream)) {
220
	  case '\0':
243
	  case '\0':
221
	    ISTREAM_HANDLE_NULL (istream, redo1, done);
244
	    ISTREAM_HANDLE_NULL(istream, redo1, done);
222
	    goto done;
245
	    goto done;
223
	  default:
246
	  default:
224
	    if ((syntax_is_letter (c)) || (syntax_is_digit (c)) ||
247
	    if ((syntax_is_letter(c)) || (syntax_is_digit(c)) ||
225
		(c == '_') || (c == '-')) {
248
		(c == '_') || (c == '-')) {
226
	      redo2:
249
	      redo2:
227
		LEXER_READ_ONE_CHAR (istream, redo2, done, c);
250
		LEXER_READ_ONE_CHAR(istream, redo2, done, c);
228
		dstring_append_char (&dstring, c);
251
		dstring_append_char(&dstring, c);
229
	    } else {
252
	    } else {
230
		goto done;
253
		goto done;
231
	    }
254
	    }
232
	    break;
255
	    break;
233
	}
256
	}
234
    }
257
    }
235
  done:
258
  done:
236
    token->t = LEXER_TOK_IDENTIFIER;
259
    token->t = LEXER_TOK_IDENTIFIER;
237
    dstring_to_nstring (&dstring, &(token->u.string));
260
    dstring_to_nstring(&dstring, &(token->u.string));
238
    dstring_destroy (&dstring);
261
    dstring_destroy(&dstring);
239
}
262
}
240
 
263
 
241
/*--------------------------------------------------------------------------*/
264
/*--------------------------------------------------------------------------*/
242
 
265
 
243
void
266
void
244
lexer_init PROTO_N ((stream, istream))
267
lexer_init(LexerStreamP stream, IStreamP istream)
245
	   PROTO_T (LexerStreamP stream X
-
 
246
		    IStreamP     istream)
-
 
247
{
268
{
248
    istream_assign (&(stream->istream), istream);
269
    istream_assign(&(stream->istream), istream);
249
    lexer_next_token (stream);
270
    lexer_next_token(stream);
250
}
271
}
251
 
272
 
252
#ifdef FS_FAST
273
#ifdef FS_FAST
253
#undef lexer_close
274
#undef lexer_close
254
#endif /* defined (FS_FAST) */
275
#endif /* defined (FS_FAST) */
255
void
276
void
256
lexer_close PROTO_N ((stream))
-
 
257
	    PROTO_T (LexerStreamP stream)
277
lexer_close(LexerStreamP stream)
258
{
278
{
259
    istream_close (&(stream->istream));
279
    istream_close(&(stream->istream));
260
}
280
}
261
#ifdef FS_FAST
281
#ifdef FS_FAST
262
#define lexer_close(s) (istream_close (&((s)->istream)))
282
#define lexer_close(s)	(istream_close(&((s)->istream)))
263
#endif /* defined (FS_FAST) */
283
#endif /* defined (FS_FAST) */
264
 
284
 
265
#ifdef FS_FAST
285
#ifdef FS_FAST
266
#undef lexer_stream_name
286
#undef lexer_stream_name
267
#endif /* defined (FS_FAST) */
287
#endif /* defined (FS_FAST) */
268
CStringP
288
CStringP
269
lexer_stream_name PROTO_N ((stream))
289
lexer_stream_name(LexerStreamP stream)
270
		  PROTO_T (LexerStreamP stream)
-
 
271
{
290
{
272
    return (istream_name (&(stream->istream)));
291
    return(istream_name(&(stream->istream)));
273
}
292
}
274
#ifdef FS_FAST
293
#ifdef FS_FAST
275
#define lexer_stream_name(s) (istream_name (&((s)->istream)))
294
#define lexer_stream_name(s)	(istream_name(&((s)->istream)))
276
#endif /* defined (FS_FAST) */
295
#endif /* defined (FS_FAST) */
277
 
296
 
278
#ifdef FS_FAST
297
#ifdef FS_FAST
279
#undef lexer_stream_line
298
#undef lexer_stream_line
280
#endif /* defined (FS_FAST) */
299
#endif /* defined (FS_FAST) */
281
unsigned
300
unsigned
282
lexer_stream_line PROTO_N ((stream))
301
lexer_stream_line(LexerStreamP stream)
283
		  PROTO_T (LexerStreamP stream)
-
 
284
{
302
{
285
    return (istream_line (&(stream->istream)));
303
    return(istream_line(&(stream->istream)));
286
}
304
}
287
#ifdef FS_FAST
305
#ifdef FS_FAST
288
#define lexer_stream_line(s) (istream_line (&((s)->istream)))
306
#define lexer_stream_line(s)	(istream_line(&((s)->istream)))
289
#endif /* defined (FS_FAST) */
307
#endif /* defined (FS_FAST) */
290
 
308
 
291
#ifdef FS_FAST
309
#ifdef FS_FAST
292
#undef lexer_get_terminal
310
#undef lexer_get_terminal
293
#endif /* defined (FS_FAST) */
311
#endif /* defined (FS_FAST) */
294
LexerTokenT
312
LexerTokenT
295
lexer_get_terminal PROTO_N ((stream))
313
lexer_get_terminal(LexerStreamP stream)
296
		   PROTO_T (LexerStreamP stream)
-
 
297
{
314
{
298
    return (stream->token.t);
315
    return(stream->token.t);
299
}
316
}
300
#ifdef FS_FAST
317
#ifdef FS_FAST
301
#define lexer_get_terminal(s) ((s)->token.t)
318
#define lexer_get_terminal(s)	((s)->token.t)
302
#endif /* defined (FS_FAST) */
319
#endif /* defined (FS_FAST) */
303
 
320
 
304
void
321
void
305
lexer_next_token PROTO_N ((stream))
322
lexer_next_token(LexerStreamP stream)
306
		 PROTO_T (LexerStreamP stream)
-
 
307
{
323
{
308
    IStreamP istream = &(stream->istream);
324
    IStreamP istream = &(stream->istream);
309
    LexT     token;
325
    LexT     token;
310
    char     c;
326
    char     c;
311
 
327
 
312
  retry:
328
  retry:
313
    switch (c = lexer_skip_white_space (istream)) {
329
    switch (c = lexer_skip_white_space(istream)) {
314
      case '\0': /*FOR EOF*/
330
      case '\0': /*FOR EOF*/
315
	token.t = LEXER_TOK_EOF;
331
	token.t = LEXER_TOK_EOF;
316
	break;
332
	break;
317
      case '#':
333
      case '#':
318
	if ((istream_peek_char (istream, &c)) && (c == '#')) {
334
	if ((istream_peek_char(istream, &c)) && (c == '#')) {
319
	    (void) istream_read_char (istream, &c);
335
	   (void)istream_read_char(istream, &c);
320
	    token.t = LEXER_TOK_HANDLER_SEP;
336
	    token.t = LEXER_TOK_HANDLER_SEP;
321
	    break;
337
	    break;
322
	}
338
	}
323
	E_expected_hash (istream);
339
	E_expected_hash(istream);
324
	goto retry;
340
	goto retry;
325
      case '$':
341
      case '$':
326
	token.t = LEXER_TOK_EMPTY;
342
	token.t = LEXER_TOK_EMPTY;
327
	break;
343
	break;
328
      case '%':
344
      case '%':
329
	lexer_read_builtin (istream, &token);
345
	lexer_read_builtin(istream, &token);
330
	break;
346
	break;
331
      case '|':
347
      case '|':
332
	if ((istream_peek_char (istream, &c)) && (c == '|')) {
348
	if ((istream_peek_char(istream, &c)) && (c == '|')) {
333
	    (void) istream_read_char (istream, &c);
349
	   (void)istream_read_char(istream, &c);
334
	    token.t = LEXER_TOK_ALT_SEP;
350
	    token.t = LEXER_TOK_ALT_SEP;
335
	    break;
351
	    break;
336
	}
352
	}
337
	E_expected_pipe (istream);
353
	E_expected_pipe(istream);
338
	goto retry;
354
	goto retry;
339
      case ',':
355
      case ',':
340
	token.t = LEXER_TOK_SEPARATOR;
356
	token.t = LEXER_TOK_SEPARATOR;
341
	break;	
357
	break;
342
      case ':':
358
      case ':':
343
	if ((istream_peek_char (istream, &c)) && (c == ':')) {
359
	if ((istream_peek_char(istream, &c)) && (c == ':')) {
344
	    (void) istream_read_char (istream, &c);
360
	   (void)istream_read_char(istream, &c);
345
	    token.t = LEXER_TOK_SCOPEMARK;
361
	    token.t = LEXER_TOK_SCOPEMARK;
346
	    break;
362
	    break;
347
	}
363
	}
348
	token.t = LEXER_TOK_TYPEMARK;
364
	token.t = LEXER_TOK_TYPEMARK;
349
	break;
365
	break;
Line 385... Line 401...
385
	break;
401
	break;
386
      case '&':
402
      case '&':
387
	token.t = LEXER_TOK_REFERENCE;
403
	token.t = LEXER_TOK_REFERENCE;
388
	break;
404
	break;
389
      case '-':
405
      case '-':
390
	if ((istream_peek_char (istream, &c)) && (c == '>')) {
406
	if ((istream_peek_char(istream, &c)) && (c == '>')) {
391
	    (void) istream_read_char (istream, &c);
407
	   (void)istream_read_char(istream, &c);
392
	    token.t = LEXER_TOK_ARROW;
408
	    token.t = LEXER_TOK_ARROW;
393
	    break;
409
	    break;
394
	}
410
	}
395
	lexer_read_identifier (istream, '-', &token);
411
	lexer_read_identifier(istream, '-', &token);
396
	break;
412
	break;
397
      default:
413
      default:
398
	if ((syntax_is_letter (c)) || (c == '_')) {
414
	if ((syntax_is_letter(c)) || (c == '_')) {
399
	    lexer_read_identifier (istream, c, &token);
415
	    lexer_read_identifier(istream, c, &token);
400
	} else {
416
	} else {
401
	    E_illegal_character (istream, c);
417
	    E_illegal_character(istream, c);
402
	    goto retry;
418
	    goto retry;
403
	}
419
	}
404
	break;
420
	break;
405
    }
421
    }
406
    stream->token = token;
422
    stream->token = token;
Line 408... Line 424...
408
 
424
 
409
#ifdef FS_FAST
425
#ifdef FS_FAST
410
#undef lexer_string_value
426
#undef lexer_string_value
411
#endif /* defined (FS_FAST) */
427
#endif /* defined (FS_FAST) */
412
NStringP
428
NStringP
413
lexer_string_value PROTO_N ((stream))
429
lexer_string_value(LexerStreamP stream)
414
		   PROTO_T (LexerStreamP stream)
-
 
415
{
430
{
416
    ASSERT (stream->token.t == LEXER_TOK_IDENTIFIER);
431
    ASSERT(stream->token.t == LEXER_TOK_IDENTIFIER);
417
    return (&(stream->token.u.string));
432
    return(&(stream->token.u.string));
418
}
433
}
419
#ifdef FS_FAST
434
#ifdef FS_FAST
420
#define lexer_string_value(s) (&((s)->token.u.string))
435
#define lexer_string_value(s)	(&((s)->token.u.string))
421
#endif /* defined (FS_FAST) */
436
#endif /* defined (FS_FAST) */
422
 
437
 
423
void
438
void
424
lexer_save_terminal PROTO_N ((stream, error_terminal))
439
lexer_save_terminal(LexerStreamP stream, LexerTokenT error_terminal)
425
		    PROTO_T (LexerStreamP stream X
-
 
426
			     LexerTokenT  error_terminal)
-
 
427
{
440
{
428
    ASSERT (stream->token.t != error_terminal);
441
    ASSERT(stream->token.t != error_terminal);
429
    stream->saved_terminal = stream->token.t;
442
    stream->saved_terminal = stream->token.t;
430
    stream->token.t        = error_terminal;
443
    stream->token.t        = error_terminal;
431
}
444
}
432
 
445
 
433
void
446
void
434
lexer_restore_terminal PROTO_N ((stream))
447
lexer_restore_terminal(LexerStreamP stream)
435
		       PROTO_T (LexerStreamP stream)
-
 
436
{
448
{
437
    stream->token.t = stream->saved_terminal;
449
    stream->token.t = stream->saved_terminal;
438
}
450
}
439

451

440
/*
452
/*