• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* scan.l - scanner for flex input */
2 
3 %{
4 /*-
5  * Copyright (c) 1990 The Regents of the University of California.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Vern Paxson.
10  *
11  * The United States Government has rights in this work pursuant
12  * to contract no. DE-AC03-76SF00098 between the United States
13  * Department of Energy and the University of California.
14  *
15  * Redistribution and use in source and binary forms with or without
16  * modification are permitted provided that: (1) source distributions retain
17  * this entire copyright notice and comment, and (2) distributions including
18  * binaries display the following acknowledgement:  ``This product includes
19  * software developed by the University of California, Berkeley and its
20  * contributors'' in the documentation or other materials provided with the
21  * distribution and in all advertising materials mentioning features or use
22  * of this software.  Neither the name of the University nor the names of
23  * its contributors may be used to endorse or promote products derived from
24  * this software without specific prior written permission.
25  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
26  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
27  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
28  */
29 
30 /* $Header: /home/daffy/u0/vern/flex/RCS/scan.l,v 2.56 95/04/24 12:17:19 vern Exp $ */
31 
32 #include "flexdef.h"
33 #include "parse.h"
34 
35 #define ACTION_ECHO add_action( yytext )
36 #define ACTION_IFDEF(def, should_define) \
37 	{ \
38 	if ( should_define ) \
39 		action_define( def, 1 ); \
40 	}
41 
42 #define MARK_END_OF_PROLOG mark_prolog();
43 
44 #define YY_DECL \
45 	int flexscan()
46 
47 #define RETURNCHAR \
48 	yylval = (unsigned char) yytext[0]; \
49 	return CHAR;
50 
51 #define RETURNNAME \
52 	strcpy( nmstr, yytext ); \
53 	return NAME;
54 
55 #define PUT_BACK_STRING(str, start) \
56 	for ( i = strlen( str ) - 1; i >= start; --i ) \
57 		unput((str)[i])
58 
59 #define CHECK_REJECT(str) \
60 	if ( all_upper( str ) ) \
61 		reject = true;
62 
63 #define CHECK_YYMORE(str) \
64 	if ( all_lower( str ) ) \
65 		yymore_used = true;
66 %}
67 
68 %option caseless nodefault outfile="scan.c" stack noyy_top_state
69 %option nostdinit
70 
71 %x SECT2 SECT2PROLOG SECT3 CODEBLOCK PICKUPDEF SC CARETISBOL NUM QUOTE
72 %x FIRSTCCL CCL ACTION RECOVER COMMENT ACTION_STRING PERCENT_BRACE_ACTION
73 %x OPTION LINEDIR
74 
75 WS		[[:blank:]]+
76 OPTWS		[[:blank:]]*
77 NOT_WS		[^[:blank:]\n]
78 
79 NL		\r?\n
80 
81 NAME		([[:alpha:]_][[:alnum:]_-]*)
82 NOT_NAME	[^[:alpha:]_*\n]+
83 
84 SCNAME		{NAME}
85 
86 ESCSEQ		(\\([^\n]|[0-7]{1,3}|x[[:xdigit:]]{1,2}))
87 
88 FIRST_CCL_CHAR	([^\\\n]|{ESCSEQ})
89 CCL_CHAR	([^\\\n\]]|{ESCSEQ})
90 CCL_EXPR	("[:"[[:alpha:]]+":]")
91 
92 LEXOPT		[aceknopr]
93 
94 %%
95 	static int bracelevel, didadef, indented_code;
96 	static int doing_rule_action = false;
97 	static int option_sense;
98 
99 	int doing_codeblock = false;
100 	int i;
101 	Char nmdef[MAXLINE], myesc();
102 
103 
104 <INITIAL>{
105 	^{WS}		indented_code = true; BEGIN(CODEBLOCK);
106 	^"/*"		ACTION_ECHO; yy_push_state( COMMENT );
107 	^#{OPTWS}line{WS}	yy_push_state( LINEDIR );
108 	^"%s"{NAME}?	return SCDECL;
109 	^"%x"{NAME}?	return XSCDECL;
110 	^"%{".*{NL}	{
111 			++linenum;
112 			line_directive_out( (FILE *) 0, 1 );
113 			indented_code = false;
114 			BEGIN(CODEBLOCK);
115 			}
116 
117 	{WS}		/* discard */
118 
119 	^"%%".*		{
120 			sectnum = 2;
121 			bracelevel = 0;
122 			mark_defs1();
123 			line_directive_out( (FILE *) 0, 1 );
124 			BEGIN(SECT2PROLOG);
125 			return SECTEND;
126 			}
127 
128 	^"%pointer".*{NL}	yytext_is_array = false; ++linenum;
129 	^"%array".*{NL}		yytext_is_array = true; ++linenum;
130 
131 	^"%option"	BEGIN(OPTION); return OPTION_OP;
132 
133 	^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL}	++linenum; /* ignore */
134 	^"%"{LEXOPT}{WS}.*{NL}	++linenum;	/* ignore */
135 
136 	^"%"[^sxaceknopr{}].*	synerr( _( "unrecognized '%' directive" ) );
137 
138 	^{NAME}		{
139 			strcpy( nmstr, yytext );
140 			didadef = false;
141 			BEGIN(PICKUPDEF);
142 			}
143 
144 	{SCNAME}	RETURNNAME;
145 	^{OPTWS}{NL}	++linenum; /* allows blank lines in section 1 */
146 	{OPTWS}{NL}	ACTION_ECHO; ++linenum; /* maybe end of comment line */
147 }
148 
149 
150 <COMMENT>{
151 	"*/"		ACTION_ECHO; yy_pop_state();
152 	"*"		ACTION_ECHO;
153 	[^*\n]+		ACTION_ECHO;
154 	[^*\n]*{NL}	++linenum; ACTION_ECHO;
155 }
156 
157 <LINEDIR>{
158 	\n		yy_pop_state();
159 	[[:digit:]]+	linenum = myctoi( yytext );
160 
161 	\"[^"\n]*\"	{
162 			flex_free( (void *) infilename );
163 			infilename = copy_string( yytext + 1 );
164 			infilename[strlen( infilename ) - 1] = '\0';
165 			}
166 	.		/* ignore spurious characters */
167 }
168 
169 <CODEBLOCK>{
170 	^"%}".*{NL}	++linenum; BEGIN(INITIAL);
171 
172 	{NAME}|{NOT_NAME}|.	ACTION_ECHO;
173 
174 	{NL}		{
175 			++linenum;
176 			ACTION_ECHO;
177 			if ( indented_code )
178 				BEGIN(INITIAL);
179 			}
180 }
181 
182 
183 <PICKUPDEF>{
184 	{WS}		/* separates name and definition */
185 
186 	{NOT_WS}.*	{
187 			strcpy( (char *) nmdef, yytext );
188 
189 			/* Skip trailing whitespace. */
190 			for ( i = strlen( (char *) nmdef ) - 1;
191 			      i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t');
192 			      --i )
193 				;
194 
195 			nmdef[i + 1] = '\0';
196 
197 			ndinstal( nmstr, nmdef );
198 			didadef = true;
199 			}
200 
201 	{NL}		{
202 			if ( ! didadef )
203 				synerr( _( "incomplete name definition" ) );
204 			BEGIN(INITIAL);
205 			++linenum;
206 			}
207 }
208 
209 
210 <OPTION>{
211 	{NL}		++linenum; BEGIN(INITIAL);
212 	{WS}		option_sense = true;
213 
214 	"="		return '=';
215 
216 	no		option_sense = ! option_sense;
217 
218 	7bit		csize = option_sense ? 128 : 256;
219 	8bit		csize = option_sense ? 256 : 128;
220 
221 	align		long_align = option_sense;
222 	always-interactive	{
223 			action_define( "YY_ALWAYS_INTERACTIVE", option_sense );
224 			}
225 	array		yytext_is_array = option_sense;
226 	backup		backing_up_report = option_sense;
227 	batch		interactive = ! option_sense;
228 	"c++"		C_plus_plus = option_sense;
229 	caseful|case-sensitive		caseins = ! option_sense;
230 	caseless|case-insensitive	caseins = option_sense;
231 	debug		ddebug = option_sense;
232 	default		spprdflt = ! option_sense;
233 	ecs		useecs = option_sense;
234 	fast		{
235 			useecs = usemecs = false;
236 			use_read = fullspd = true;
237 			}
238 	full		{
239 			useecs = usemecs = false;
240 			use_read = fulltbl = true;
241 			}
242 	input		ACTION_IFDEF("YY_NO_INPUT", ! option_sense);
243 	interactive	interactive = option_sense;
244 	lex-compat	lex_compat = option_sense;
245 	main		{
246 			action_define( "YY_MAIN", option_sense );
247 			do_yywrap = ! option_sense;
248 			}
249 	meta-ecs	usemecs = option_sense;
250 	never-interactive	{
251 			action_define( "YY_NEVER_INTERACTIVE", option_sense );
252 			}
253 	perf-report	performance_report += option_sense ? 1 : -1;
254 	pointer		yytext_is_array = ! option_sense;
255 	read		use_read = option_sense;
256 	reject		reject_really_used = option_sense;
257 	stack		action_define( "YY_STACK_USED", option_sense );
258 	stdinit		do_stdinit = option_sense;
259 	stdout		use_stdout = option_sense;
260 	unput		ACTION_IFDEF("YY_NO_UNPUT", ! option_sense);
261 	verbose		printstats = option_sense;
262 	warn		nowarn = ! option_sense;
263 	yylineno	do_yylineno = option_sense;
264 	yymore		yymore_really_used = option_sense;
265 	yywrap		do_yywrap = option_sense;
266 
267 	yy_push_state	ACTION_IFDEF("YY_NO_PUSH_STATE", ! option_sense);
268 	yy_pop_state	ACTION_IFDEF("YY_NO_POP_STATE", ! option_sense);
269 	yy_top_state	ACTION_IFDEF("YY_NO_TOP_STATE", ! option_sense);
270 
271 	yy_scan_buffer	ACTION_IFDEF("YY_NO_SCAN_BUFFER", ! option_sense);
272 	yy_scan_bytes	ACTION_IFDEF("YY_NO_SCAN_BYTES", ! option_sense);
273 	yy_scan_string	ACTION_IFDEF("YY_NO_SCAN_STRING", ! option_sense);
274 
275 	outfile		return OPT_OUTFILE;
276 	prefix		return OPT_PREFIX;
277 	yyclass		return OPT_YYCLASS;
278 
279 	\"[^"\n]*\"	{
280 			strcpy( nmstr, yytext + 1 );
281 			nmstr[strlen( nmstr ) - 1] = '\0';
282 			return NAME;
283 			}
284 
285 	(([a-mo-z]|n[a-np-z])[[:alpha:]\-+]*)|.	{
286 			format_synerr( _( "unrecognized %%option: %s" ),
287 				yytext );
288 			BEGIN(RECOVER);
289 			}
290 }
291 
292 <RECOVER>.*{NL}		++linenum; BEGIN(INITIAL);
293 
294 
295 <SECT2PROLOG>{
296 	^"%{".*	++bracelevel; yyless( 2 );	/* eat only %{ */
297 	^"%}".*	--bracelevel; yyless( 2 );	/* eat only %} */
298 
299 	^{WS}.*	ACTION_ECHO;	/* indented code in prolog */
300 
301 	^{NOT_WS}.*	{	/* non-indented code */
302 			if ( bracelevel <= 0 )
303 				{ /* not in %{ ... %} */
304 				yyless( 0 );	/* put it all back */
305 				yy_set_bol( 1 );
306 				mark_prolog();
307 				BEGIN(SECT2);
308 				}
309 			else
310 				ACTION_ECHO;
311 			}
312 
313 	.*		ACTION_ECHO;
314 	{NL}	++linenum; ACTION_ECHO;
315 
316 	<<EOF>>		{
317 			mark_prolog();
318 			sectnum = 0;
319 			yyterminate(); /* to stop the parser */
320 			}
321 }
322 
323 <SECT2>{
324 	^{OPTWS}{NL}	++linenum; /* allow blank lines in section 2 */
325 
326 	^{OPTWS}"%{"	{
327 			indented_code = false;
328 			doing_codeblock = true;
329 			bracelevel = 1;
330 			BEGIN(PERCENT_BRACE_ACTION);
331 			}
332 
333 	^{OPTWS}"<"	BEGIN(SC); return '<';
334 	^{OPTWS}"^"	return '^';
335 	\"		BEGIN(QUOTE); return '"';
336 	"{"/[[:digit:]]	BEGIN(NUM); return '{';
337 	"$"/([[:blank:]]|{NL})	return '$';
338 
339 	{WS}"%{"		{
340 			bracelevel = 1;
341 			BEGIN(PERCENT_BRACE_ACTION);
342 
343 			if ( in_rule )
344 				{
345 				doing_rule_action = true;
346 				in_rule = false;
347 				return '\n';
348 				}
349 			}
350 	{WS}"|".*{NL}	continued_action = true; ++linenum; return '\n';
351 
352 	^{WS}"/*"	{
353 			yyless( yyleng - 2 );	/* put back '/', '*' */
354 			bracelevel = 0;
355 			continued_action = false;
356 			BEGIN(ACTION);
357 			}
358 
359 	^{WS}		/* allow indented rules */
360 
361 	{WS}		{
362 			/* This rule is separate from the one below because
363 			 * otherwise we get variable trailing context, so
364 			 * we can't build the scanner using -{f,F}.
365 			 */
366 			bracelevel = 0;
367 			continued_action = false;
368 			BEGIN(ACTION);
369 
370 			if ( in_rule )
371 				{
372 				doing_rule_action = true;
373 				in_rule = false;
374 				return '\n';
375 				}
376 			}
377 
378 	{OPTWS}{NL}	{
379 			bracelevel = 0;
380 			continued_action = false;
381 			BEGIN(ACTION);
382 			unput( '\n' );	/* so <ACTION> sees it */
383 
384 			if ( in_rule )
385 				{
386 				doing_rule_action = true;
387 				in_rule = false;
388 				return '\n';
389 				}
390 			}
391 
392 	^{OPTWS}"<<EOF>>"	|
393 	"<<EOF>>"	return EOF_OP;
394 
395 	^"%%".*		{
396 			sectnum = 3;
397 			BEGIN(SECT3);
398 			yyterminate(); /* to stop the parser */
399 			}
400 
401 	"["({FIRST_CCL_CHAR}|{CCL_EXPR})({CCL_CHAR}|{CCL_EXPR})*	{
402 			int cclval;
403 
404 			strcpy( nmstr, yytext );
405 
406 			/* Check to see if we've already encountered this
407 			 * ccl.
408 			 */
409 			if ( (cclval = ccllookup( (Char *) nmstr )) != 0 )
410 				{
411 				if ( input() != ']' )
412 					synerr( _( "bad character class" ) );
413 
414 				yylval = cclval;
415 				++cclreuse;
416 				return PREVCCL;
417 				}
418 			else
419 				{
420 				/* We fudge a bit.  We know that this ccl will
421 				 * soon be numbered as lastccl + 1 by cclinit.
422 				 */
423 				cclinstal( (Char *) nmstr, lastccl + 1 );
424 
425 				/* Push back everything but the leading bracket
426 				 * so the ccl can be rescanned.
427 				 */
428 				yyless( 1 );
429 
430 				BEGIN(FIRSTCCL);
431 				return '[';
432 				}
433 			}
434 
435 	"{"{NAME}"}"	{
436 			register Char *nmdefptr;
437 			Char *ndlookup();
438 
439 			strcpy( nmstr, yytext + 1 );
440 			nmstr[yyleng - 2] = '\0';  /* chop trailing brace */
441 
442 			if ( (nmdefptr = ndlookup( nmstr )) == 0 )
443 				format_synerr(
444 					_( "undefined definition {%s}" ),
445 						nmstr );
446 
447 			else
448 				{ /* push back name surrounded by ()'s */
449 				int len = strlen( (char *) nmdefptr );
450 
451 				if ( lex_compat || nmdefptr[0] == '^' ||
452 				     (len > 0 && nmdefptr[len - 1] == '$') )
453 					{ /* don't use ()'s after all */
454 					PUT_BACK_STRING((char *) nmdefptr, 0);
455 
456 					if ( nmdefptr[0] == '^' )
457 						BEGIN(CARETISBOL);
458 					}
459 
460 				else
461 					{
462 					unput(')');
463 					PUT_BACK_STRING((char *) nmdefptr, 0);
464 					unput('(');
465 					}
466 				}
467 			}
468 
469 	[/|*+?.(){}]	return (unsigned char) yytext[0];
470 	.		RETURNCHAR;
471 }
472 
473 
474 <SC>{
475 	[,*]		return (unsigned char) yytext[0];
476 	">"		BEGIN(SECT2); return '>';
477 	">"/^		BEGIN(CARETISBOL); return '>';
478 	{SCNAME}	RETURNNAME;
479 	.		{
480 			format_synerr( _( "bad <start condition>: %s" ),
481 				yytext );
482 			}
483 }
484 
485 <CARETISBOL>"^"		BEGIN(SECT2); return '^';
486 
487 
488 <QUOTE>{
489 	[^"\n]		RETURNCHAR;
490 	\"		BEGIN(SECT2); return '"';
491 
492 	{NL}		{
493 			synerr( _( "missing quote" ) );
494 			BEGIN(SECT2);
495 			++linenum;
496 			return '"';
497 			}
498 }
499 
500 
501 <FIRSTCCL>{
502 	"^"/[^-\]\n]	BEGIN(CCL); return '^';
503 	"^"/("-"|"]")	return '^';
504 	.		BEGIN(CCL); RETURNCHAR;
505 }
506 
507 <CCL>{
508 	-/[^\]\n]	return '-';
509 	[^\]\n]		RETURNCHAR;
510 	"]"		BEGIN(SECT2); return ']';
511 	.|{NL}		{
512 			synerr( _( "bad character class" ) );
513 			BEGIN(SECT2);
514 			return ']';
515 			}
516 }
517 
518 <FIRSTCCL,CCL>{
519 	"[:alnum:]"	BEGIN(CCL); return CCE_ALNUM;
520 	"[:alpha:]"	BEGIN(CCL); return CCE_ALPHA;
521 	"[:blank:]"	BEGIN(CCL); return CCE_BLANK;
522 	"[:cntrl:]"	BEGIN(CCL); return CCE_CNTRL;
523 	"[:digit:]"	BEGIN(CCL); return CCE_DIGIT;
524 	"[:graph:]"	BEGIN(CCL); return CCE_GRAPH;
525 	"[:lower:]"	BEGIN(CCL); return CCE_LOWER;
526 	"[:print:]"	BEGIN(CCL); return CCE_PRINT;
527 	"[:punct:]"	BEGIN(CCL); return CCE_PUNCT;
528 	"[:space:]"	BEGIN(CCL); return CCE_SPACE;
529 	"[:upper:]"	BEGIN(CCL); return CCE_UPPER;
530 	"[:xdigit:]"	BEGIN(CCL); return CCE_XDIGIT;
531 	{CCL_EXPR}	{
532 			format_synerr(
533 				_( "bad character class expression: %s" ),
534 					yytext );
535 			BEGIN(CCL); return CCE_ALNUM;
536 			}
537 }
538 
539 <NUM>{
540 	[[:digit:]]+	{
541 			yylval = myctoi( yytext );
542 			return NUMBER;
543 			}
544 
545 	","		return ',';
546 	"}"		BEGIN(SECT2); return '}';
547 
548 	.		{
549 			synerr( _( "bad character inside {}'s" ) );
550 			BEGIN(SECT2);
551 			return '}';
552 			}
553 
554 	{NL}		{
555 			synerr( _( "missing }" ) );
556 			BEGIN(SECT2);
557 			++linenum;
558 			return '}';
559 			}
560 }
561 
562 
563 <PERCENT_BRACE_ACTION>{
564 	{OPTWS}"%}".*		bracelevel = 0;
565 
566 	<ACTION>"/*"		ACTION_ECHO; yy_push_state( COMMENT );
567 
568 	<CODEBLOCK,ACTION>{
569 		"reject"	{
570 			ACTION_ECHO;
571 			CHECK_REJECT(yytext);
572 			}
573 		"yymore"	{
574 			ACTION_ECHO;
575 			CHECK_YYMORE(yytext);
576 			}
577 	}
578 
579 	{NAME}|{NOT_NAME}|.	ACTION_ECHO;
580 	{NL}		{
581 			++linenum;
582 			ACTION_ECHO;
583 			if ( bracelevel == 0 ||
584 			     (doing_codeblock && indented_code) )
585 				{
586 				if ( doing_rule_action )
587 					add_action( "\tYY_BREAK\n" );
588 
589 				doing_rule_action = doing_codeblock = false;
590 				BEGIN(SECT2);
591 				}
592 			}
593 }
594 
595 
596 	/* Reject and YYmore() are checked for above, in PERCENT_BRACE_ACTION */
597 <ACTION>{
598 	"{"		ACTION_ECHO; ++bracelevel;
599 	"}"		ACTION_ECHO; --bracelevel;
600 	[^[:alpha:]_{}"'/\n]+	ACTION_ECHO;
601 	{NAME}		ACTION_ECHO;
602 	"'"([^'\\\n]|\\.)*"'"	ACTION_ECHO; /* character constant */
603 	\"		ACTION_ECHO; BEGIN(ACTION_STRING);
604 	{NL}		{
605 			++linenum;
606 			ACTION_ECHO;
607 			if ( bracelevel == 0 )
608 				{
609 				if ( doing_rule_action )
610 					add_action( "\tYY_BREAK\n" );
611 
612 				doing_rule_action = false;
613 				BEGIN(SECT2);
614 				}
615 			}
616 	.		ACTION_ECHO;
617 }
618 
619 <ACTION_STRING>{
620 	[^"\\\n]+	ACTION_ECHO;
621 	\\.		ACTION_ECHO;
622 	{NL}		++linenum; ACTION_ECHO;
623 	\"		ACTION_ECHO; BEGIN(ACTION);
624 	.		ACTION_ECHO;
625 }
626 
627 <COMMENT,ACTION,ACTION_STRING><<EOF>>	{
628 			synerr( _( "EOF encountered inside an action" ) );
629 			yyterminate();
630 			}
631 
632 
633 <SECT2,QUOTE,FIRSTCCL,CCL>{ESCSEQ}	{
634 			yylval = myesc( (Char *) yytext );
635 
636 			if ( YY_START == FIRSTCCL )
637 				BEGIN(CCL);
638 
639 			return CHAR;
640 			}
641 
642 
643 <SECT3>{
644 	.*(\n?)		ECHO;
645 	<<EOF>>		sectnum = 0; yyterminate();
646 }
647 
648 <*>.|\n			format_synerr( _( "bad character: %s" ), yytext );
649 
650 %%
651 
652 
653 int yywrap()
654 	{
655 	if ( --num_input_files > 0 )
656 		{
657 		set_input_file( *++input_files );
658 		return 0;
659 		}
660 
661 	else
662 		return 1;
663 	}
664 
665 
666 /* set_input_file - open the given file (if NULL, stdin) for scanning */
667 
668 void set_input_file( file )
669 char *file;
670 	{
671 	if ( file && strcmp( file, "-" ) )
672 		{
673 		infilename = copy_string( file );
674 		yyin = fopen( infilename, "r" );
675 
676 		if ( yyin == NULL )
677 			lerrsf( _( "can't open %s" ), file );
678 		}
679 
680 	else
681 		{
682 		yyin = stdin;
683 		infilename = copy_string( "<stdin>" );
684 		}
685 
686 	linenum = 1;
687 	}
688 
689 
690 /* Wrapper routines for accessing the scanner's malloc routines. */
691 
692 void *flex_alloc( size )
693 size_t size;
694 	{
695 	return (void *) malloc( size );
696 	}
697 
698 void *flex_realloc( ptr, size )
699 void *ptr;
700 size_t size;
701 	{
702 	return (void *) realloc( ptr, size );
703 	}
704 
705 void flex_free( ptr )
706 void *ptr;
707 	{
708 	if ( ptr )
709 		free( ptr );
710 	}
711