*** empty log message ***
[minix.git] / commands / flex-2.5.4 / scan.l
blobfee78ab758169cfa8a558534b5d1817449473c49
1 /* scan.l - scanner for flex input */
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  */
30 /* $Header$ */
32 #include "flexdef.h"
33 #include "parse.h"
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         }
42 #define MARK_END_OF_PROLOG mark_prolog();
44 #define YY_DECL \
45         int flexscan()
47 #define RETURNCHAR \
48         yylval = (unsigned char) yytext[0]; \
49         return CHAR;
51 #define RETURNNAME \
52         strcpy( nmstr, yytext ); \
53         return NAME;
55 #define PUT_BACK_STRING(str, start) \
56         for ( i = strlen( str ) - 1; i >= start; --i ) \
57                 unput((str)[i])
59 #define CHECK_REJECT(str) \
60         if ( all_upper( str ) ) \
61                 reject = true;
63 #define CHECK_YYMORE(str) \
64         if ( all_lower( str ) ) \
65                 yymore_used = true;
68 %option caseless nodefault outfile="scan.c" stack noyy_top_state
69 %option nostdinit
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
75 WS              [[:blank:]]+
76 OPTWS           [[:blank:]]*
77 NOT_WS          [^[:blank:]\n]
79 NL              \r?\n
81 NAME            ([[:alpha:]_][[:alnum:]_-]*)
82 NOT_NAME        [^[:alpha:]_*\n]+
84 SCNAME          {NAME}
86 ESCSEQ          (\\([^\n]|[0-7]{1,3}|x[[:xdigit:]]{1,2}))
88 FIRST_CCL_CHAR  ([^\\\n]|{ESCSEQ})
89 CCL_CHAR        ([^\\\n\]]|{ESCSEQ})
90 CCL_EXPR        ("[:"[[:alpha:]]+":]")
92 LEXOPT          [aceknopr]
95         static int bracelevel, didadef, indented_code;
96         static int doing_rule_action = false;
97         static int option_sense;
99         int doing_codeblock = false;
100         int i;
101         Char nmdef[MAXLINE], myesc();
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                         }
117         {WS}            /* discard */
119         ^"%%".*         {
120                         sectnum = 2;
121                         bracelevel = 0;
122                         mark_defs1();
123                         line_directive_out( (FILE *) 0, 1 );
124                         BEGIN(SECT2PROLOG);
125                         return SECTEND;
126                         }
128         ^"%pointer".*{NL}       yytext_is_array = false; ++linenum;
129         ^"%array".*{NL}         yytext_is_array = true; ++linenum;
131         ^"%option"      BEGIN(OPTION); return OPTION_OP;
133         ^"%"{LEXOPT}{OPTWS}[[:digit:]]*{OPTWS}{NL}      ++linenum; /* ignore */
134         ^"%"{LEXOPT}{WS}.*{NL}  ++linenum;      /* ignore */
136         ^"%"[^sxaceknopr{}].*   synerr( _( "unrecognized '%' directive" ) );
138         ^{NAME}         {
139                         strcpy( nmstr, yytext );
140                         didadef = false;
141                         BEGIN(PICKUPDEF);
142                         }
144         {SCNAME}        RETURNNAME;
145         ^{OPTWS}{NL}    ++linenum; /* allows blank lines in section 1 */
146         {OPTWS}{NL}     ACTION_ECHO; ++linenum; /* maybe end of comment line */
150 <COMMENT>{
151         "*/"            ACTION_ECHO; yy_pop_state();
152         "*"             ACTION_ECHO;
153         [^*\n]+         ACTION_ECHO;
154         [^*\n]*{NL}     ++linenum; ACTION_ECHO;
157 <LINEDIR>{
158         \n              yy_pop_state();
159         [[:digit:]]+    linenum = myctoi( yytext );
161         \"[^"\n]*\"     {
162                         flex_free( (void *) infilename );
163                         infilename = copy_string( yytext + 1 );
164                         infilename[strlen( infilename ) - 1] = '\0';
165                         }
166         .               /* ignore spurious characters */
169 <CODEBLOCK>{
170         ^"%}".*{NL}     ++linenum; BEGIN(INITIAL);
172         {NAME}|{NOT_NAME}|.     ACTION_ECHO;
174         {NL}            {
175                         ++linenum;
176                         ACTION_ECHO;
177                         if ( indented_code )
178                                 BEGIN(INITIAL);
179                         }
183 <PICKUPDEF>{
184         {WS}            /* separates name and definition */
186         {NOT_WS}.*      {
187                         strcpy( (char *) nmdef, yytext );
189                         /* Skip trailing whitespace. */
190                         for ( i = strlen( (char *) nmdef ) - 1;
191                               i >= 0 && (nmdef[i] == ' ' || nmdef[i] == '\t');
192                               --i )
193                                 ;
195                         nmdef[i + 1] = '\0';
197                         ndinstal( nmstr, nmdef );
198                         didadef = true;
199                         }
201         {NL}            {
202                         if ( ! didadef )
203                                 synerr( _( "incomplete name definition" ) );
204                         BEGIN(INITIAL);
205                         ++linenum;
206                         }
210 <OPTION>{
211         {NL}            ++linenum; BEGIN(INITIAL);
212         {WS}            option_sense = true;
214         "="             return '=';
216         no              option_sense = ! option_sense;
218         7bit            csize = option_sense ? 128 : 256;
219         8bit            csize = option_sense ? 256 : 128;
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;
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);
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);
275         outfile         return OPT_OUTFILE;
276         prefix          return OPT_PREFIX;
277         yyclass         return OPT_YYCLASS;
279         \"[^"\n]*\"     {
280                         strcpy( nmstr, yytext + 1 );
281                         nmstr[strlen( nmstr ) - 1] = '\0';
282                         return NAME;
283                         }
285         (([a-mo-z]|n[a-np-z])[[:alpha:]\-+]*)|. {
286                         format_synerr( _( "unrecognized %%option: %s" ),
287                                 yytext );
288                         BEGIN(RECOVER);
289                         }
292 <RECOVER>.*{NL}         ++linenum; BEGIN(INITIAL);
295 <SECT2PROLOG>{
296         ^"%{".* ++bracelevel; yyless( 2 );      /* eat only %{ */
297         ^"%}".* --bracelevel; yyless( 2 );      /* eat only %} */
299         ^{WS}.* ACTION_ECHO;    /* indented code in prolog */
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                         }
313         .*              ACTION_ECHO;
314         {NL}    ++linenum; ACTION_ECHO;
316         <<EOF>>         {
317                         mark_prolog();
318                         sectnum = 0;
319                         yyterminate(); /* to stop the parser */
320                         }
323 <SECT2>{
324         ^{OPTWS}{NL}    ++linenum; /* allow blank lines in section 2 */
326         ^{OPTWS}"%{"    {
327                         indented_code = false;
328                         doing_codeblock = true;
329                         bracelevel = 1;
330                         BEGIN(PERCENT_BRACE_ACTION);
331                         }
333         ^{OPTWS}"<"     BEGIN(SC); return '<';
334         ^{OPTWS}"^"     return '^';
335         \"              BEGIN(QUOTE); return '"';
336         "{"/[[:digit:]] BEGIN(NUM); return '{';
337         "$"/([[:blank:]]|{NL})  return '$';
339         {WS}"%{"                {
340                         bracelevel = 1;
341                         BEGIN(PERCENT_BRACE_ACTION);
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';
352         ^{WS}"/*"       {
353                         yyless( yyleng - 2 );   /* put back '/', '*' */
354                         bracelevel = 0;
355                         continued_action = false;
356                         BEGIN(ACTION);
357                         }
359         ^{WS}           /* allow indented rules */
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);
370                         if ( in_rule )
371                                 {
372                                 doing_rule_action = true;
373                                 in_rule = false;
374                                 return '\n';
375                                 }
376                         }
378         {OPTWS}{NL}     {
379                         bracelevel = 0;
380                         continued_action = false;
381                         BEGIN(ACTION);
382                         unput( '\n' );  /* so <ACTION> sees it */
384                         if ( in_rule )
385                                 {
386                                 doing_rule_action = true;
387                                 in_rule = false;
388                                 return '\n';
389                                 }
390                         }
392         ^{OPTWS}"<<EOF>>"       |
393         "<<EOF>>"       return EOF_OP;
395         ^"%%".*         {
396                         sectnum = 3;
397                         BEGIN(SECT3);
398                         yyterminate(); /* to stop the parser */
399                         }
401         "["({FIRST_CCL_CHAR}|{CCL_EXPR})({CCL_CHAR}|{CCL_EXPR})*        {
402                         int cclval;
404                         strcpy( nmstr, yytext );
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" ) );
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 );
425                                 /* Push back everything but the leading bracket
426                                  * so the ccl can be rescanned.
427                                  */
428                                 yyless( 1 );
430                                 BEGIN(FIRSTCCL);
431                                 return '[';
432                                 }
433                         }
435         "{"{NAME}"}"    {
436                         register Char *nmdefptr;
437                         Char *ndlookup();
439                         strcpy( nmstr, yytext + 1 );
440                         nmstr[yyleng - 2] = '\0';  /* chop trailing brace */
442                         if ( (nmdefptr = ndlookup( nmstr )) == 0 )
443                                 format_synerr(
444                                         _( "undefined definition {%s}" ),
445                                                 nmstr );
447                         else
448                                 { /* push back name surrounded by ()'s */
449                                 int len = strlen( (char *) nmdefptr );
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);
456                                         if ( nmdefptr[0] == '^' )
457                                                 BEGIN(CARETISBOL);
458                                         }
460                                 else
461                                         {
462                                         unput(')');
463                                         PUT_BACK_STRING((char *) nmdefptr, 0);
464                                         unput('(');
465                                         }
466                                 }
467                         }
469         [/|*+?.(){}]    return (unsigned char) yytext[0];
470         .               RETURNCHAR;
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                         }
485 <CARETISBOL>"^"         BEGIN(SECT2); return '^';
488 <QUOTE>{
489         [^"\n]          RETURNCHAR;
490         \"              BEGIN(SECT2); return '"';
492         {NL}            {
493                         synerr( _( "missing quote" ) );
494                         BEGIN(SECT2);
495                         ++linenum;
496                         return '"';
497                         }
501 <FIRSTCCL>{
502         "^"/[^-\]\n]    BEGIN(CCL); return '^';
503         "^"/("-"|"]")   return '^';
504         .               BEGIN(CCL); RETURNCHAR;
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                         }
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                         }
539 <NUM>{
540         [[:digit:]]+    {
541                         yylval = myctoi( yytext );
542                         return NUMBER;
543                         }
545         ","             return ',';
546         "}"             BEGIN(SECT2); return '}';
548         .               {
549                         synerr( _( "bad character inside {}'s" ) );
550                         BEGIN(SECT2);
551                         return '}';
552                         }
554         {NL}            {
555                         synerr( _( "missing }" ) );
556                         BEGIN(SECT2);
557                         ++linenum;
558                         return '}';
559                         }
563 <PERCENT_BRACE_ACTION>{
564         {OPTWS}"%}".*           bracelevel = 0;
566         <ACTION>"/*"            ACTION_ECHO; yy_push_state( COMMENT );
568         <CODEBLOCK,ACTION>{
569                 "reject"        {
570                         ACTION_ECHO;
571                         CHECK_REJECT(yytext);
572                         }
573                 "yymore"        {
574                         ACTION_ECHO;
575                         CHECK_YYMORE(yytext);
576                         }
577         }
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" );
589                                 doing_rule_action = doing_codeblock = false;
590                                 BEGIN(SECT2);
591                                 }
592                         }
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" );
612                                 doing_rule_action = false;
613                                 BEGIN(SECT2);
614                                 }
615                         }
616         .               ACTION_ECHO;
619 <ACTION_STRING>{
620         [^"\\\n]+       ACTION_ECHO;
621         \\.             ACTION_ECHO;
622         {NL}            ++linenum; ACTION_ECHO;
623         \"              ACTION_ECHO; BEGIN(ACTION);
624         .               ACTION_ECHO;
627 <COMMENT,ACTION,ACTION_STRING><<EOF>>   {
628                         synerr( _( "EOF encountered inside an action" ) );
629                         yyterminate();
630                         }
633 <SECT2,QUOTE,FIRSTCCL,CCL>{ESCSEQ}      {
634                         yylval = myesc( (Char *) yytext );
636                         if ( YY_START == FIRSTCCL )
637                                 BEGIN(CCL);
639                         return CHAR;
640                         }
643 <SECT3>{
644         .*(\n?)         ECHO;
645         <<EOF>>         sectnum = 0; yyterminate();
648 <*>.|\n                 format_synerr( _( "bad character: %s" ), yytext );
653 int yywrap()
654         {
655         if ( --num_input_files > 0 )
656                 {
657                 set_input_file( *++input_files );
658                 return 0;
659                 }
661         else
662                 return 1;
663         }
666 /* set_input_file - open the given file (if NULL, stdin) for scanning */
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" );
676                 if ( yyin == NULL )
677                         lerrsf( _( "can't open %s" ), file );
678                 }
680         else
681                 {
682                 yyin = stdin;
683                 infilename = copy_string( "<stdin>" );
684                 }
686         linenum = 1;
687         }
690 /* Wrapper routines for accessing the scanner's malloc routines. */
692 void *flex_alloc( size )
693 size_t size;
694         {
695         return (void *) malloc( size );
696         }
698 void *flex_realloc( ptr, size )
699 void *ptr;
700 size_t size;
701         {
702         return (void *) realloc( ptr, size );
703         }
705 void flex_free( ptr )
706 void *ptr;
707         {
708         if ( ptr )
709                 free( ptr );
710         }