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 40... Line 70...
40
 
70
 
41
    This variable gives the main output file.  out is used within this file
71
    This variable gives the main output file.  out is used within this file
42
    as a shorthand for lex_output.
72
    as a shorthand for lex_output.
43
*/
73
*/
44
 
74
 
45
FILE *lex_output ;
75
FILE *lex_output;
46
#define out lex_output
76
#define out lex_output
47
 
77
 
48
 
78
 
49
/*
79
/*
50
    OUTPUT INDENTATION
80
    OUTPUT INDENTATION
51
 
81
 
52
    This routine outputs an indentation of d.
82
    This routine outputs an indentation of d.
53
*/
83
*/
54
 
84
 
55
static void output_indent
85
static void
56
    PROTO_N ( ( d ) )
-
 
57
    PROTO_T ( int d )
86
output_indent(int d)
58
{
87
{
59
    int n = 4 * d ;
88
    int n = 4 * d;
60
    for ( ; n >= 8 ; n -= 8 ) fputc_v ( '\t', out ) ;
89
    for (; n >= 8; n -= 8)fputc_v('\t', out);
61
    for ( ; n ; n-- ) fputc_v ( ' ', out ) ;
90
    for (; n; n--)fputc_v(' ', out);
62
    return ;
91
    return;
63
}
92
}
64
 
93
 
65
 
94
 
66
/*
95
/*
67
    FIND A CHARACTER LITERAL
96
    FIND A CHARACTER LITERAL
68
 
97
 
69
    This routine finds the character literal corresponding to c.
98
    This routine finds the character literal corresponding to c.
70
*/
99
*/
71
 
100
 
72
static char *char_lit
101
static char *
73
    PROTO_N ( ( c ) )
-
 
74
    PROTO_T ( letter c )
102
char_lit(letter c)
75
{
103
{
76
    static char buff [10] ;
104
    static char buff [10];
77
    switch ( c ) {
105
    switch (c) {
78
	case '\n' : return ( "'\\n'" ) ;
106
	case '\n': return("'\\n'");
79
	case '\t' : return ( "'\\t'" ) ;
107
	case '\t': return("'\\t'");
80
	case '\v' : return ( "'\\v'" ) ;
108
	case '\v': return("'\\v'");
81
	case '\f' : return ( "'\\f'" ) ;
109
	case '\f': return("'\\f'");
82
	case '\\' : return ( "'\\\\'" ) ;
110
	case '\\': return("'\\\\'");
83
	case '\'' : return ( "'\\''" ) ;
111
	case '\'': return("'\\''");
84
    }
112
    }
85
    if ( c == EOF_LETTER ) return ( "LEX_EOF" ) ;
113
    if (c == EOF_LETTER) return("LEX_EOF");
86
    if ( c > 127 ) return ( "'?'" ) ;
114
    if (c > 127) return("'?'");
87
    sprintf_v ( buff, "'%c'", ( char ) c ) ;
115
    sprintf_v(buff, "'%c'",(char)c);
88
    return ( buff ) ;
116
    return(buff);
89
}
117
}
90
 
118
 
91
 
119
 
92
/*
120
/*
93
    OUTPUT OPTIONS
121
    OUTPUT OPTIONS
Line 95... Line 123...
95
    The flag in_pre_pass is used to indicate the preliminary pass to
123
    The flag in_pre_pass is used to indicate the preliminary pass to
96
    output_pass.  read_name gives the name of the character reading
124
    output_pass.  read_name gives the name of the character reading
97
    function used in the output routines.
125
    function used in the output routines.
98
*/
126
*/
99
 
127
 
100
static int in_pre_pass = 0 ;
128
static int in_pre_pass = 0;
101
static char *read_name = "read_char" ;
129
static char *read_name = "read_char";
102
 
130
 
103
 
131
 
104
/*
132
/*
105
    OUTPUT PASS INFORMATION
133
    OUTPUT PASS INFORMATION
106
 
134
 
107
    This routine outputs code for the lexical pass indicated by p.  n
135
    This routine outputs code for the lexical pass indicated by p.  n
108
    gives the depth of recursion and d gives the indentation.
136
    gives the depth of recursion and d gives the indentation.
109
*/
137
*/
110
 
138
 
111
static int output_pass
139
static int
112
    PROTO_N ( ( p, n, d ) )
-
 
113
    PROTO_T ( character *p X int n X int d )
140
output_pass(character *p, int n, int d)
114
{
141
{
115
    character *q ;
142
    character *q;
116
    int cases = 0 ;
143
    int cases = 0;
117
    int classes = 0 ;
144
    int classes = 0;
118
    char *ret = NULL ;
145
    char *ret = NULL;
119
    char *args = NULL ;
146
    char *args = NULL;
120
    char *cond = NULL ;
147
    char *cond = NULL;
121
 
148
 
122
    /* First pass */
149
    /* First pass */
123
    for ( q = p->next ; q != NULL ; q = q->opt ) {
150
    for (q = p->next; q != NULL; q = q->opt) {
124
	letter c = q->ch ;
151
	letter c = q->ch;
125
	if ( c == LAST_LETTER ) {
152
	if (c == LAST_LETTER) {
126
	    ret = q->defn ;
153
	    ret = q->defn;
127
	    args = q->args ;
154
	    args = q->args;
128
	    cond = q->cond ;
155
	    cond = q->cond;
129
	} else if ( c <= SIMPLE_LETTER ) {
156
	} else if (c <= SIMPLE_LETTER) {
130
	    cases++ ;
157
	    cases++;
131
	} else {
158
	} else {
132
	    classes++ ;
159
	    classes++;
133
	}
160
	}
134
    }
161
    }
135
 
162
 
136
    /* Deal with cases */
163
    /* Deal with cases */
137
    if ( cases || classes ) {
164
    if (cases || classes) {
138
	int w1 = ( n == 0 && !in_pre_pass ) ;
165
	int w1 = (n == 0 && !in_pre_pass);
139
	int w2 = ( n == 0 && in_pre_pass ) ;
166
	int w2 = (n == 0 && in_pre_pass);
140
	output_indent ( d ) ;
167
	output_indent(d);
141
	fprintf_v ( out, "int c%d = %s ()", n, read_name ) ;
168
	fprintf_v(out, "int c%d = %s()", n, read_name);
142
	if ( classes || w1 ) fprintf_v ( out, ", t%d", n ) ;
169
	if (classes || w1)fprintf_v(out, ", t%d", n);
143
	fputs_v ( " ;\n", out ) ;
170
	fputs_v(";\n", out);
144
	if ( w1 ) {
171
	if (w1) {
145
	    output_indent ( d ) ;
172
	    output_indent(d);
146
	    fputs_v ( "t0 = lookup_char ( c0 ) ;\n", out ) ;
173
	    fputs_v("t0 = lookup_char(c0);\n", out);
147
	    output_indent ( d ) ;
174
	    output_indent(d);
148
	    fputs_v ( "if ( is_white ( t0 ) ) goto start ;\n", out ) ;
175
	    fputs_v("if (is_white(t0)) goto start;\n", out);
149
	}
176
	}
150
	if ( w2 ) {
177
	if (w2) {
151
	    output_indent ( d ) ;
178
	    output_indent(d);
152
	    fputs_v ( "restart : {\n", out ) ;
179
	    fputs_v("restart: {\n", out);
153
	    d++ ;
180
	    d++;
154
	}
181
	}
155
 
182
 
156
	if ( cases > 4 ) {
183
	if (cases > 4) {
157
	    /* Small number of cases */
184
	    /* Small number of cases */
158
	    output_indent ( d ) ;
185
	    output_indent(d);
159
	    fprintf_v ( out, "switch ( c%d ) {\n", n ) ;
186
	    fprintf_v(out, "switch (c%d) {\n", n);
160
	    for ( q = p->next ; q != NULL ; q = q->opt ) {
187
	    for (q = p->next; q != NULL; q = q->opt) {
161
		letter c = q->ch ;
188
		letter c = q->ch;
162
		if ( c != LAST_LETTER && c <= SIMPLE_LETTER ) {
189
		if (c != LAST_LETTER && c <= SIMPLE_LETTER) {
163
		    output_indent ( d + 1 ) ;
190
		    output_indent(d + 1);
164
		    fprintf_v ( out, "case %s : {\n", char_lit ( c ) ) ;
191
		    fprintf_v(out, "case %s: {\n", char_lit(c));
165
		    if ( output_pass ( q, n + 1, d + 2 ) == 0 ) {
192
		    if (output_pass(q, n + 1, d + 2) == 0) {
166
			output_indent ( d + 2 ) ;
193
			output_indent(d + 2);
167
			fputs_v ( "break ;\n", out ) ;
194
			fputs_v("break;\n", out);
168
		    }
195
		    }
169
		    output_indent ( d + 1 ) ;
196
		    output_indent(d + 1);
170
		    fputs_v ( "}\n", out ) ;
197
		    fputs_v("}\n", out);
171
		}
198
		}
172
	    }
199
	    }
173
	    output_indent ( d ) ;
200
	    output_indent(d);
174
	    fputs_v ( "}\n", out ) ;
201
	    fputs_v("}\n", out);
175
	} else {
202
	} else {
176
	    /* Large number of cases */
203
	    /* Large number of cases */
177
	    int started = 0 ;
204
	    int started = 0;
178
	    for ( q = p->next ; q != NULL ; q = q->opt ) {
205
	    for (q = p->next; q != NULL; q = q->opt) {
179
		letter c = q->ch ;
206
		letter c = q->ch;
180
		if ( c != LAST_LETTER && c <= SIMPLE_LETTER ) {
207
		if (c != LAST_LETTER && c <= SIMPLE_LETTER) {
181
		    output_indent ( d ) ;
208
		    output_indent(d);
182
		    if ( started ) fputs_v ( "} else ", out ) ;
209
		    if (started)fputs_v("} else ", out);
183
		    fprintf_v ( out, "if ( c%d == %s ) {\n",
210
		    fprintf_v(out, "if (c%d == %s) {\n",
184
				n, char_lit ( c ) ) ;
211
				n, char_lit(c));
185
		    IGNORE output_pass ( q, n + 1, d + 1 ) ;
212
		    IGNORE output_pass(q, n + 1, d + 1);
186
		    started = 1 ;
213
		    started = 1;
187
		}
214
		}
188
	    }
215
	    }
189
	    if ( started ) {
216
	    if (started) {
190
		output_indent ( d ) ;
217
		output_indent(d);
191
		fputs_v ( "}\n", out ) ;
218
		fputs_v("}\n", out);
192
	    }
219
	    }
193
	}
220
	}
194
 
221
 
195
	if ( classes ) {
222
	if (classes) {
196
	    /* Complex cases */
223
	    /* Complex cases */
197
	    int started = 0 ;
224
	    int started = 0;
198
	    if ( !w1 ) {
225
	    if (!w1) {
199
		output_indent ( d ) ;
226
		output_indent(d);
200
		fprintf_v ( out, "t%d = lookup_char ( c%d ) ;\n", n, n ) ;
227
		fprintf_v(out, "t%d = lookup_char(c%d);\n", n, n);
201
	    }
228
	    }
202
	    for ( q = p->next ; q != NULL ; q = q->opt ) {
229
	    for (q = p->next; q != NULL; q = q->opt) {
203
		letter c = q->ch ;
230
		letter c = q->ch;
204
		if ( c != LAST_LETTER && c > SIMPLE_LETTER ) {
231
		if (c != LAST_LETTER && c > SIMPLE_LETTER) {
205
		    char *gnm ;
232
		    char *gnm;
206
		    if ( c == WHITE_LETTER ) {
233
		    if (c == WHITE_LETTER) {
207
			gnm = "white" ;
234
			gnm = "white";
208
		    } else {
235
		    } else {
209
			int g = ( int ) ( c - GROUP_LETTER ) ;
236
			int g = (int)(c - GROUP_LETTER);
210
			gnm = groups [g].name ;
237
			gnm = groups [g].name;
211
		    }
238
		    }
212
		    output_indent ( d ) ;
239
		    output_indent(d);
213
		    if ( started ) fputs_v ( "} else ", out ) ;
240
		    if (started)fputs_v("} else ", out);
214
		    fprintf_v ( out, "if ( is_%s ( t%d ) ) {\n", gnm, n ) ;
241
		    fprintf_v(out, "if (is_%s(t%d)) {\n", gnm, n);
215
		    IGNORE output_pass ( q, n + 1, d + 1 ) ;
242
		    IGNORE output_pass(q, n + 1, d + 1);
216
		    started = 1 ;
243
		    started = 1;
217
		}
244
		}
218
	    }
245
	    }
219
	    output_indent ( d ) ;
246
	    output_indent(d);
220
	    fputs_v ( "}\n", out ) ;
247
	    fputs_v("}\n", out);
221
	}
248
	}
222
	if ( w2 ) {
249
	if (w2) {
223
	    d-- ;
250
	    d--;
224
	    output_indent ( d ) ;
251
	    output_indent(d);
225
	    fputs_v ( "}\n", out ) ;
252
	    fputs_v("}\n", out);
226
	}
253
	}
227
	if ( n ) {
254
	if (n) {
228
	    output_indent ( d ) ;
255
	    output_indent(d);
229
	    fprintf_v ( out, "unread_char ( c%d ) ;\n", n ) ;
256
	    fprintf_v(out, "unread_char(c%d);\n", n);
230
	}
257
	}
231
    }
258
    }
232
 
259
 
233
    /* Deal with return */
260
    /* Deal with return */
234
    if ( ret ) {
261
    if (ret) {
235
	if ( in_pre_pass ) {
262
	if (in_pre_pass) {
236
	    int m = *ret ;
263
	    int m = *ret;
237
	    if ( m ) {
264
	    if (m) {
238
		char *str ;
265
		char *str;
239
		if ( m == '\\' ) {
266
		if (m == '\\') {
240
		    str = char_lit ( find_escape ( ret [1] ) ) ;
267
		    str = char_lit(find_escape(ret [1]));
241
		    m = ret [2] ;
268
		    m = ret [2];
242
		} else {
269
		} else {
243
		    str = char_lit ( ( letter ) m ) ;
270
		    str = char_lit((letter)m);
244
		    m = ret [1] ;
271
		    m = ret [1];
245
		}
272
		}
246
		if ( m ) {
273
		if (m) {
247
		    error ( ERROR_SERIOUS, "Bad mapping string, '%s'", ret ) ;
274
		    error(ERROR_SERIOUS, "Bad mapping string, '%s'", ret);
248
		}
275
		}
249
		if ( cond ) {
276
		if (cond) {
250
		    output_indent ( d ) ;
277
		    output_indent(d);
251
		    fprintf_v ( out, "if ( %s ) {\n", cond ) ;
278
		    fprintf_v(out, "if (%s) {\n", cond);
252
		    output_indent ( d + 1 ) ;
279
		    output_indent(d + 1);
253
		    fprintf_v ( out, "c0 = %s ;\n", str ) ;
280
		    fprintf_v(out, "c0 = %s;\n", str);
254
		    output_indent ( d + 1 ) ;
281
		    output_indent(d + 1);
255
		    fputs_v ( "goto restart ;\n", out ) ;
282
		    fputs_v("goto restart;\n", out);
256
		    output_indent ( d ) ;
283
		    output_indent(d);
257
		    fputs_v ( "}\n", out ) ;
284
		    fputs_v("}\n", out);
258
		} else {
285
		} else {
259
		    output_indent ( d ) ;
286
		    output_indent(d);
260
		    fprintf_v ( out, "c0 = %s ;\n", str ) ;
287
		    fprintf_v(out, "c0 = %s;\n", str);
261
		    output_indent ( d ) ;
288
		    output_indent(d);
262
		    fputs_v ( "goto restart ;\n", out ) ;
289
		    fputs_v("goto restart;\n", out);
263
		}
290
		}
264
	    } else {
291
	    } else {
265
		output_indent ( d ) ;
292
		output_indent(d);
266
		if ( cond ) fprintf_v ( out, "if ( %s ) ", cond ) ;
293
		if (cond)fprintf_v(out, "if (%s) ", cond);
267
		fputs_v ( "goto start ;\n", out ) ;
294
		fputs_v("goto start;\n", out);
268
	    }
295
	    }
269
	} else {
296
	} else {
270
	    output_indent ( d ) ;
297
	    output_indent(d);
271
	    if ( cond ) fprintf_v ( out, "if ( %s ) ", cond ) ;
298
	    if (cond)fprintf_v(out, "if (%s) ", cond);
272
	    fprintf_v ( out, "return ( %s", ret ) ;
299
	    fprintf_v(out, "return(%s", ret);
273
	    if ( args ) {
300
	    if (args) {
274
		int i ;
301
		int i;
275
		fputs_v ( " ( c0", out ) ;
302
		fputs_v("(c0", out);
276
		for ( i = 1 ; i < n ; i++ ) fprintf_v ( out, ", c%d", i ) ;
303
		for (i = 1; i < n; i++)fprintf_v(out, ", c%d", i);
277
		fputs_v ( " )", out ) ;
304
		fputs_v(")", out);
278
	    }
305
	    }
279
	    fputs_v ( " ) ;\n", out ) ;
306
	    fputs_v(");\n", out);
280
	}
307
	}
281
    }
308
    }
282
    return ( ( ret && ( cond == NULL ) ) ? 1 : 0 ) ;
309
    return((ret && (cond == NULL))? 1 : 0);
283
}
310
}
284
 
311
 
285
 
312
 
286
/*
313
/*
287
    OUTPUT INITIAL COMMENT
314
    OUTPUT INITIAL COMMENT
288
 
315
 
289
    This routine outputs a comment stating that the file is automatically
316
    This routine outputs a comment stating that the file is automatically
290
    generated.
317
    generated.
291
*/
318
*/
292
 
319
 
293
static void output_comment
320
static void
294
    PROTO_Z ()
321
output_comment(void)
295
{
322
{
296
    if ( first_comment ) {
323
    if (first_comment) {
297
	/* Print copyright comment, if present */
324
	/* Print copyright comment, if present */
298
	fprintf_v ( out, "%s\n\n", first_comment ) ;
325
	fprintf_v(out, "%s\n\n", first_comment);
299
    }
326
    }
300
    fputs_v ( "/*\n    AUTOMATICALLY GENERATED", out ) ;
327
    fputs_v ( "/*\n *  AUTOMATICALLY GENERATED", out ) ;
301
    fprintf_v ( out, " BY %s VERSION %s", progname, progvers ) ;
328
    fprintf_v ( out, " BY %s VERSION %s", progname, progvers ) ;
302
    fputs_v ( "\n*/\n\n\n", out ) ;
329
    fputs_v ( "\n */\n\n\n", out ) ;
303
    return ;
330
    return;
304
}
331
}
305
 
332
 
306
 
333
 
307
/*
334
/*
308
    MAIN OUTPUT ROUTINE
335
    MAIN OUTPUT ROUTINE
309
 
336
 
310
    This routine is the entry point for the main output routine.
337
    This routine is the entry point for the main output routine.
311
*/
338
*/
312
 
339
 
313
void output_all
340
void
314
    PROTO_Z ()
341
output_all(void)
315
{
342
{
316
    int c, n ;
343
    int c, n;
317
 
344
 
318
    /* Initial comment */
345
    /* Initial comment */
319
    output_comment () ;
346
    output_comment();
320
 
347
 
321
    /* Character look-up table */
348
    /* Character look-up table */
322
    fputs_v ( "/* LOOKUP TABLE */\n\n", out ) ;
349
    fputs_v ( "/* LOOKUP TABLE */\n\n", out ) ;
323
    fprintf_v ( out, "static unsigned %s lookup_tab [257] = {\n",
350
    fprintf_v(out, "static unsigned %s lookup_tab[257] = {\n",
324
		( no_groups >= 8 ? "short" : "char" ) ) ;
351
		(no_groups >= 8 ? "short" : "char"));
325
    for ( c = 0 ; c <= 256 ; c++ ) {
352
    for (c = 0; c <= 256; c++) {
326
	unsigned int m = 0 ;
353
	unsigned int m = 0;
327
	letter a = ( c == 256 ? EOF_LETTER : ( letter ) c ) ;
354
	letter a = (c == 256 ? EOF_LETTER :(letter)c);
328
	if ( in_group ( white_space, a ) ) m = 1 ;
355
	if (in_group(white_space, a))m = 1;
329
	for ( n = 0 ; n < no_groups ; n++ ) {
356
	for (n = 0; n < no_groups; n++) {
330
	    if ( in_group ( groups [n].defn, a ) ) {
357
	    if (in_group(groups [n].defn, a)) {
331
		m |= ( unsigned int ) ( 1 << ( n + 1 ) ) ;
358
		m |= (unsigned int)(1 << (n + 1));
332
	    }
359
	    }
333
	}
360
	}
334
	if ( ( c % 8 ) == 0 ) fputs_v ( "    ", out ) ;
361
	if ((c % 8) == 0)fputs_v("    ", out);
335
	fprintf_v ( out, "0x%04x", m ) ;
362
	fprintf_v(out, "0x%04x", m);
336
	if ( c != 256 ) {
363
	if (c != 256) {
337
	    if ( ( c % 8 ) == 7 ) {
364
	    if ((c % 8) == 7) {
338
		fputs_v ( ",\n", out ) ;
365
		fputs_v(",\n", out);
339
	    } else {
366
	    } else {
340
		fputs_v ( ", ", out ) ;
367
		fputs_v(", ", out);
341
	    }
368
	    }
342
	}
369
	}
343
    }
370
    }
344
    fputs_v ( "\n} ;\n\n", out ) ;
371
    fputs_v("\n};\n\n", out);
345
 
372
 
346
    /* Macros for accessing table */
373
    /* Macros for accessing table */
347
    fputs_v ( "#ifndef LEX_EOF\n", out ) ;
374
    fputs_v("#ifndef LEX_EOF\n", out);
348
    fputs_v ( "#define LEX_EOF\t\t\t256\n", out ) ;
375
    fputs_v("#define LEX_EOF\t\t256\n", out);
349
    fputs_v ( "#endif\n\n", out ) ;
376
    fputs_v("#endif\n\n", out);
350
    fputs_v ( "#define lookup_char( C )\t", out ) ;
377
    fputs_v("#define lookup_char(C)\t", out);
351
    fputs_v ( "( ( int ) lookup_tab [ ( C ) ] )\n", out ) ;
378
    fputs_v("((int)lookup_tab[(C)])\n", out);
352
    fputs_v ( "#define is_white( T )\t\t( ( T ) & 0x0001 )\n", out ) ;
379
    fputs_v("#define is_white(T)\t((T) & 0x0001)\n", out);
353
    for ( n = 0 ; n < no_groups ; n++ ) {
380
    for (n = 0; n < no_groups; n++) {
354
	char *gnm = groups [n].name ;
381
	char *gnm = groups [n].name;
355
	unsigned int m = ( unsigned int ) ( 1 << ( n + 1 ) ) ;
382
	unsigned int m = (unsigned int)(1 << (n + 1));
356
	fprintf_v ( out, "#define is_%s( T )\t", gnm ) ;
383
	fprintf_v(out, "#define is_%s(T)\t", gnm);
357
	if ( ( int ) strlen ( gnm ) < 8 ) fputc_v ( '\t', out ) ;
384
	/*if ((int)strlen(gnm) < 8)fputc_v('\t', out);*/
358
	fprintf_v ( out, "( ( T ) & 0x%04x )\n", m ) ;
385
	fprintf_v(out, "((T) & 0x%04x)\n", m);
359
    }
386
    }
360
    fputs_v ( "\n", out ) ;
387
    fputs_v("\n\n", out);
361
    fputs_v ( "#ifndef PROTO_Z\n", out ) ;
-
 
362
    fputs_v ( "#ifdef __STDC__\n", out ) ;
-
 
363
    fputs_v ( "#define PROTO_Z()\t\t( void )\n", out ) ;
-
 
364
    fputs_v ( "#else\n", out ) ;
-
 
365
    fputs_v ( "#define PROTO_Z()\t\t()\n", out ) ;
-
 
366
    fputs_v ( "#endif\n", out ) ;
-
 
367
    fputs_v ( "#endif\n\n\n", out ) ;
-
 
368
 
388
 
369
    /* Lexical pre-pass */
389
    /* Lexical pre-pass */
370
    if ( pre_pass->next ) {
390
    if (pre_pass->next) {
371
	in_pre_pass = 1 ;
391
	in_pre_pass = 1;
372
	fputs_v ( "/* PRE-PASS ANALYSER */\n\n", out ) ;
392
	fputs_v ( "/* PRE-PASS ANALYSER */\n\n", out ) ;
373
	fputs_v ( "static int read_char_aux PROTO_Z ()\n", out ) ;
393
	fputs_v("static int read_char_aux(void)\n", out);
374
	fputs_v ( "{\n", out ) ;
394
	fputs_v("{\n", out);
375
	fputs_v ( "    start : {\n", out ) ;
395
	fputs_v("    start: {\n", out);
376
	IGNORE output_pass ( pre_pass, 0, 2 ) ;
396
	IGNORE output_pass(pre_pass, 0, 2);
377
	fputs_v ( "\treturn ( c0 ) ;\n", out ) ;
397
	fputs_v("\treturn(c0);\n", out);
378
	fputs_v ( "    }\n", out ) ;
398
	fputs_v("    }\n", out);
379
	fputs_v ( "}\n\n\n", out ) ;
399
	fputs_v("}\n\n\n", out);
380
	read_name = "read_char_aux" ;
400
	read_name = "read_char_aux";
381
    }
401
    }
382
 
402
 
383
    /* Main pass */
403
    /* Main pass */
384
    in_pre_pass = 0 ;
404
    in_pre_pass = 0;
385
    fputs_v ( "/* MAIN PASS ANALYSER */\n\n", out ) ;
405
    fputs_v ( "/* MAIN PASS ANALYSER */\n\n", out ) ;
386
    fputs_v ( "int read_token PROTO_Z ()\n", out ) ;
406
    fputs_v("int\nread_token(void)\n", out);
387
    fputs_v ( "{\n", out ) ;
407
    fputs_v("{\n", out);
388
    fputs_v ( "    start : {\n", out ) ;
408
    fputs_v("    start: {\n", out);
389
    IGNORE output_pass ( main_pass, 0, 2 ) ;
409
    IGNORE output_pass(main_pass, 0, 2);
390
    fputs_v ( "\treturn ( unknown_token ( c0 ) ) ;\n", out ) ;
410
    fputs_v("\treturn(unknown_token(c0));\n", out);
391
    fputs_v ( "    }\n", out ) ;
411
    fputs_v("    }\n", out);
392
    fputs_v ( "}\n", out ) ;
412
    fputs_v("}\n", out);
393
    return ;
413
    return;
394
}
414
}
395
 
415
 
396
 
416
 
397
/*
417
/*
398
    OUTPUT CODE FOR A SINGLE KEYWORD
418
    OUTPUT CODE FOR A SINGLE KEYWORD
399
 
419
 
400
    This routine outputs code for the keyword p.
420
    This routine outputs code for the keyword p.
401
*/
421
*/
402
 
422
 
403
static void output_word
423
static void
404
    PROTO_N ( ( p ) )
-
 
405
    PROTO_T ( keyword *p )
424
output_word(keyword *p)
406
{
425
{
407
    fprintf_v ( out, "MAKE_KEYWORD ( \"%s\", %s", p->name, p->defn ) ;
426
    fprintf_v(out, "MAKE_KEYWORD(\"%s\", %s", p->name, p->defn);
408
    if ( p->args ) fputs_v ( " ()", out ) ;
427
    if (p->args)fputs_v("()", out);
409
    fputs_v ( " ) ;\n", out ) ;
428
    fputs_v(");\n", out);
410
    p->done = 1 ;
429
    p->done = 1;
411
    return ;
430
    return;
412
}
431
}
413
 
432
 
414
 
433
 
415
/*
434
/*
416
    KEYWORD OUTPUT ROUTINE
435
    KEYWORD OUTPUT ROUTINE
417
 
436
 
418
    This routine outputs code to generate all keywords.
437
    This routine outputs code to generate all keywords.
419
*/
438
*/
420
 
439
 
421
void output_keyword
440
void
422
    PROTO_Z ()
441
output_keyword(void)
423
{
442
{
424
    keyword *p, *q ;
443
    keyword *p, *q;
425
    output_comment () ;
444
    output_comment();
426
    fputs_v ( "/* KEYWORDS */\n\n", out ) ;
445
    fputs_v ( "/* KEYWORDS */\n\n", out ) ;
427
    for ( p = keywords ; p != NULL ; p = p->next ) {
446
    for (p = keywords; p != NULL; p = p->next) {
428
	if ( p->done == 0 ) {
447
	if (p->done == 0) {
429
	    char *cond = p->cond ;
448
	    char *cond = p->cond;
430
	    if ( cond ) {
449
	    if (cond) {
431
		fprintf_v ( out, "if ( %s ) {\n    ", cond ) ;
450
		fprintf_v(out, "if (%s) {\n    ", cond);
432
		output_word ( p ) ;
451
		output_word(p);
433
		for ( q = p->next ; q != NULL ; q = q->next ) {
452
		for (q = p->next; q != NULL; q = q->next) {
434
		    if ( q->cond && streq ( q->cond, cond ) ) {
453
		    if (q->cond && streq(q->cond, cond)) {
435
			fputs_v ( "    ", out ) ;
454
			fputs_v("    ", out);
436
			output_word ( q ) ;
455
			output_word(q);
437
		    }
456
		    }
438
		}
457
		}
439
		fputs_v ( "}\n", out ) ;
458
		fputs_v("}\n", out);
440
	    } else {
459
	    } else {
441
		output_word ( p ) ;
460
		output_word(p);
442
		for ( q = p->next ; q != NULL ; q = q->next ) {
461
		for (q = p->next; q != NULL; q = q->next) {
443
		    if ( q->cond == NULL ) output_word ( q ) ;
462
		    if (q->cond == NULL)output_word(q);
444
		}
463
		}
445
	    }
464
	    }
446
	}
465
	}
447
    }
466
    }
448
    return ;
467
    return;
449
}
468
}