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 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
c_lexer_skip_bracketed_comment PROTO_N ((istream))
108
c_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 (!c_lexer_skip_bracketed_comment (istream)) {
119
	    if (!c_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
c_lexer_skip_white_space PROTO_N ((istream))
136
c_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 (!c_lexer_skip_bracketed_comment (istream)) {
159
		if (!c_lexer_skip_bracketed_comment(istream)) {
132
		  eof_in_comment:
160
		  eof_in_comment:
133
		    E_c_eof_in_comment (istream);
161
		    E_c_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_c_illegal_comment_character (istream, c);
173
		E_c_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
c_lexer_read_builtin PROTO_N ((istream, token))
189
c_lexer_read_builtin(IStreamP istream, CLexP token)
162
		     PROTO_T (IStreamP istream X
-
 
163
			      CLexP    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_c_null_character_in_builtin (istream);
202
	    E_c_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_c_newline_in_builtin (istream);
206
	    E_c_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
	    break;
212
	    break;
187
	}
213
	}
188
    }
214
    }
189
  eof:
215
  eof:
190
    E_c_eof_in_builtin (istream);
216
    E_c_eof_in_builtin(istream);
191
  done:
217
  done:
192
    cstring = dstring_destroy_to_cstring (&dstring);
218
    cstring = dstring_destroy_to_cstring(&dstring);
193
    if (cstring_ci_equal (cstring, "prefixes")) {
219
    if (cstring_ci_equal(cstring, "prefixes")) {
194
	token->t = C_TOK_BLT_PREFIXES;
220
	token->t = C_TOK_BLT_PREFIXES;
195
    } else if (cstring_ci_equal (cstring, "maps")) {
221
    } else if (cstring_ci_equal(cstring, "maps")) {
196
	token->t = C_TOK_BLT_MAPS;
222
	token->t = C_TOK_BLT_MAPS;
197
    } else if (cstring_ci_equal (cstring, "assignments")) {
223
    } else if (cstring_ci_equal(cstring, "assignments")) {
198
	token->t = C_TOK_BLT_ASSIGNMENTS;
224
	token->t = C_TOK_BLT_ASSIGNMENTS;
199
    } else if (cstring_ci_equal (cstring, "assign")) {
225
    } else if (cstring_ci_equal(cstring, "assign")) {
200
	token->t = C_TOK_BLT_ASSIGNMENTS;
226
	token->t = C_TOK_BLT_ASSIGNMENTS;
201
    } else if (cstring_ci_equal (cstring, "terminals")) {
227
    } else if (cstring_ci_equal(cstring, "terminals")) {
202
	token->t = C_TOK_BLT_TERMINALS;
228
	token->t = C_TOK_BLT_TERMINALS;
203
    } else if (cstring_ci_equal (cstring, "header")) {
229
    } else if (cstring_ci_equal(cstring, "header")) {
204
	token->t = C_TOK_BLT_HEADER;
230
	token->t = C_TOK_BLT_HEADER;
205
    } else if (cstring_ci_equal (cstring, "actions")) {
231
    } else if (cstring_ci_equal(cstring, "actions")) {
206
	token->t = C_TOK_BLT_ACTIONS;
232
	token->t = C_TOK_BLT_ACTIONS;
207
    } else if (cstring_ci_equal (cstring, "trailer")) {
233
    } else if (cstring_ci_equal(cstring, "trailer")) {
208
	token->t = C_TOK_BLT_TRAILER;
234
	token->t = C_TOK_BLT_TRAILER;
209
    } else if (cstring_ci_equal (cstring, "result-assignments")) {
235
    } else if (cstring_ci_equal(cstring, "result-assignments")) {
210
	token->t = C_TOK_BLT_RESULT_ASSIGN;
-
 
211
    } else if (cstring_ci_equal (cstring, "result-assign")) {
-
 
212
	token->t = C_TOK_BLT_RESULT_ASSIGN;
236
	token->t = C_TOK_BLT_RESULT_ASSIGN;
-
 
237
    } else if (cstring_ci_equal(cstring, "result-assign")) {
-
 
238
	token->t = C_TOK_BLT_RESULT_ASSIGN;
213
    } else if (cstring_ci_equal (cstring, "parameter-assignments")) {
239
    } else if (cstring_ci_equal(cstring, "parameter-assignments")) {
-
 
240
	token->t = C_TOK_BLT_PARAM_ASSIGN;
-
 
241
    } else if (cstring_ci_equal(cstring, "parameter-assign")) {
214
	token->t = C_TOK_BLT_PARAM_ASSIGN;
242
	token->t = C_TOK_BLT_PARAM_ASSIGN;
215
    } else if (cstring_ci_equal (cstring, "parameter-assign")) {
243
    } else if (cstring_ci_equal(cstring, "param-assignments")) {
216
	token->t = C_TOK_BLT_PARAM_ASSIGN;
244
	token->t = C_TOK_BLT_PARAM_ASSIGN;
217
    } else if (cstring_ci_equal (cstring, "param-assignments")) {
-
 
218
	token->t = C_TOK_BLT_PARAM_ASSIGN;
-
 
219
    } else if (cstring_ci_equal (cstring, "param-assign")) {
245
    } else if (cstring_ci_equal(cstring, "param-assign")) {
220
	token->t = C_TOK_BLT_PARAM_ASSIGN;
246
	token->t = C_TOK_BLT_PARAM_ASSIGN;
221
    } else {
247
    } else {
222
	E_c_unknown_builtin (istream, cstring);
248
	E_c_unknown_builtin(istream, cstring);
223
	UNREACHED;
249
	UNREACHED;
224
    }
250
    }
225
    DEALLOCATE (cstring);
251
    DEALLOCATE(cstring);
226
}
252
}
227
 
253
 
228
static void
254
static void
229
c_lexer_read_identifier PROTO_N ((istream, c, token))
255
c_lexer_read_identifier(IStreamP istream, char c, CLexP token)
230
			PROTO_T (IStreamP istream X
-
 
231
				 char     c X
-
 
232
				 CLexP    token)
-
 
233
{
256
{
234
    BoolT    c_ident = (c != '-');
257
    BoolT    c_ident = (c != '-');
235
    DStringT dstring;
258
    DStringT dstring;
236
 
259
 
237
    dstring_init (&dstring);
260
    dstring_init(&dstring);
238
    dstring_append_char (&dstring, c);
261
    dstring_append_char(&dstring, c);
239
    for (;;) {
262
    for (;;) {
240
      redo1:
263
      redo1:
241
	switch (c = ISTREAM_PEEK_CHAR (istream)) {
264
	switch (c = ISTREAM_PEEK_CHAR(istream)) {
242
	  case '\0':
265
	  case '\0':
243
	    ISTREAM_HANDLE_NULL (istream, redo1, done);
266
	    ISTREAM_HANDLE_NULL(istream, redo1, done);
244
	    goto done;
267
	    goto done;
245
	  default:
268
	  default:
246
	    if ((syntax_is_letter (c)) || (syntax_is_digit (c)) ||
269
	    if ((syntax_is_letter(c)) || (syntax_is_digit(c)) ||
247
		(c == '_') || (c == '-')) {
270
		(c == '_') || (c == '-')) {
248
	      redo2:
271
	      redo2:
249
		LEXER_READ_ONE_CHAR (istream, redo2, done, c);
272
		LEXER_READ_ONE_CHAR(istream, redo2, done, c);
250
		dstring_append_char (&dstring, c);
273
		dstring_append_char(&dstring, c);
251
		if (c == '-') {
274
		if (c == '-') {
252
		    c_ident = FALSE;
275
		    c_ident = FALSE;
253
		}
276
		}
254
	    } else {
277
	    } else {
255
		goto done;
278
		goto done;
Line 259... Line 282...
259
    }
282
    }
260
  done:
283
  done:
261
    if (c_ident) {
284
    if (c_ident) {
262
	token->t = C_TOK_C_IDENTIFIER;
285
	token->t = C_TOK_C_IDENTIFIER;
263
    } else {
286
    } else {
264
	token->t = C_TOK_SID_IDENTIFIER;
287
	token->t = C_TOK_SID_IDENTIFIER;
265
    }
288
    }
266
    dstring_to_nstring (&dstring, &(token->u.string));
289
    dstring_to_nstring(&dstring, &(token->u.string));
267
    dstring_destroy (&dstring);
290
    dstring_destroy(&dstring);
268
}
291
}
269
 
292
 
270
static void
293
static void
271
c_lexer_read_code_id PROTO_N ((istream, c, nstring))
294
c_lexer_read_code_id(IStreamP istream, char c, NStringP nstring)
272
		     PROTO_T (IStreamP istream X
-
 
273
			      char     c X
-
 
274
			      NStringP nstring)
-
 
275
{
295
{
276
    BoolT    numbers_ok = (syntax_is_letter (c) || (c == '_'));
296
    BoolT    numbers_ok = (syntax_is_letter(c) || (c == '_'));
277
    DStringT dstring;
297
    DStringT dstring;
278
    char     c1;
298
    char     c1;
279
 
299
 
280
    dstring_init (&dstring);
300
    dstring_init(&dstring);
281
    if (numbers_ok) {
301
    if (numbers_ok) {
282
	dstring_append_char (&dstring, c);
302
	dstring_append_char(&dstring, c);
283
    }
303
    }
284
    for (;;) {
304
    for (;;) {
285
      redo1:
305
      redo1:
286
	switch (c1 = ISTREAM_PEEK_CHAR (istream)) {
306
	switch (c1 = ISTREAM_PEEK_CHAR(istream)) {
287
	  case '\0':
307
	  case '\0':
288
	    ISTREAM_HANDLE_NULL (istream, redo1, done);
308
	    ISTREAM_HANDLE_NULL(istream, redo1, done);
289
	    goto done;
309
	    goto done;
290
	  default:
310
	  default:
291
	    if (syntax_is_letter (c1) || (c1 == '_') ||
311
	    if (syntax_is_letter(c1) || (c1 == '_') ||
292
		(numbers_ok && syntax_is_digit (c1))) {
312
		(numbers_ok && syntax_is_digit(c1))) {
293
	      redo2:
313
	      redo2:
294
		LEXER_READ_ONE_CHAR (istream, redo2, done, c1);
314
		LEXER_READ_ONE_CHAR(istream, redo2, done, c1);
295
		dstring_append_char (&dstring, c1);
315
		dstring_append_char(&dstring, c1);
296
		numbers_ok = TRUE;
316
		numbers_ok = TRUE;
297
	    } else {
317
	    } else {
298
		goto done;
318
		goto done;
299
	    }
319
	    }
300
	    break;
320
	    break;
301
	}
321
	}
302
    }
322
    }
303
  done:
323
  done:
304
    if (!numbers_ok) {
324
    if (!numbers_ok) {
305
	E_c_expected_at_id (istream, c);
325
	E_c_expected_at_id(istream, c);
306
    }
326
    }
307
    dstring_to_nstring (&dstring, nstring);
327
    dstring_to_nstring(&dstring, nstring);
308
    dstring_destroy (&dstring);
328
    dstring_destroy(&dstring);
309
}
329
}
310
 
330
 
311
static void
331
static void
312
c_lexer_flush_string PROTO_N ((dstring, code, force_nl))
332
c_lexer_flush_string(DStringP dstring, CCodeP code, BoolT force_nl)
313
		     PROTO_T (DStringP dstring X
-
 
314
			      CCodeP   code X
-
 
315
			      BoolT    force_nl)
-
 
316
{
333
{
317
    NStringT nstring;
334
    NStringT nstring;
318
 
335
 
319
    if (dstring_length (dstring) > 0) {
336
    if (dstring_length(dstring) > 0) {
320
	if (force_nl && (!dstring_last_char_equal (dstring, '\n'))) {
337
	if (force_nl && (!dstring_last_char_equal(dstring, '\n'))) {
321
	    dstring_append_char (dstring, '\n');
338
	    dstring_append_char(dstring, '\n');
322
	}
339
	}
323
	dstring_to_nstring (dstring, &nstring);
340
	dstring_to_nstring(dstring, &nstring);
324
	c_code_append_string (code, &nstring);
341
	c_code_append_string(code, &nstring);
325
	dstring_destroy (dstring);
342
	dstring_destroy(dstring);
326
	dstring_init (dstring);
343
	dstring_init(dstring);
327
    } else if (force_nl) {
344
    } else if (force_nl) {
328
	nstring_copy_cstring (&nstring, "\n");
345
	nstring_copy_cstring(&nstring, "\n");
329
	c_code_append_string (code, &nstring);
346
	c_code_append_string(code, &nstring);
330
    }
347
    }
331
}
348
}
332
 
349
 
333
static BoolT
350
static BoolT
334
c_lexer_read_at PROTO_N ((istream, dstring, code))
351
c_lexer_read_at(IStreamP istream, DStringP dstring, CCodeP code)
335
		PROTO_T (IStreamP istream X
-
 
336
			 DStringP dstring X
-
 
337
			 CCodeP   code)
-
 
338
{
352
{
339
    char     c;
353
    char     c;
340
    NStringT nstring;
354
    NStringT nstring;
341
 
355
 
342
  redo:
356
  redo:
343
    switch (c = ISTREAM_READ_CHAR (istream)) {
357
    switch (c = ISTREAM_READ_CHAR(istream)) {
344
      case '\0':
358
      case '\0':
345
	ISTREAM_HANDLE_NULL (istream, redo, error);
359
	ISTREAM_HANDLE_NULL(istream, redo, error);
346
	goto error;
360
	goto error;
347
      case '\n':
361
      case '\n':
348
	istream_inc_line (istream);
362
	istream_inc_line(istream);
349
	goto error;
363
	goto error;
350
      case '@':
364
      case '@':
351
	dstring_append_char (dstring, c);
365
	dstring_append_char(dstring, c);
352
	break;
366
	break;
353
      case '}':
367
      case '}':
354
	return (TRUE);
368
	return(TRUE);
355
      case '!':
369
      case '!':
356
	c_lexer_flush_string (dstring, code, FALSE);
370
	c_lexer_flush_string(dstring, code, FALSE);
357
	c_code_append_exception (code);
371
	c_code_append_exception(code);
358
	break;
372
	break;
359
      case '.':
373
      case '.':
360
	c_lexer_flush_string (dstring, code, FALSE);
374
	c_lexer_flush_string(dstring, code, FALSE);
361
	c_code_append_terminal (code);
375
	c_code_append_terminal(code);
362
	break;
376
	break;
363
      case '>':
377
      case '>':
364
	c_lexer_flush_string (dstring, code, FALSE);
378
	c_lexer_flush_string(dstring, code, FALSE);
365
	c_code_append_advance (code);
379
	c_code_append_advance(code);
366
	break;
380
	break;
367
      case ':':
381
      case ':':
368
	c_lexer_flush_string (dstring, code, FALSE);
382
	c_lexer_flush_string(dstring, code, FALSE);
369
	c_lexer_read_code_id (istream, ':', &nstring);
383
	c_lexer_read_code_id(istream, ':', &nstring);
370
	c_code_append_label (code, &nstring);
384
	c_code_append_label(code, &nstring);
371
	break;
385
	break;
372
      case '&':
386
      case '&':
373
	c_lexer_flush_string (dstring, code, FALSE);
387
	c_lexer_flush_string(dstring, code, FALSE);
374
	c_lexer_read_code_id (istream, '&', &nstring);
388
	c_lexer_read_code_id(istream, '&', &nstring);
375
	c_code_append_reference (code, &nstring);
389
	c_code_append_reference(code, &nstring);
376
	break;
390
	break;
377
      case '=':
391
      case '=':
378
	c_lexer_flush_string (dstring, code, FALSE);
392
	c_lexer_flush_string(dstring, code, FALSE);
379
	c_lexer_read_code_id (istream, '=', &nstring);
393
	c_lexer_read_code_id(istream, '=', &nstring);
380
	c_code_append_modifiable (code, &nstring);
394
	c_code_append_modifiable(code, &nstring);
381
	break;
395
	break;
382
      default:
396
      default:
383
	if (syntax_is_letter (c) || (c == '_')) {
397
	if (syntax_is_letter(c) || (c == '_')) {
384
	    c_lexer_flush_string (dstring, code, FALSE);
398
	    c_lexer_flush_string(dstring, code, FALSE);
385
	    c_lexer_read_code_id (istream, c, &nstring);
399
	    c_lexer_read_code_id(istream, c, &nstring);
386
	    c_code_append_identifier (code, &nstring);
400
	    c_code_append_identifier(code, &nstring);
387
	} else {
401
	} else {
388
	  error:
402
	  error:
389
	    E_c_illegal_at_char (istream, c);
403
	    E_c_illegal_at_char(istream, c);
390
	}
404
	}
391
	break;
405
	break;
392
    }
406
    }
393
    return (FALSE);
407
    return(FALSE);
394
}
408
}
395
    
409
 
396
static void
410
static void
397
c_lexer_read_code PROTO_N ((istream, token))
411
c_lexer_read_code(IStreamP istream, CLexP token)
398
		  PROTO_T (IStreamP istream X
-
 
399
			   CLexP    token)
-
 
400
{
412
{
401
    CCodeP   code = c_code_create (istream_name (istream),
413
    CCodeP   code = c_code_create(istream_name(istream),
402
				   istream_line (istream));
414
				   istream_line(istream));
403
    DStringT dstring;
415
    DStringT dstring;
404
    char     c;
416
    char     c;
405
 
417
 
406
  redo1:
418
  redo1:
407
    switch (ISTREAM_PEEK_CHAR (istream)) {
419
    switch (ISTREAM_PEEK_CHAR(istream)) {
408
      case '\0':
420
      case '\0':
409
	ISTREAM_HANDLE_NULL (istream, redo1, error);
421
	ISTREAM_HANDLE_NULL(istream, redo1, error);
410
	goto error;
422
	goto error;
411
      case '{':
423
      case '{':
412
      redo2:
424
      redo2:
413
	LEXER_READ_ONE_CHAR (istream, redo2, error, c);
425
	LEXER_READ_ONE_CHAR(istream, redo2, error, c);
414
	UNUSED (c);
426
	UNUSED(c);
415
	break;
427
	break;
416
      default:
428
      default:
417
      error:
429
      error:
418
	E_c_code_block_syntax (istream);
430
	E_c_code_block_syntax(istream);
419
	break;
431
	break;
420
    }
432
    }
421
    dstring_init (&dstring);
433
    dstring_init(&dstring);
422
    for (;;) {
434
    for (;;) {
423
      redo3:
435
      redo3:
424
	switch (c = ISTREAM_READ_CHAR (istream)) {
436
	switch (c = ISTREAM_READ_CHAR(istream)) {
425
	  case '\0':
437
	  case '\0':
426
	    ISTREAM_HANDLE_NULL (istream, redo3, eof);
438
	    ISTREAM_HANDLE_NULL(istream, redo3, eof);
427
	    dstring_append_char (&dstring, c);
439
	    dstring_append_char(&dstring, c);
428
	    break;
440
	    break;
429
	  case '\n':
441
	  case '\n':
430
	    istream_inc_line (istream);
442
	    istream_inc_line(istream);
431
	    dstring_append_char (&dstring, c);
443
	    dstring_append_char(&dstring, c);
432
	    break;
444
	    break;
433
	  case '@':
445
	  case '@':
434
	    if (c_lexer_read_at (istream, &dstring, code)) {
446
	    if (c_lexer_read_at(istream, &dstring, code)) {
435
		goto done;
447
		goto done;
436
	    }
448
	    }
437
	    break;
449
	    break;
438
	  default:
450
	  default:
439
	    dstring_append_char (&dstring, c);
451
	    dstring_append_char(&dstring, c);
440
	    break;
452
	    break;
441
	}
453
	}
442
    }
454
    }
443
  eof:
455
  eof:
444
    E_c_eof_in_code (istream);
456
    E_c_eof_in_code(istream);
445
  done:
457
  done:
446
    token->t = C_TOK_CODE;
458
    token->t = C_TOK_CODE;
447
    c_lexer_flush_string (&dstring, code, TRUE);
459
    c_lexer_flush_string(&dstring, code, TRUE);
448
    dstring_destroy (&dstring);
460
    dstring_destroy(&dstring);
449
    token->u.code = code;
461
    token->u.code = code;
450
}
462
}
451
 
463
 
452
/*--------------------------------------------------------------------------*/
464
/*--------------------------------------------------------------------------*/
453
 
465
 
454
void
466
void
455
c_lexer_init PROTO_N ((stream, istream))
467
c_lexer_init(CLexerStreamP stream, IStreamP istream)
456
	     PROTO_T (CLexerStreamP stream X
-
 
457
		      IStreamP      istream)
-
 
458
{
468
{
459
    istream_assign (&(stream->istream), istream);
469
    istream_assign(&(stream->istream), istream);
460
    c_lexer_next_token (stream);
470
    c_lexer_next_token(stream);
461
}
471
}
462
 
472
 
463
#ifdef FS_FAST
473
#ifdef FS_FAST
464
#undef c_lexer_close
474
#undef c_lexer_close
465
#endif /* defined (FS_FAST) */
475
#endif /* defined (FS_FAST) */
466
void
476
void
467
c_lexer_close PROTO_N ((stream))
-
 
468
	      PROTO_T (CLexerStreamP stream)
477
c_lexer_close(CLexerStreamP stream)
469
{
478
{
470
    istream_close (&(stream->istream));
479
    istream_close(&(stream->istream));
471
}
480
}
472
#ifdef FS_FAST
481
#ifdef FS_FAST
473
#define c_lexer_close(s) (istream_close (&((s)->istream)))
482
#define c_lexer_close(s)	(istream_close(&((s)->istream)))
474
#endif /* defined (FS_FAST) */
483
#endif /* defined (FS_FAST) */
475
 
484
 
476
#ifdef FS_FAST
485
#ifdef FS_FAST
477
#undef c_lexer_stream_name
486
#undef c_lexer_stream_name
478
#endif /* defined (FS_FAST) */
487
#endif /* defined (FS_FAST) */
479
CStringP
488
CStringP
480
c_lexer_stream_name PROTO_N ((stream))
489
c_lexer_stream_name(CLexerStreamP stream)
481
		    PROTO_T (CLexerStreamP stream)
-
 
482
{
490
{
483
    return (istream_name (&(stream->istream)));
491
    return(istream_name(&(stream->istream)));
484
}
492
}
485
#ifdef FS_FAST
493
#ifdef FS_FAST
486
#define c_lexer_stream_name(s) (istream_name (&((s)->istream)))
494
#define c_lexer_stream_name(s)	(istream_name(&((s)->istream)))
487
#endif /* defined (FS_FAST) */
495
#endif /* defined (FS_FAST) */
488
 
496
 
489
#ifdef FS_FAST
497
#ifdef FS_FAST
490
#undef c_lexer_stream_line
498
#undef c_lexer_stream_line
491
#endif /* defined (FS_FAST) */
499
#endif /* defined (FS_FAST) */
492
unsigned
500
unsigned
493
c_lexer_stream_line PROTO_N ((stream))
501
c_lexer_stream_line(CLexerStreamP stream)
494
		    PROTO_T (CLexerStreamP stream)
-
 
495
{
502
{
496
    return (istream_line (&(stream->istream)));
503
    return(istream_line(&(stream->istream)));
497
}
504
}
498
#ifdef FS_FAST
505
#ifdef FS_FAST
499
#define c_lexer_stream_line(s) (istream_line (&((s)->istream)))
506
#define c_lexer_stream_line(s)	(istream_line(&((s)->istream)))
500
#endif /* defined (FS_FAST) */
507
#endif /* defined (FS_FAST) */
501
 
508
 
502
#ifdef FS_FAST
509
#ifdef FS_FAST
503
#undef c_lexer_get_terminal
510
#undef c_lexer_get_terminal
504
#endif /* defined (FS_FAST) */
511
#endif /* defined (FS_FAST) */
505
CTokenT
512
CTokenT
506
c_lexer_get_terminal PROTO_N ((stream))
513
c_lexer_get_terminal(CLexerStreamP stream)
507
		     PROTO_T (CLexerStreamP stream)
-
 
508
{
514
{
509
    return (stream->token.t);
515
    return(stream->token.t);
510
}
516
}
511
#ifdef FS_FAST
517
#ifdef FS_FAST
512
#define c_lexer_get_terminal(s) ((s)->token.t)
518
#define c_lexer_get_terminal(s)	((s)->token.t)
513
#endif /* defined (FS_FAST) */
519
#endif /* defined (FS_FAST) */
514
 
520
 
515
void
521
void
516
c_lexer_next_token PROTO_N ((stream))
522
c_lexer_next_token(CLexerStreamP stream)
517
		   PROTO_T (CLexerStreamP stream)
-
 
518
{
523
{
519
    IStreamP istream = &(stream->istream);
524
    IStreamP istream = &(stream->istream);
520
    CLexT    token;
525
    CLexT    token;
521
    char     c;
526
    char     c;
522
 
527
 
523
  retry:
528
  retry:
524
    switch (c = c_lexer_skip_white_space (istream)) {
529
    switch (c = c_lexer_skip_white_space(istream)) {
525
      case '\0': /*FOR EOF*/
530
      case '\0': /*FOR EOF*/
526
	token.t = C_TOK_EOF;
531
	token.t = C_TOK_EOF;
527
	break;
532
	break;
528
      case '%':
533
      case '%':
529
	c_lexer_read_builtin (istream, &token);
534
	c_lexer_read_builtin(istream, &token);
530
	break;
535
	break;
531
      case ',':
536
      case ',':
532
	token.t = C_TOK_SEPARATOR;
537
	token.t = C_TOK_SEPARATOR;
533
	break;
538
	break;
534
      case ':':
539
      case ':':
Line 554... Line 559...
554
	break;
559
	break;
555
      case '&':
560
      case '&':
556
	token.t = C_TOK_REFERENCE;
561
	token.t = C_TOK_REFERENCE;
557
	break;
562
	break;
558
      case '@':
563
      case '@':
559
	c_lexer_read_code (istream, &token);
564
	c_lexer_read_code(istream, &token);
560
	break;
565
	break;
561
      case '-':
566
      case '-':
562
	if ((istream_peek_char (istream, &c)) && (c == '>')) {
567
	if ((istream_peek_char(istream, &c)) && (c == '>')) {
563
	    (void) istream_read_char (istream, &c);
568
	   (void)istream_read_char(istream, &c);
564
	    token.t = C_TOK_ARROW;
569
	    token.t = C_TOK_ARROW;
565
	    break;
570
	    break;
566
	}
571
	}
567
	c_lexer_read_identifier (istream, '-', &token);
572
	c_lexer_read_identifier(istream, '-', &token);
568
	break;
573
	break;
569
      default:
574
      default:
570
	if ((syntax_is_letter (c)) || (c == '_')) {
575
	if ((syntax_is_letter(c)) || (c == '_')) {
571
	    c_lexer_read_identifier (istream, c, &token);
576
	    c_lexer_read_identifier(istream, c, &token);
572
	} else {
577
	} else {
573
	    E_c_illegal_character (istream, c);
578
	    E_c_illegal_character(istream, c);
574
	    goto retry;
579
	    goto retry;
575
	}
580
	}
576
	break;
581
	break;
577
    }
582
    }
578
    stream->token = token;
583
    stream->token = token;
Line 580... Line 585...
580
 
585
 
581
#ifdef FS_FAST
586
#ifdef FS_FAST
582
#undef c_lexer_string_value
587
#undef c_lexer_string_value
583
#endif /* defined (FS_FAST) */
588
#endif /* defined (FS_FAST) */
584
NStringP
589
NStringP
585
c_lexer_string_value PROTO_N ((stream))
590
c_lexer_string_value(CLexerStreamP stream)
586
		     PROTO_T (CLexerStreamP stream)
-
 
587
{
591
{
588
    ASSERT ((stream->token.t == C_TOK_C_IDENTIFIER) ||
592
    ASSERT((stream->token.t == C_TOK_C_IDENTIFIER) ||
589
	    (stream->token.t == C_TOK_SID_IDENTIFIER));
593
	   (stream->token.t == C_TOK_SID_IDENTIFIER));
590
    return (&(stream->token.u.string));
594
    return(&(stream->token.u.string));
591
}
595
}
592
#ifdef FS_FAST
596
#ifdef FS_FAST
593
#define c_lexer_string_value(s) (&((s)->token.u.string))
597
#define c_lexer_string_value(s)	(&((s)->token.u.string))
594
#endif /* defined (FS_FAST) */
598
#endif /* defined (FS_FAST) */
595
 
599
 
596
#ifdef FS_FAST
600
#ifdef FS_FAST
597
#undef c_lexer_code_value
601
#undef c_lexer_code_value
598
#endif /* defined (FS_FAST) */
602
#endif /* defined (FS_FAST) */
599
CCodeP
603
CCodeP
600
c_lexer_code_value PROTO_N ((stream))
604
c_lexer_code_value(CLexerStreamP stream)
601
		   PROTO_T (CLexerStreamP stream)
-
 
602
{
605
{
603
    ASSERT (stream->token.t == C_TOK_CODE);
606
    ASSERT(stream->token.t == C_TOK_CODE);
604
    return (stream->token.u.code);
607
    return(stream->token.u.code);
605
}
608
}
606
#ifdef FS_FAST
609
#ifdef FS_FAST
607
#define c_lexer_code_value(s) ((s)->token.u.code)
610
#define c_lexer_code_value(s)	((s)->token.u.code)
608
#endif /* defined (FS_FAST) */
611
#endif /* defined (FS_FAST) */
609
 
612
 
610
void
613
void
611
c_lexer_save_terminal PROTO_N ((stream, error_terminal))
614
c_lexer_save_terminal(CLexerStreamP stream, CTokenT error_terminal)
612
		      PROTO_T (CLexerStreamP stream X
-
 
613
			       CTokenT       error_terminal)
-
 
614
{
615
{
615
    ASSERT (stream->token.t != error_terminal);
616
    ASSERT(stream->token.t != error_terminal);
616
    stream->saved_terminal = stream->token.t;
617
    stream->saved_terminal = stream->token.t;
617
    stream->token.t        = error_terminal;
618
    stream->token.t        = error_terminal;
618
}
619
}
619
 
620
 
620
void
621
void
621
c_lexer_restore_terminal PROTO_N ((stream))
622
c_lexer_restore_terminal(CLexerStreamP stream)
622
			 PROTO_T (CLexerStreamP stream)
-
 
623
{
623
{
624
    stream->token.t = stream->saved_terminal;
624
    stream->token.t = stream->saved_terminal;
625
}
625
}
626

626

627
/*
627
/*