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
/*
7 7u83 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
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
7 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
7 7u83 42
 
2 7u83 43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
7 7u83 45
 
2 7u83 46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
7 7u83 49
 
2 7u83 50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
7 7u83 53
 
2 7u83 54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
/*** c-lexer.c --- SID C lexical analyser.
62
 *
63
 ** Author: Steve Folkes <smf@hermes.mod.uk>
64
 *
65
 *** Commentary:
66
 *
67
 * This file implements the SID C lexical analyser.  Any changes to the syntax
68
 * of SID identifiers should be made both here and in the file
69
 * "../parser/lexer.c".
70
 *
71
 *** Change Log:
72
 * $Log: c-lexer.c,v $
73
 * Revision 1.1.1.1  1998/01/17  15:57:42  release
74
 * First version to be checked into rolling release.
75
 *
76
 * Revision 1.2  1994/12/15  09:55:56  smf
77
 * Brought into line with OSSG C Coding Standards Document, as per
78
 * "CR94_178.sid+tld-update".
79
 *
80
 * Revision 1.1.1.1  1994/07/25  16:04:13  smf
81
 * Initial import of SID 1.8 non shared files.
82
 *
83
**/
84
 
85
/****************************************************************************/
86
 
87
#include "c-lexer.h"
88
#include "gen-errors.h"
89
#include "syntax.h"
90
 
91
/*--------------------------------------------------------------------------*/
92
 
7 7u83 93
#define LEXER_READ_ONE_CHAR(istream, redo, eof, id)\
94
    switch ((id) = ISTREAM_READ_CHAR(istream)) { \
2 7u83 95
      case '\0': \
7 7u83 96
        ISTREAM_HANDLE_NULL((istream), redo, eof); \
2 7u83 97
        break; \
98
      case '\n': \
7 7u83 99
        istream_inc_line(istream); \
2 7u83 100
        break; \
101
      default: \
102
        break; \
103
    }
104
 
105
/*--------------------------------------------------------------------------*/
106
 
107
static BoolT
7 7u83 108
c_lexer_skip_bracketed_comment(IStreamP istream)
2 7u83 109
{
110
    char c1;
111
    char c2;
112
 
113
  redo1:
7 7u83 114
    LEXER_READ_ONE_CHAR(istream, redo1, eof, c1);
2 7u83 115
  redo2:
7 7u83 116
    LEXER_READ_ONE_CHAR(istream, redo2, eof, c2);
2 7u83 117
    for (;;) {
118
	if ((c1 == '/') && (c2 == '*')) {
7 7u83 119
	    if (!c_lexer_skip_bracketed_comment(istream)) {
2 7u83 120
		goto eof;
121
	    }
122
	  redo3:
7 7u83 123
	    LEXER_READ_ONE_CHAR(istream, redo3, eof, c2);
2 7u83 124
	} else if ((c1 == '*') && (c2 == '/')) {
7 7u83 125
	    return(TRUE);
2 7u83 126
	}
127
	c1 = c2;
128
      redo4:
7 7u83 129
	LEXER_READ_ONE_CHAR(istream, redo4, eof, c2);
2 7u83 130
    }
131
  eof:
7 7u83 132
    return(FALSE);
2 7u83 133
}
134
 
135
static char
7 7u83 136
c_lexer_skip_white_space(IStreamP istream)
2 7u83 137
{
138
    for (;;) {
139
	char c;
140
 
141
      redo1:
7 7u83 142
	switch (c = ISTREAM_READ_CHAR(istream)) {
2 7u83 143
	  case '\0':
7 7u83 144
	    ISTREAM_HANDLE_NULL(istream, redo1, eof);
2 7u83 145
	    break;
146
	  case '\n':
7 7u83 147
	    istream_inc_line(istream);
2 7u83 148
	    break;
149
	  case '/':
150
	  redo2:
7 7u83 151
	    switch (c = ISTREAM_READ_CHAR(istream)) {
2 7u83 152
	      case '\0':
7 7u83 153
		ISTREAM_HANDLE_NULL(istream, redo2, eof_in_comment);
2 7u83 154
		goto illegal_in_comment;
155
	      case '\n':
7 7u83 156
		istream_inc_line(istream);
2 7u83 157
		goto illegal_in_comment;
158
	      case '*':
7 7u83 159
		if (!c_lexer_skip_bracketed_comment(istream)) {
2 7u83 160
		  eof_in_comment:
7 7u83 161
		    E_c_eof_in_comment(istream);
162
		    return('\0'); /*FOR EOF*/
2 7u83 163
		}
164
		break;
165
	      case '/':
166
		do {
167
		  redo3:
7 7u83 168
		    LEXER_READ_ONE_CHAR(istream, redo3, eof, c);
2 7u83 169
		} while (c != '\n');
170
		break;
171
	      default:
172
	      illegal_in_comment:
7 7u83 173
		E_c_illegal_comment_character(istream, c);
2 7u83 174
		break;
175
	    }
176
	    break;
177
	  default:
7 7u83 178
	    if (!syntax_is_white_space(c)) {
179
		return(c);
2 7u83 180
	    }
181
	    break;
182
	}
183
    }
184
  eof:
7 7u83 185
    return('\0'); /*FOR EOF*/
2 7u83 186
}
187
 
188
static void
7 7u83 189
c_lexer_read_builtin(IStreamP istream, CLexP token)
2 7u83 190
{
191
    DStringT dstring;
192
    CStringP cstring;
193
 
7 7u83 194
    dstring_init(&dstring);
2 7u83 195
    for (;;) {
196
	char c;
197
 
198
      redo:
7 7u83 199
	switch (c = ISTREAM_READ_CHAR(istream)) {
2 7u83 200
	  case '\0':
7 7u83 201
	    ISTREAM_HANDLE_NULL(istream, redo, eof);
202
	    E_c_null_character_in_builtin(istream);
2 7u83 203
	    break;
204
	  case '\n':
7 7u83 205
	    istream_inc_line(istream);
206
	    E_c_newline_in_builtin(istream);
2 7u83 207
	    goto done;
208
	  case '%':
209
	    goto done;
210
	  default:
7 7u83 211
	    dstring_append_char(&dstring, c);
2 7u83 212
	    break;
213
	}
214
    }
215
  eof:
7 7u83 216
    E_c_eof_in_builtin(istream);
2 7u83 217
  done:
7 7u83 218
    cstring = dstring_destroy_to_cstring(&dstring);
219
    if (cstring_ci_equal(cstring, "prefixes")) {
2 7u83 220
	token->t = C_TOK_BLT_PREFIXES;
7 7u83 221
    } else if (cstring_ci_equal(cstring, "maps")) {
2 7u83 222
	token->t = C_TOK_BLT_MAPS;
7 7u83 223
    } else if (cstring_ci_equal(cstring, "assignments")) {
2 7u83 224
	token->t = C_TOK_BLT_ASSIGNMENTS;
7 7u83 225
    } else if (cstring_ci_equal(cstring, "assign")) {
2 7u83 226
	token->t = C_TOK_BLT_ASSIGNMENTS;
7 7u83 227
    } else if (cstring_ci_equal(cstring, "terminals")) {
2 7u83 228
	token->t = C_TOK_BLT_TERMINALS;
7 7u83 229
    } else if (cstring_ci_equal(cstring, "header")) {
2 7u83 230
	token->t = C_TOK_BLT_HEADER;
7 7u83 231
    } else if (cstring_ci_equal(cstring, "actions")) {
2 7u83 232
	token->t = C_TOK_BLT_ACTIONS;
7 7u83 233
    } else if (cstring_ci_equal(cstring, "trailer")) {
2 7u83 234
	token->t = C_TOK_BLT_TRAILER;
7 7u83 235
    } else if (cstring_ci_equal(cstring, "result-assignments")) {
2 7u83 236
	token->t = C_TOK_BLT_RESULT_ASSIGN;
7 7u83 237
    } else if (cstring_ci_equal(cstring, "result-assign")) {
2 7u83 238
	token->t = C_TOK_BLT_RESULT_ASSIGN;
7 7u83 239
    } else if (cstring_ci_equal(cstring, "parameter-assignments")) {
2 7u83 240
	token->t = C_TOK_BLT_PARAM_ASSIGN;
7 7u83 241
    } else if (cstring_ci_equal(cstring, "parameter-assign")) {
2 7u83 242
	token->t = C_TOK_BLT_PARAM_ASSIGN;
7 7u83 243
    } else if (cstring_ci_equal(cstring, "param-assignments")) {
2 7u83 244
	token->t = C_TOK_BLT_PARAM_ASSIGN;
7 7u83 245
    } else if (cstring_ci_equal(cstring, "param-assign")) {
2 7u83 246
	token->t = C_TOK_BLT_PARAM_ASSIGN;
247
    } else {
7 7u83 248
	E_c_unknown_builtin(istream, cstring);
2 7u83 249
	UNREACHED;
250
    }
7 7u83 251
    DEALLOCATE(cstring);
2 7u83 252
}
253
 
254
static void
7 7u83 255
c_lexer_read_identifier(IStreamP istream, char c, CLexP token)
2 7u83 256
{
257
    BoolT    c_ident = (c != '-');
258
    DStringT dstring;
259
 
7 7u83 260
    dstring_init(&dstring);
261
    dstring_append_char(&dstring, c);
2 7u83 262
    for (;;) {
263
      redo1:
7 7u83 264
	switch (c = ISTREAM_PEEK_CHAR(istream)) {
2 7u83 265
	  case '\0':
7 7u83 266
	    ISTREAM_HANDLE_NULL(istream, redo1, done);
2 7u83 267
	    goto done;
268
	  default:
7 7u83 269
	    if ((syntax_is_letter(c)) || (syntax_is_digit(c)) ||
2 7u83 270
		(c == '_') || (c == '-')) {
271
	      redo2:
7 7u83 272
		LEXER_READ_ONE_CHAR(istream, redo2, done, c);
273
		dstring_append_char(&dstring, c);
2 7u83 274
		if (c == '-') {
275
		    c_ident = FALSE;
276
		}
277
	    } else {
278
		goto done;
279
	    }
280
	    break;
281
	}
282
    }
283
  done:
284
    if (c_ident) {
285
	token->t = C_TOK_C_IDENTIFIER;
286
    } else {
287
	token->t = C_TOK_SID_IDENTIFIER;
288
    }
7 7u83 289
    dstring_to_nstring(&dstring, &(token->u.string));
290
    dstring_destroy(&dstring);
2 7u83 291
}
292
 
293
static void
7 7u83 294
c_lexer_read_code_id(IStreamP istream, char c, NStringP nstring)
2 7u83 295
{
7 7u83 296
    BoolT    numbers_ok = (syntax_is_letter(c) || (c == '_'));
2 7u83 297
    DStringT dstring;
298
    char     c1;
299
 
7 7u83 300
    dstring_init(&dstring);
2 7u83 301
    if (numbers_ok) {
7 7u83 302
	dstring_append_char(&dstring, c);
2 7u83 303
    }
304
    for (;;) {
305
      redo1:
7 7u83 306
	switch (c1 = ISTREAM_PEEK_CHAR(istream)) {
2 7u83 307
	  case '\0':
7 7u83 308
	    ISTREAM_HANDLE_NULL(istream, redo1, done);
2 7u83 309
	    goto done;
310
	  default:
7 7u83 311
	    if (syntax_is_letter(c1) || (c1 == '_') ||
312
		(numbers_ok && syntax_is_digit(c1))) {
2 7u83 313
	      redo2:
7 7u83 314
		LEXER_READ_ONE_CHAR(istream, redo2, done, c1);
315
		dstring_append_char(&dstring, c1);
2 7u83 316
		numbers_ok = TRUE;
317
	    } else {
318
		goto done;
319
	    }
320
	    break;
321
	}
322
    }
323
  done:
324
    if (!numbers_ok) {
7 7u83 325
	E_c_expected_at_id(istream, c);
2 7u83 326
    }
7 7u83 327
    dstring_to_nstring(&dstring, nstring);
328
    dstring_destroy(&dstring);
2 7u83 329
}
330
 
331
static void
7 7u83 332
c_lexer_flush_string(DStringP dstring, CCodeP code, BoolT force_nl)
2 7u83 333
{
334
    NStringT nstring;
335
 
7 7u83 336
    if (dstring_length(dstring) > 0) {
337
	if (force_nl && (!dstring_last_char_equal(dstring, '\n'))) {
338
	    dstring_append_char(dstring, '\n');
2 7u83 339
	}
7 7u83 340
	dstring_to_nstring(dstring, &nstring);
341
	c_code_append_string(code, &nstring);
342
	dstring_destroy(dstring);
343
	dstring_init(dstring);
2 7u83 344
    } else if (force_nl) {
7 7u83 345
	nstring_copy_cstring(&nstring, "\n");
346
	c_code_append_string(code, &nstring);
2 7u83 347
    }
348
}
349
 
350
static BoolT
7 7u83 351
c_lexer_read_at(IStreamP istream, DStringP dstring, CCodeP code)
2 7u83 352
{
353
    char     c;
354
    NStringT nstring;
355
 
356
  redo:
7 7u83 357
    switch (c = ISTREAM_READ_CHAR(istream)) {
2 7u83 358
      case '\0':
7 7u83 359
	ISTREAM_HANDLE_NULL(istream, redo, error);
2 7u83 360
	goto error;
361
      case '\n':
7 7u83 362
	istream_inc_line(istream);
2 7u83 363
	goto error;
364
      case '@':
7 7u83 365
	dstring_append_char(dstring, c);
2 7u83 366
	break;
367
      case '}':
7 7u83 368
	return(TRUE);
2 7u83 369
      case '!':
7 7u83 370
	c_lexer_flush_string(dstring, code, FALSE);
371
	c_code_append_exception(code);
2 7u83 372
	break;
373
      case '.':
7 7u83 374
	c_lexer_flush_string(dstring, code, FALSE);
375
	c_code_append_terminal(code);
2 7u83 376
	break;
377
      case '>':
7 7u83 378
	c_lexer_flush_string(dstring, code, FALSE);
379
	c_code_append_advance(code);
2 7u83 380
	break;
381
      case ':':
7 7u83 382
	c_lexer_flush_string(dstring, code, FALSE);
383
	c_lexer_read_code_id(istream, ':', &nstring);
384
	c_code_append_label(code, &nstring);
2 7u83 385
	break;
386
      case '&':
7 7u83 387
	c_lexer_flush_string(dstring, code, FALSE);
388
	c_lexer_read_code_id(istream, '&', &nstring);
389
	c_code_append_reference(code, &nstring);
2 7u83 390
	break;
391
      case '=':
7 7u83 392
	c_lexer_flush_string(dstring, code, FALSE);
393
	c_lexer_read_code_id(istream, '=', &nstring);
394
	c_code_append_modifiable(code, &nstring);
2 7u83 395
	break;
396
      default:
7 7u83 397
	if (syntax_is_letter(c) || (c == '_')) {
398
	    c_lexer_flush_string(dstring, code, FALSE);
399
	    c_lexer_read_code_id(istream, c, &nstring);
400
	    c_code_append_identifier(code, &nstring);
2 7u83 401
	} else {
402
	  error:
7 7u83 403
	    E_c_illegal_at_char(istream, c);
2 7u83 404
	}
405
	break;
406
    }
7 7u83 407
    return(FALSE);
2 7u83 408
}
7 7u83 409
 
2 7u83 410
static void
7 7u83 411
c_lexer_read_code(IStreamP istream, CLexP token)
2 7u83 412
{
7 7u83 413
    CCodeP   code = c_code_create(istream_name(istream),
414
				   istream_line(istream));
2 7u83 415
    DStringT dstring;
416
    char     c;
417
 
418
  redo1:
7 7u83 419
    switch (ISTREAM_PEEK_CHAR(istream)) {
2 7u83 420
      case '\0':
7 7u83 421
	ISTREAM_HANDLE_NULL(istream, redo1, error);
2 7u83 422
	goto error;
423
      case '{':
424
      redo2:
7 7u83 425
	LEXER_READ_ONE_CHAR(istream, redo2, error, c);
426
	UNUSED(c);
2 7u83 427
	break;
428
      default:
429
      error:
7 7u83 430
	E_c_code_block_syntax(istream);
2 7u83 431
	break;
432
    }
7 7u83 433
    dstring_init(&dstring);
2 7u83 434
    for (;;) {
435
      redo3:
7 7u83 436
	switch (c = ISTREAM_READ_CHAR(istream)) {
2 7u83 437
	  case '\0':
7 7u83 438
	    ISTREAM_HANDLE_NULL(istream, redo3, eof);
439
	    dstring_append_char(&dstring, c);
2 7u83 440
	    break;
441
	  case '\n':
7 7u83 442
	    istream_inc_line(istream);
443
	    dstring_append_char(&dstring, c);
2 7u83 444
	    break;
445
	  case '@':
7 7u83 446
	    if (c_lexer_read_at(istream, &dstring, code)) {
2 7u83 447
		goto done;
448
	    }
449
	    break;
450
	  default:
7 7u83 451
	    dstring_append_char(&dstring, c);
2 7u83 452
	    break;
453
	}
454
    }
455
  eof:
7 7u83 456
    E_c_eof_in_code(istream);
2 7u83 457
  done:
458
    token->t = C_TOK_CODE;
7 7u83 459
    c_lexer_flush_string(&dstring, code, TRUE);
460
    dstring_destroy(&dstring);
2 7u83 461
    token->u.code = code;
462
}
463
 
464
/*--------------------------------------------------------------------------*/
465
 
466
void
7 7u83 467
c_lexer_init(CLexerStreamP stream, IStreamP istream)
2 7u83 468
{
7 7u83 469
    istream_assign(&(stream->istream), istream);
470
    c_lexer_next_token(stream);
2 7u83 471
}
472
 
473
#ifdef FS_FAST
474
#undef c_lexer_close
475
#endif /* defined (FS_FAST) */
476
void
7 7u83 477
c_lexer_close(CLexerStreamP stream)
2 7u83 478
{
7 7u83 479
    istream_close(&(stream->istream));
2 7u83 480
}
481
#ifdef FS_FAST
7 7u83 482
#define c_lexer_close(s)	(istream_close(&((s)->istream)))
2 7u83 483
#endif /* defined (FS_FAST) */
484
 
485
#ifdef FS_FAST
486
#undef c_lexer_stream_name
487
#endif /* defined (FS_FAST) */
488
CStringP
7 7u83 489
c_lexer_stream_name(CLexerStreamP stream)
2 7u83 490
{
7 7u83 491
    return(istream_name(&(stream->istream)));
2 7u83 492
}
493
#ifdef FS_FAST
7 7u83 494
#define c_lexer_stream_name(s)	(istream_name(&((s)->istream)))
2 7u83 495
#endif /* defined (FS_FAST) */
496
 
497
#ifdef FS_FAST
498
#undef c_lexer_stream_line
499
#endif /* defined (FS_FAST) */
500
unsigned
7 7u83 501
c_lexer_stream_line(CLexerStreamP stream)
2 7u83 502
{
7 7u83 503
    return(istream_line(&(stream->istream)));
2 7u83 504
}
505
#ifdef FS_FAST
7 7u83 506
#define c_lexer_stream_line(s)	(istream_line(&((s)->istream)))
2 7u83 507
#endif /* defined (FS_FAST) */
508
 
509
#ifdef FS_FAST
510
#undef c_lexer_get_terminal
511
#endif /* defined (FS_FAST) */
512
CTokenT
7 7u83 513
c_lexer_get_terminal(CLexerStreamP stream)
2 7u83 514
{
7 7u83 515
    return(stream->token.t);
2 7u83 516
}
517
#ifdef FS_FAST
7 7u83 518
#define c_lexer_get_terminal(s)	((s)->token.t)
2 7u83 519
#endif /* defined (FS_FAST) */
520
 
521
void
7 7u83 522
c_lexer_next_token(CLexerStreamP stream)
2 7u83 523
{
524
    IStreamP istream = &(stream->istream);
525
    CLexT    token;
526
    char     c;
527
 
528
  retry:
7 7u83 529
    switch (c = c_lexer_skip_white_space(istream)) {
2 7u83 530
      case '\0': /*FOR EOF*/
531
	token.t = C_TOK_EOF;
532
	break;
533
      case '%':
7 7u83 534
	c_lexer_read_builtin(istream, &token);
2 7u83 535
	break;
536
      case ',':
537
	token.t = C_TOK_SEPARATOR;
538
	break;
539
      case ':':
540
	token.t = C_TOK_TYPEMARK;
541
	break;
542
      case ';':
543
	token.t = C_TOK_TERMINATOR;
544
	break;
545
      case '<':
546
	token.t = C_TOK_BEGIN_ACTION;
547
	break;
548
      case '=':
549
	token.t = C_TOK_DEFINE;
550
	break;
551
      case '>':
552
	token.t = C_TOK_END_ACTION;
553
	break;
554
      case '(':
555
	token.t = C_TOK_OPEN_TUPLE;
556
	break;
557
      case ')':
558
	token.t = C_TOK_CLOSE_TUPLE;
559
	break;
560
      case '&':
561
	token.t = C_TOK_REFERENCE;
562
	break;
563
      case '@':
7 7u83 564
	c_lexer_read_code(istream, &token);
2 7u83 565
	break;
566
      case '-':
7 7u83 567
	if ((istream_peek_char(istream, &c)) && (c == '>')) {
568
	   (void)istream_read_char(istream, &c);
2 7u83 569
	    token.t = C_TOK_ARROW;
570
	    break;
571
	}
7 7u83 572
	c_lexer_read_identifier(istream, '-', &token);
2 7u83 573
	break;
574
      default:
7 7u83 575
	if ((syntax_is_letter(c)) || (c == '_')) {
576
	    c_lexer_read_identifier(istream, c, &token);
2 7u83 577
	} else {
7 7u83 578
	    E_c_illegal_character(istream, c);
2 7u83 579
	    goto retry;
580
	}
581
	break;
582
    }
583
    stream->token = token;
584
}
585
 
586
#ifdef FS_FAST
587
#undef c_lexer_string_value
588
#endif /* defined (FS_FAST) */
589
NStringP
7 7u83 590
c_lexer_string_value(CLexerStreamP stream)
2 7u83 591
{
7 7u83 592
    ASSERT((stream->token.t == C_TOK_C_IDENTIFIER) ||
593
	   (stream->token.t == C_TOK_SID_IDENTIFIER));
594
    return(&(stream->token.u.string));
2 7u83 595
}
596
#ifdef FS_FAST
7 7u83 597
#define c_lexer_string_value(s)	(&((s)->token.u.string))
2 7u83 598
#endif /* defined (FS_FAST) */
599
 
600
#ifdef FS_FAST
601
#undef c_lexer_code_value
602
#endif /* defined (FS_FAST) */
603
CCodeP
7 7u83 604
c_lexer_code_value(CLexerStreamP stream)
2 7u83 605
{
7 7u83 606
    ASSERT(stream->token.t == C_TOK_CODE);
607
    return(stream->token.u.code);
2 7u83 608
}
609
#ifdef FS_FAST
7 7u83 610
#define c_lexer_code_value(s)	((s)->token.u.code)
2 7u83 611
#endif /* defined (FS_FAST) */
612
 
613
void
7 7u83 614
c_lexer_save_terminal(CLexerStreamP stream, CTokenT error_terminal)
2 7u83 615
{
7 7u83 616
    ASSERT(stream->token.t != error_terminal);
2 7u83 617
    stream->saved_terminal = stream->token.t;
618
    stream->token.t        = error_terminal;
619
}
620
 
621
void
7 7u83 622
c_lexer_restore_terminal(CLexerStreamP stream)
2 7u83 623
{
624
    stream->token.t = stream->saved_terminal;
625
}
626
 
627
/*
628
 * Local variables(smf):
629
 * eval: (include::add-path-entry "../os-interface" "../library")
630
 * eval: (include::add-path-entry "../transforms" "../output")
631
 * eval: (include::add-path-entry "../c-output" "../generated")
632
 * end:
633
**/