Fixed a typo in the ktrace man page. Added a check for a signal SIGSYS
[unix-history] / usr.bin / lex / scan.l
CommitLineData
7d684d5e
NW
1
2/* scan.l - scanner for flex input */
3
4%{
15637ed4
RG
5/*-
6 * Copyright (c) 1990 The Regents of the University of California.
7 * All rights reserved.
8 *
9 * This code is derived from software contributed to Berkeley by
7d684d5e 10 * Vern Paxson.
15637ed4 11 *
7d684d5e 12 * The United States Government has rights in this work pursuant
15637ed4
RG
13 * to contract no. DE-AC03-76SF00098 between the United States
14 * Department of Energy and the University of California.
15 *
7d684d5e
NW
16 * Redistribution and use in source and binary forms are permitted provided
17 * that: (1) source distributions retain this entire copyright notice and
18 * comment, and (2) distributions including binaries display the following
19 * acknowledgement: ``This product includes software developed by the
20 * University of California, Berkeley and its contributors'' in the
21 * documentation or other materials provided with the distribution and in
22 * all advertising materials mentioning features or use of this software.
23 * Neither the name of the University nor the names of its contributors may
24 * be used to endorse or promote products derived from this software without
25 * specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
27 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
28 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15637ed4
RG
29 */
30
7d684d5e
NW
31#ifndef lint
32static char rcsid[] =
33 "@(#) $Header: /usr/fsys/odin/a/vern/flex/RCS/scan.l,v 2.9 90/06/27 23:48:34 vern Exp $ (LBL)";
34#endif
15637ed4 35
15637ed4
RG
36#undef yywrap
37
38#include "flexdef.h"
39#include "parse.h"
40
15637ed4
RG
41#define ACTION_ECHO fprintf( temp_action_file, "%s", yytext )
42#define MARK_END_OF_PROLOG fprintf( temp_action_file, "%%%% end of prolog\n" );
43
44#undef YY_DECL
45#define YY_DECL \
46 int flexscan()
47
48#define RETURNCHAR \
49 yylval = yytext[0]; \
50 return ( CHAR );
51
52#define RETURNNAME \
53 (void) strcpy( nmstr, (char *) yytext ); \
54 return ( NAME );
55
56#define PUT_BACK_STRING(str, start) \
57 for ( i = strlen( (char *) (str) ) - 1; i >= start; --i ) \
58 unput((str)[i])
59
60#define CHECK_REJECT(str) \
61 if ( all_upper( str ) ) \
62 reject = true;
63
64#define CHECK_YYMORE(str) \
65 if ( all_lower( str ) ) \
66 yymore_used = true;
67%}
68
69%x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
70%x FIRSTCCL CCL ACTION RECOVER BRACEERROR C_COMMENT ACTION_COMMENT
71%x ACTION_STRING PERCENT_BRACE_ACTION USED_LIST CODEBLOCK_2 XLATION
72
73WS [ \t\f]+
74OPTWS [ \t\f]*
75NOT_WS [^ \t\f\n]
76
77NAME [a-z_][a-z_0-9-]*
78NOT_NAME [^a-z_\n]+
79
80SCNAME {NAME}
81
82ESCSEQ \\([^\n]|[0-9]{1,3}|x[0-9a-f]{1,2})
83
84%%
85 static int bracelevel, didadef;
86 int i, indented_code, checking_used, new_xlation;
87 int doing_codeblock = false;
88 Char nmdef[MAXLINE], myesc();
89
90^{WS} indented_code = true; BEGIN(CODEBLOCK);
91^#.*\n ++linenum; /* treat as a comment */
92^"/*" ECHO; BEGIN(C_COMMENT);
93^"%s"{NAME}? return ( SCDECL );
94^"%x"{NAME}? return ( XSCDECL );
95^"%{".*\n {
96 ++linenum;
97 line_directive_out( stdout );
98 indented_code = false;
99 BEGIN(CODEBLOCK);
100 }
101
102{WS} return ( WHITESPACE );
103
104^"%%".* {
105 sectnum = 2;
106 line_directive_out( stdout );
107 BEGIN(SECT2PROLOG);
108 return ( SECTEND );
109 }
110
111^"%used" {
112 pinpoint_message( "warning - %%used/%%unused have been deprecated" );
113 checking_used = REALLY_USED; BEGIN(USED_LIST);
114 }
115^"%unused" {
116 checking_used = REALLY_NOT_USED; BEGIN(USED_LIST);
117 pinpoint_message( "warning - %%used/%%unused have been deprecated" );
118 checking_used = REALLY_NOT_USED; BEGIN(USED_LIST);
119 }
120
121
7d684d5e 122^"%"[aeknopt]{WS}.*\n {
15637ed4
RG
123#ifdef NOTDEF
124 fprintf( stderr,
125 "old-style lex command at line %d ignored:\n\t%s",
126 linenum, yytext );
127#endif
128 ++linenum;
129 }
130
131^"%"[cr]{OPTWS} /* ignore old lex directive */
132
133%t{OPTWS}\n {
134 ++linenum;
135 xlation =
136 (int *) malloc( sizeof( int ) * (unsigned) csize );
137
138 if ( ! xlation )
139 flexfatal(
140 "dynamic memory failure building %t table" );
141
142 for ( i = 0; i < csize; ++i )
143 xlation[i] = 0;
144
145 num_xlations = 0;
146
147 BEGIN(XLATION);
148 }
149
150^"%"[^sxanpekotcru{}]{OPTWS} synerr( "unrecognized '%' directive" );
151
152^{NAME} {
153 (void) strcpy( nmstr, (char *) yytext );
154 didadef = false;
155 BEGIN(PICKUPDEF);
156 }
157
158{SCNAME} RETURNNAME;
159^{OPTWS}\n ++linenum; /* allows blank lines in section 1 */
160{OPTWS}\n ++linenum; return ( '\n' );
161. synerr( "illegal character" ); BEGIN(RECOVER);
162
163
164<C_COMMENT>"*/" ECHO; BEGIN(INITIAL);
165<C_COMMENT>"*/".*\n ++linenum; ECHO; BEGIN(INITIAL);
166<C_COMMENT>[^*\n]+ ECHO;
167<C_COMMENT>"*" ECHO;
168<C_COMMENT>\n ++linenum; ECHO;
169
170
171<CODEBLOCK>^"%}".*\n ++linenum; BEGIN(INITIAL);
172<CODEBLOCK>"reject" ECHO; CHECK_REJECT(yytext);
173<CODEBLOCK>"yymore" ECHO; CHECK_YYMORE(yytext);
174<CODEBLOCK>{NAME}|{NOT_NAME}|. ECHO;
175<CODEBLOCK>\n {
176 ++linenum;
177 ECHO;
178 if ( indented_code )
179 BEGIN(INITIAL);
180 }
181
182
183<PICKUPDEF>{WS} /* separates name and definition */
184
185<PICKUPDEF>{NOT_WS}.* {
186 (void) strcpy( (char *) nmdef, (char *) yytext );
187
188 for ( i = strlen( (char *) nmdef ) - 1;
189 i >= 0 &&
190 nmdef[i] == ' ' || nmdef[i] == '\t';
191 --i )
192 ;
193
194 nmdef[i + 1] = '\0';
195
196 ndinstal( nmstr, nmdef );
197 didadef = true;
198 }
199
200<PICKUPDEF>\n {
201 if ( ! didadef )
202 synerr( "incomplete name definition" );
203 BEGIN(INITIAL);
204 ++linenum;
205 }
206
207<RECOVER>.*\n ++linenum; BEGIN(INITIAL); RETURNNAME;
208
209
210<USED_LIST>\n ++linenum; BEGIN(INITIAL);
211<USED_LIST>{WS}
212<USED_LIST>"reject" {
213 if ( all_upper( yytext ) )
214 reject_really_used = checking_used;
215 else
216 synerr( "unrecognized %used/%unused construct" );
217 }
218<USED_LIST>"yymore" {
219 if ( all_lower( yytext ) )
220 yymore_really_used = checking_used;
221 else
222 synerr( "unrecognized %used/%unused construct" );
223 }
224<USED_LIST>{NOT_WS}+ synerr( "unrecognized %used/%unused construct" );
225
226
227<XLATION>"%t"{OPTWS}\n ++linenum; BEGIN(INITIAL);
228<XLATION>^{OPTWS}[0-9]+ ++num_xlations; new_xlation = true;
229<XLATION>^. synerr( "bad row in translation table" );
230<XLATION>{WS} /* ignore whitespace */
231
232<XLATION>{ESCSEQ} {
233 xlation[myesc( yytext )] =
234 (new_xlation ? num_xlations : -num_xlations);
235 new_xlation = false;
236 }
237<XLATION>. {
238 xlation[yytext[0]] =
239 (new_xlation ? num_xlations : -num_xlations);
240 new_xlation = false;
241 }
242
243<XLATION>\n ++linenum;
244
245
246<SECT2PROLOG>.*\n/{NOT_WS} {
247 ++linenum;
248 ACTION_ECHO;
249 MARK_END_OF_PROLOG;
250 BEGIN(SECT2);
251 }
252
253<SECT2PROLOG>.*\n ++linenum; ACTION_ECHO;
254
255<SECT2PROLOG><<EOF>> MARK_END_OF_PROLOG; yyterminate();
256
257<SECT2>^{OPTWS}\n ++linenum; /* allow blank lines in section 2 */
258
259<SECT2>^({WS}|"%{") {
260 indented_code = (yytext[0] != '%');
261 doing_codeblock = true;
262 bracelevel = 1;
263
264 if ( indented_code )
265 ACTION_ECHO;
266
267 BEGIN(CODEBLOCK_2);
268 }
269
270<SECT2>"<" BEGIN(SC); return ( '<' );
271<SECT2>^"^" return ( '^' );
272<SECT2>\" BEGIN(QUOTE); return ( '"' );
273<SECT2>"{"/[0-9] BEGIN(NUM); return ( '{' );
274<SECT2>"{"[^0-9\n][^}\n]* BEGIN(BRACEERROR);
275<SECT2>"$"/[ \t\n] return ( '$' );
276
277<SECT2>{WS}"%{" {
278 bracelevel = 1;
279 BEGIN(PERCENT_BRACE_ACTION);
280 return ( '\n' );
281 }
282<SECT2>{WS}"|".*\n continued_action = true; ++linenum; return ( '\n' );
283
284<SECT2>{WS} {
285 /* this rule is separate from the one below because
286 * otherwise we get variable trailing context, so
287 * we can't build the scanner using -{f,F}
288 */
289 bracelevel = 0;
290 continued_action = false;
291 BEGIN(ACTION);
292 return ( '\n' );
293 }
294
295<SECT2>{OPTWS}/\n {
296 bracelevel = 0;
297 continued_action = false;
298 BEGIN(ACTION);
299 return ( '\n' );
300 }
301
302<SECT2>^{OPTWS}\n ++linenum; return ( '\n' );
303
304<SECT2>"<<EOF>>" return ( EOF_OP );
305
306<SECT2>^"%%".* {
307 sectnum = 3;
308 BEGIN(SECT3);
309 return ( EOF ); /* to stop the parser */
310 }
311
312<SECT2>"["([^\\\]\n]|{ESCSEQ})+"]" {
313 int cclval;
314
315 (void) strcpy( nmstr, (char *) yytext );
316
317 /* check to see if we've already encountered this ccl */
318 if ( (cclval = ccllookup( (Char *) nmstr )) )
319 {
320 yylval = cclval;
321 ++cclreuse;
322 return ( PREVCCL );
323 }
324 else
325 {
326 /* we fudge a bit. We know that this ccl will
327 * soon be numbered as lastccl + 1 by cclinit
328 */
329 cclinstal( (Char *) nmstr, lastccl + 1 );
330
331 /* push back everything but the leading bracket
332 * so the ccl can be rescanned
333 */
334 PUT_BACK_STRING((Char *) nmstr, 1);
335
336 BEGIN(FIRSTCCL);
337 return ( '[' );
338 }
339 }
340
341<SECT2>"{"{NAME}"}" {
342 register Char *nmdefptr;
343 Char *ndlookup();
344
345 (void) strcpy( nmstr, (char *) yytext );
346 nmstr[yyleng - 1] = '\0'; /* chop trailing brace */
347
348 /* lookup from "nmstr + 1" to chop leading brace */
349 if ( ! (nmdefptr = ndlookup( nmstr + 1 )) )
350 synerr( "undefined {name}" );
351
352 else
353 { /* push back name surrounded by ()'s */
354 unput(')');
355 PUT_BACK_STRING(nmdefptr, 0);
356 unput('(');
357 }
358 }
359
360<SECT2>[/|*+?.()] return ( yytext[0] );
361<SECT2>. RETURNCHAR;
362<SECT2>\n ++linenum; return ( '\n' );
363
364
365<SC>"," return ( ',' );
366<SC>">" BEGIN(SECT2); return ( '>' );
367<SC>">"/"^" BEGIN(CARETISBOL); return ( '>' );
368<SC>{SCNAME} RETURNNAME;
369<SC>. synerr( "bad start condition name" );
370
371<CARETISBOL>"^" BEGIN(SECT2); return ( '^' );
372
373
374<QUOTE>[^"\n] RETURNCHAR;
375<QUOTE>\" BEGIN(SECT2); return ( '"' );
376
377<QUOTE>\n {
378 synerr( "missing quote" );
379 BEGIN(SECT2);
380 ++linenum;
381 return ( '"' );
382 }
383
384
385<FIRSTCCL>"^"/[^-\n] BEGIN(CCL); return ( '^' );
386<FIRSTCCL>"^"/- return ( '^' );
387<FIRSTCCL>- BEGIN(CCL); yylval = '-'; return ( CHAR );
388<FIRSTCCL>. BEGIN(CCL); RETURNCHAR;
389
390<CCL>-/[^\]\n] return ( '-' );
391<CCL>[^\]\n] RETURNCHAR;
392<CCL>"]" BEGIN(SECT2); return ( ']' );
393
394
395<NUM>[0-9]+ {
396 yylval = myctoi( yytext );
397 return ( NUMBER );
398 }
399
400<NUM>"," return ( ',' );
401<NUM>"}" BEGIN(SECT2); return ( '}' );
402
403<NUM>. {
404 synerr( "bad character inside {}'s" );
405 BEGIN(SECT2);
406 return ( '}' );
407 }
408
409<NUM>\n {
410 synerr( "missing }" );
411 BEGIN(SECT2);
412 ++linenum;
413 return ( '}' );
414 }
415
416
417<BRACEERROR>"}" synerr( "bad name in {}'s" ); BEGIN(SECT2);
418<BRACEERROR>\n synerr( "missing }" ); ++linenum; BEGIN(SECT2);
419
420
421<PERCENT_BRACE_ACTION,CODEBLOCK_2>{OPTWS}"%}".* bracelevel = 0;
422<PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"reject" {
423 ACTION_ECHO;
424 CHECK_REJECT(yytext);
425 }
426<PERCENT_BRACE_ACTION,CODEBLOCK_2,ACTION>"yymore" {
427 ACTION_ECHO;
428 CHECK_YYMORE(yytext);
429 }
430<PERCENT_BRACE_ACTION,CODEBLOCK_2>{NAME}|{NOT_NAME}|. ACTION_ECHO;
431<PERCENT_BRACE_ACTION,CODEBLOCK_2>\n {
432 ++linenum;
433 ACTION_ECHO;
434 if ( bracelevel == 0 ||
435 (doing_codeblock && indented_code) )
436 {
437 if ( ! doing_codeblock )
438 fputs( "\tYY_BREAK\n", temp_action_file );
439
440 doing_codeblock = false;
441 BEGIN(SECT2);
442 }
443 }
444
445
446 /* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
447<ACTION>"{" ACTION_ECHO; ++bracelevel;
448<ACTION>"}" ACTION_ECHO; --bracelevel;
449<ACTION>[^a-z_{}"'/\n]+ ACTION_ECHO;
450<ACTION>{NAME} ACTION_ECHO;
451<ACTION>"/*" ACTION_ECHO; BEGIN(ACTION_COMMENT);
452<ACTION>"'"([^'\\\n]|\\.)*"'" ACTION_ECHO; /* character constant */
453<ACTION>\" ACTION_ECHO; BEGIN(ACTION_STRING);
454<ACTION>\n {
455 ++linenum;
456 ACTION_ECHO;
457 if ( bracelevel == 0 )
458 {
459 fputs( "\tYY_BREAK\n", temp_action_file );
460 BEGIN(SECT2);
461 }
462 }
463<ACTION>. ACTION_ECHO;
464
465<ACTION_COMMENT>"*/" ACTION_ECHO; BEGIN(ACTION);
466<ACTION_COMMENT>[^*\n]+ ACTION_ECHO;
467<ACTION_COMMENT>"*" ACTION_ECHO;
468<ACTION_COMMENT>\n ++linenum; ACTION_ECHO;
469<ACTION_COMMENT>. ACTION_ECHO;
470
471<ACTION_STRING>[^"\\\n]+ ACTION_ECHO;
472<ACTION_STRING>\\. ACTION_ECHO;
473<ACTION_STRING>\n ++linenum; ACTION_ECHO;
474<ACTION_STRING>\" ACTION_ECHO; BEGIN(ACTION);
475<ACTION_STRING>. ACTION_ECHO;
476
477<ACTION,ACTION_COMMENT,ACTION_STRING><<EOF>> {
478 synerr( "EOF encountered inside an action" );
479 yyterminate();
480 }
481
482
483<SECT2,QUOTE,CCL>{ESCSEQ} {
484 yylval = myesc( yytext );
485 return ( CHAR );
486 }
487
488<FIRSTCCL>{ESCSEQ} {
489 yylval = myesc( yytext );
490 BEGIN(CCL);
491 return ( CHAR );
492 }
493
494
495<SECT3>.*(\n?) ECHO;
496%%
497
498
499int yywrap()
500
501 {
502 if ( --num_input_files > 0 )
503 {
504 set_input_file( *++input_files );
505 return ( 0 );
506 }
507
508 else
509 return ( 1 );
510 }
511
512
513/* set_input_file - open the given file (if NULL, stdin) for scanning */
514
515void set_input_file( file )
516char *file;
517
518 {
519 if ( file )
520 {
521 infilename = file;
522 yyin = fopen( infilename, "r" );
523
524 if ( yyin == NULL )
525 lerrsf( "can't open %s", file );
526 }
527
528 else
529 {
530 yyin = stdin;
531 infilename = "<stdin>";
532 }
533 }