1 /* $NetBSD: main.c,v 1.4 2013/04/06 14:27:52 christos Exp $ */
3 /* flex - tool to generate fast lexical analyzers */
5 /* Copyright (c) 1990 The Regents of the University of California. */
6 /* All rights reserved. */
8 /* This code is derived from software contributed to Berkeley by */
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. */
15 /* This file is part of flex. */
17 /* Redistribution and use in source and binary forms, with or without */
18 /* modification, are permitted provided that the following conditions */
21 /* 1. Redistributions of source code must retain the above copyright */
22 /* notice, this list of conditions and the following disclaimer. */
23 /* 2. Redistributions in binary form must reproduce the above copyright */
24 /* notice, this list of conditions and the following disclaimer in the */
25 /* documentation and/or other materials provided with the distribution. */
27 /* Neither the name of the University nor the names of its contributors */
28 /* may be used to endorse or promote products derived from this software */
29 /* without specific prior written permission. */
31 /* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */
32 /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */
33 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */
42 static char flex_version
[] = FLEX_VERSION
;
44 /* declare functions that have forward references */
46 void flexinit
PROTO ((int, char **));
47 void readin
PROTO ((void));
48 void set_up_initial_allocations
PROTO ((void));
49 static char *basename2
PROTO ((char *path
, int should_strip_ext
));
52 /* these globals are all defined and commented in flexdef.h */
53 int printstats
, syntaxerror
, eofseen
, ddebug
, trace
, nowarn
, spprdflt
;
54 int interactive
, lex_compat
, posix_compat
, do_yylineno
,
55 useecs
, fulltbl
, usemecs
;
56 int fullspd
, gen_line_dirs
, performance_report
, backing_up_report
;
57 int C_plus_plus
, long_align
, use_read
, yytext_is_array
, do_yywrap
,
59 int reentrant
, bison_bridge_lval
, bison_bridge_lloc
;
60 int yymore_used
, reject
, real_reject
, continued_action
, in_rule
;
61 int yymore_really_used
, reject_really_used
;
62 int datapos
, dataline
, linenum
;
63 FILE *skelfile
= NULL
;
66 int action_size
, defs1_offset
, prolog_offset
, action_offset
,
68 char *infilename
= NULL
, *outfilename
= NULL
, *headerfilename
= NULL
;
70 char *prefix
, *yyclass
, *extra_type
= NULL
;
71 int do_stdinit
, use_stdout
;
72 int onestate
[ONE_STACK_SIZE
], onesym
[ONE_STACK_SIZE
];
73 int onenext
[ONE_STACK_SIZE
], onedef
[ONE_STACK_SIZE
], onesp
;
74 int maximum_mns
, current_mns
, current_max_rules
;
75 int num_rules
, num_eof_rules
, default_rule
, lastnfa
;
76 int *firstst
, *lastst
, *finalst
, *transchar
, *trans1
, *trans2
;
77 int *accptnum
, *assoc_rule
, *state_type
;
78 int *rule_type
, *rule_linenum
, *rule_useful
;
79 int current_state_type
;
80 int variable_trailing_context_rules
;
81 int numtemps
, numprots
, protprev
[MSP
], protnext
[MSP
], prottbl
[MSP
];
82 int protcomst
[MSP
], firstprot
, lastprot
, protsave
[PROT_SAVE_SIZE
];
83 int numecs
, nextecm
[CSIZE
+ 1], ecgroup
[CSIZE
+ 1], nummecs
,
85 int tecbck
[CSIZE
+ 1];
86 int lastsc
, *scset
, *scbol
, *scxclu
, *sceof
;
89 int current_max_dfa_size
, current_max_xpairs
;
90 int current_max_template_xpairs
, current_max_dfas
;
91 int lastdfa
, *nxt
, *chk
, *tnxt
;
92 int *base
, *def
, *nultrans
, NUL_ec
, tblend
, firstfree
, **dss
, *dfasiz
;
93 union dfaacc_union
*dfaacc
;
94 int *accsiz
, *dhash
, numas
;
95 int numsnpairs
, jambase
, jamstate
;
96 int lastccl
, *cclmap
, *ccllen
, *cclng
, cclreuse
;
97 int current_maxccls
, current_max_ccl_tbl_size
;
100 int sectnum
, nummt
, hshcol
, dfaeql
, numeps
, eps2
, num_reallocs
;
101 int tmpuses
, totnst
, peakpairs
, numuniq
, numdup
, hshsave
;
102 int num_backing_up
, bol_needed
;
103 FILE *backing_up_file
;
104 int end_of_buffer_state
;
107 jmp_buf flex_main_jmp_buf
;
108 bool *rule_has_nl
, *ccl_has_nl
;
110 bool ansi_func_defs
, ansi_func_protos
;
112 bool tablesext
, tablesverify
, gentables
;
113 char *tablesfilename
=0,*tablesname
=0;
114 struct yytbl_writer tableswr
;
116 /* Make sure program_name is initialized so we don't crash if writing
117 * out an error message before getting the program name from argv[0].
119 char *program_name
= "flex";
121 #ifndef SHORT_FILE_NAMES
122 static const char outfile_template
[] = "lex.%s.%s";
123 static const char backing_name
[] = "lex.backup";
124 static const char tablesfile_template
[] = "lex.%s.tables";
126 static const char outfile_template
[] = "lex%s.%s";
127 static const char backing_name
[] = "lex.bck";
128 static const char tablesfile_template
[] = "lex%s.tbl";
132 extern unsigned _stklen
= 16384;
138 static char outfile_path
[MAXLINE
];
139 static int outfile_created
= 0;
140 static char *skelname
= NULL
;
141 static int _stdout_closed
= 0; /* flag to prevent double-fclose() on stdout. */
142 const char *escaped_qstart
= "[[]]M4_YY_NOOP[M4_YY_NOOP[M4_YY_NOOP[[]]";
143 const char *escaped_qend
= "[[]]M4_YY_NOOP]M4_YY_NOOP]M4_YY_NOOP[[]]";
145 /* For debugging. The max number of filters to apply to skeleton. */
146 static int preproc_level
= 1000;
148 int flex_main
PROTO ((int argc
, char *argv
[]));
149 int main
PROTO ((int argc
, char *argv
[]));
151 int flex_main (argc
, argv
)
155 int i
, exit_status
, child_status
;
157 /* Set a longjmp target. Yes, I know it's a hack, but it gets worse: The
158 * return value of setjmp, if non-zero, is the desired exit code PLUS ONE.
159 * For example, if you want 'main' to return with code '2', then call
160 * longjmp() with an argument of 3. This is because it is invalid to
161 * specify a value of 0 to longjmp. FLEX_EXIT(n) should be used instead of
164 exit_status
= setjmp (flex_main_jmp_buf
);
166 if (stdout
&& !_stdout_closed
&& !ferror(stdout
)){
170 while (wait(&child_status
) > 0){
171 if (!WIFEXITED (child_status
)
172 || WEXITSTATUS (child_status
) != 0){
173 /* report an error of a child
175 if( exit_status
<= 1 )
180 return exit_status
- 1;
183 flexinit (argc
, argv
);
189 for (i
= 1; i
<= num_rules
; ++i
)
190 if (!rule_useful
[i
] && i
!= default_rule
)
191 line_warning (_("rule cannot be matched"),
194 if (spprdflt
&& !reject
&& rule_useful
[default_rule
])
196 ("-s option given but default rule can be matched"),
197 rule_linenum
[default_rule
]);
199 /* Generate the C state transition tables from the DFA. */
202 /* Note, flexend does not return. It exits with its argument
207 return 0; /* keep compilers/lint happy */
210 /* Wrapper around flex_main, so flex_main can be built as a library. */
211 int main (argc
, argv
)
217 setlocale (LC_MESSAGES
, "");
218 setlocale (LC_CTYPE
, "");
219 textdomain (PACKAGE
);
220 bindtextdomain (PACKAGE
, LOCALEDIR
);
224 return flex_main (argc
, argv
);
227 /* check_options - check user-specified options */
229 void check_options ()
232 const char * m4
= NULL
;
236 flexerror (_("Can't use -+ with -l option"));
238 if (fulltbl
|| fullspd
)
239 flexerror (_("Can't use -f or -F with -l option"));
241 if (reentrant
|| bison_bridge_lval
)
243 ("Can't use --reentrant or --bison-bridge with -l option"));
245 /* Don't rely on detecting use of yymore() and REJECT,
246 * just assume they'll be used.
248 yymore_really_used
= reject_really_used
= true;
250 yytext_is_array
= true;
257 /* This makes no sense whatsoever. I'm removing it. */
259 /* This should really be "maintain_backup_tables = true" */
260 reject_really_used
= true;
263 if (csize
== unspecified
) {
264 if ((fulltbl
|| fullspd
) && !useecs
)
265 csize
= DEFAULT_CSIZE
;
270 if (interactive
== unspecified
) {
271 if (fulltbl
|| fullspd
)
277 if (fulltbl
|| fullspd
) {
280 ("-Cf/-CF and -Cm don't make sense together"));
283 flexerror (_("-Cf/-CF and -I are incompatible"));
287 ("-Cf/-CF are incompatible with lex-compatibility mode"));
290 if (fulltbl
&& fullspd
)
292 ("-Cf and -CF are mutually exclusive"));
295 if (C_plus_plus
&& fullspd
)
296 flexerror (_("Can't use -+ with -CF option"));
298 if (C_plus_plus
&& yytext_is_array
) {
299 lwarn (_("%array incompatible with -+ option"));
300 yytext_is_array
= false;
303 if (C_plus_plus
&& (reentrant
))
304 flexerror (_("Options -+ and --reentrant are mutually exclusive."));
306 if (C_plus_plus
&& bison_bridge_lval
)
307 flexerror (_("bison bridge not supported for the C++ scanner."));
310 if (useecs
) { /* Set up doubly-linked equivalence classes. */
312 /* We loop all the way up to csize, since ecgroup[csize] is
313 * the position used for NUL characters.
317 for (i
= 2; i
<= csize
; ++i
) {
322 nextecm
[csize
] = NIL
;
326 /* Put everything in its own equivalence class. */
327 for (i
= 1; i
<= csize
; ++i
) {
329 nextecm
[i
] = BAD_SUBSCRIPT
; /* to catch errors */
334 buf_m4_define( &m4defs_buf
, "M4_YY_NO_ANSI_FUNC_DEFS", NULL
);
336 if (!ansi_func_protos
)
337 buf_m4_define( &m4defs_buf
, "M4_YY_NO_ANSI_FUNC_PROTOS", NULL
);
340 buf_m4_define( &m4defs_buf
, "M4_EXTRA_TYPE_DEFS", extra_type
);
345 if (!did_outfilename
) {
353 snprintf (outfile_path
, sizeof(outfile_path
), outfile_template
,
356 outfilename
= outfile_path
;
359 prev_stdout
= freopen (outfilename
, "w+", stdout
);
361 if (prev_stdout
== NULL
)
362 lerrsf (_("could not create %s"), outfilename
);
368 /* Setup the filter chain. */
369 output_chain
= filter_create_int(NULL
, filter_tee_header
, headerfilename
);
370 if ( !(m4
= getenv("M4")))
372 filter_create_ext(output_chain
, m4
, "-P", 0);
373 filter_create_int(output_chain
, filter_fix_linedirs
, NULL
);
375 /* For debugging, only run the requested number of filters. */
376 if (preproc_level
> 0) {
377 filter_truncate(output_chain
, preproc_level
);
378 filter_apply_chain(output_chain
);
383 /* always generate the tablesverify flag. */
384 buf_m4_define (&m4defs_buf
, "M4_YY_TABLES_VERIFY", tablesverify
? "1" : "0");
389 /* force generation of C tables. */
395 struct yytbl_hdr hdr
;
399 buf_m4_define (&m4defs_buf
, "M4_YY_TABLES_EXTERNAL", NULL
);
401 if (!tablesfilename
) {
402 nbytes
= strlen (prefix
) + strlen (tablesfile_template
) + 2;
403 tablesfilename
= pname
= (char *) calloc (nbytes
, 1);
404 snprintf (pname
, nbytes
, tablesfile_template
, prefix
);
407 if ((tablesout
= fopen (tablesfilename
, "w")) == NULL
)
408 lerrsf (_("could not create %s"), tablesfilename
);
413 yytbl_writer_init (&tableswr
, tablesout
);
415 nbytes
= strlen (prefix
) + strlen ("tables") + 2;
416 tablesname
= (char *) calloc (nbytes
, 1);
417 snprintf (tablesname
, nbytes
, "%stables", prefix
);
418 yytbl_hdr_init (&hdr
, flex_version
, tablesname
);
420 if (yytbl_hdr_fwrite (&tableswr
, &hdr
) <= 0)
421 flexerror (_("could not write tables header"));
424 if (skelname
&& (skelfile
= fopen (skelname
, "r")) == NULL
)
425 lerrsf (_("can't open skeleton file %s"), skelname
);
428 buf_m4_define (&m4defs_buf
, "M4_YY_REENTRANT", NULL
);
430 buf_m4_define (&m4defs_buf
, "M4_YY_TEXT_IS_ARRAY", NULL
);
433 if ( bison_bridge_lval
)
434 buf_m4_define (&m4defs_buf
, "M4_YY_BISON_LVAL", NULL
);
436 if ( bison_bridge_lloc
)
437 buf_m4_define (&m4defs_buf
, "<M4_YY_BISON_LLOC>", NULL
);
439 buf_m4_define(&m4defs_buf
, "M4_YY_PREFIX", prefix
);
442 line_directive_out (stdout
, 0);
445 buf_m4_define (&m4defs_buf
, "M4_YY_USE_LINENO", NULL
);
447 /* Create the alignment type. */
448 buf_strdefine (&userdef_buf
, "YY_INT_ALIGNED",
449 long_align
? "long int" : "short int");
451 /* Define the start condition macros. */
454 buf_init(&tmpbuf
, sizeof(char));
455 for (i
= 1; i
<= lastsc
; i
++) {
456 char *str
, *fmt
= "#define %s %d\n";
459 str
= (char*)flex_alloc(strsz
= strlen(fmt
) + strlen(scname
[i
]) + (int)(1 + log10(i
)) + 2);
461 flexfatal(_("allocation of macro definition failed"));
462 snprintf(str
, strsz
, fmt
, scname
[i
], i
- 1);
463 buf_strappend(&tmpbuf
, str
);
466 buf_m4_define(&m4defs_buf
, "M4_YY_SC_DEFS", tmpbuf
.elts
);
467 buf_destroy(&tmpbuf
);
470 /* This is where we begin writing to the file. */
472 /* Dump the %top code. */
474 outn((char*) top_buf
.elts
);
476 /* Dump the m4 definitions. */
477 buf_print_strings(&m4defs_buf
, stdout
);
478 m4defs_buf
.nelts
= 0; /* memory leak here. */
480 /* Place a bogus line directive, it will be fixed in the filter. */
481 outn("#line 0 \"M4_YY_OUTFILE_NAME\"\n");
483 /* Dump the user defined preproc directives. */
484 if (userdef_buf
.elts
)
485 outn ((char *) (userdef_buf
.elts
));
491 /* flexend - terminate flex
494 * This routine does not return.
497 void flexend (exit_status
)
501 static int called_before
= -1; /* prevent infinite recursion. */
505 FLEX_EXIT (exit_status
);
507 if (skelfile
!= NULL
) {
508 if (ferror (skelfile
))
509 lerrsf (_("input error reading skeleton file %s"),
512 else if (fclose (skelfile
))
513 lerrsf (_("error closing skeleton file %s"),
519 "#ifdef YY_HEADER_EXPORT_START_CONDITIONS\n");
521 "/* Beware! Start conditions are not prefixed. */\n");
523 /* Special case for "INITIAL" */
525 "#undef INITIAL\n#define INITIAL 0\n");
526 for (i
= 2; i
<= lastsc
; i
++)
527 fprintf (header_out
, "#define %s %d\n", scname
[i
], i
- 1);
529 "#endif /* YY_HEADER_EXPORT_START_CONDITIONS */\n\n");
531 /* Kill ALL flex-related macros. This is so the user
532 * can #include more than one generated header file. */
533 fprintf (header_out
, "#ifndef YY_HEADER_NO_UNDEFS\n");
535 "/* Undefine all internal macros, etc., that do no belong in the header. */\n\n");
538 const char * undef_list
[] = {
542 "EOB_ACT_CONTINUE_SCAN",
543 "EOB_ACT_END_OF_FILE",
544 "EOB_ACT_LAST_MATCH",
556 "YY_BUFFER_EOF_PENDING",
560 "M4_YY_CALL_LAST_ARG",
561 "M4_YY_CALL_ONLY_ARG",
564 "M4_YY_DECL_LAST_ARG",
565 "M4_YY_DEF_LAST_ARG",
566 "M4_YY_DEF_ONLY_ARG",
567 "YY_DO_BEFORE_ACTION",
569 "YY_END_OF_BUFFER_CHAR",
573 "YY_FLEX_DEFINED_ECHO",
574 "YY_FLEX_LEX_COMPAT",
575 "YY_FLEX_MAJOR_VERSION",
576 "YY_FLEX_MINOR_VERSION",
577 "YY_FLEX_SUBMINOR_VERSION",
586 "YY_LEX_DECLARATION",
597 "M4_YY_PROTO_LAST_ARG",
598 "M4_YY_PROTO_ONLY_ARG void",
601 "YY_RESTORE_YY_MORE_OFFSET",
606 "YY_START_STACK_INCR",
609 "YY_TRAILING_HEAD_MASK",
621 "yy_load_buffer_state",
627 "yy_set_interactive",
628 "yy_switch_to_buffer",
629 "yypush_buffer_state",
630 "yypop_buffer_state",
631 "yyensure_buffer_stack",
673 /* must be null-terminated */
677 for (i
=0; undef_list
[i
] != NULL
; i
++)
678 fprintf (header_out
, "#undef %s\n", undef_list
[i
]);
681 /* undef any of the auto-generated symbols. */
682 for (i
= 0; i
< defs_buf
.nelts
; i
++) {
684 /* don't undef start conditions */
685 if (sclookup (((char **) defs_buf
.elts
)[i
]) > 0)
687 fprintf (header_out
, "#undef %s\n",
688 ((char **) defs_buf
.elts
)[i
]);
692 "#endif /* !YY_HEADER_NO_UNDEFS */\n");
693 fprintf (header_out
, "\n");
694 fprintf (header_out
, "#undef %sIN_HEADER\n", prefix
);
695 fprintf (header_out
, "#endif /* %sHEADER_H */\n", prefix
);
697 if (ferror (header_out
))
698 lerrsf (_("error creating header file %s"),
704 if (exit_status
!= 0 && outfile_created
) {
706 lerrsf (_("error writing output file %s"),
709 else if ((_stdout_closed
= 1) && fclose (stdout
))
710 lerrsf (_("error closing output file %s"),
713 else if (unlink (outfilename
))
714 lerrsf (_("error deleting output file %s"),
719 if (backing_up_report
&& backing_up_file
) {
720 if (num_backing_up
== 0)
721 fprintf (backing_up_file
, _("No backing up.\n"));
722 else if (fullspd
|| fulltbl
)
723 fprintf (backing_up_file
,
725 ("%d backing up (non-accepting) states.\n"),
728 fprintf (backing_up_file
,
729 _("Compressed tables always back up.\n"));
731 if (ferror (backing_up_file
))
732 lerrsf (_("error writing backup file %s"),
735 else if (fclose (backing_up_file
))
736 lerrsf (_("error closing backup file %s"),
741 fprintf (stderr
, _("%s version %s usage statistics:\n"),
742 program_name
, flex_version
);
744 fprintf (stderr
, _(" scanner options: -"));
748 if (backing_up_report
)
758 if (performance_report
> 0)
760 if (performance_report
> 1)
765 fputs ("--reentrant", stderr
);
766 if (bison_bridge_lval
)
767 fputs ("--bison-bridge", stderr
);
768 if (bison_bridge_lloc
)
769 fputs ("--bison-locations", stderr
);
773 putc ('v', stderr
); /* always true! */
776 if (interactive
== false)
778 if (interactive
== true)
785 if (csize
== unspecified
)
786 /* We encountered an error fairly early on, so csize
787 * never got specified. Define it now, to prevent
788 * bogus table sizes being written out below.
797 fprintf (stderr
, " -C");
813 fprintf (stderr
, " -o%s", outfilename
);
816 fprintf (stderr
, " -S%s", skelname
);
818 if (strcmp (prefix
, "yy"))
819 fprintf (stderr
, " -P%s", prefix
);
823 fprintf (stderr
, _(" %d/%d NFA states\n"),
824 lastnfa
, current_mns
);
825 fprintf (stderr
, _(" %d/%d DFA states (%d words)\n"),
826 lastdfa
, current_max_dfas
, totnst
);
827 fprintf (stderr
, _(" %d rules\n"),
828 num_rules
+ num_eof_rules
-
829 1 /* - 1 for def. rule */ );
831 if (num_backing_up
== 0)
832 fprintf (stderr
, _(" No backing up\n"));
833 else if (fullspd
|| fulltbl
)
836 (" %d backing-up (non-accepting) states\n"),
841 (" Compressed tables always back-up\n"));
845 _(" Beginning-of-line patterns used\n"));
847 fprintf (stderr
, _(" %d/%d start conditions\n"), lastsc
,
851 (" %d epsilon states, %d double epsilon states\n"),
855 fprintf (stderr
, _(" no character classes\n"));
859 (" %d/%d character classes needed %d/%d words of storage, %d reused\n"),
860 lastccl
, current_maxccls
,
861 cclmap
[lastccl
] + ccllen
[lastccl
],
862 current_max_ccl_tbl_size
, cclreuse
);
864 fprintf (stderr
, _(" %d state/nextstate pairs created\n"),
867 _(" %d/%d unique/duplicate transitions\n"),
871 tblsiz
= lastdfa
* numecs
;
872 fprintf (stderr
, _(" %d table entries\n"),
877 tblsiz
= 2 * (lastdfa
+ numtemps
) + 2 * tblend
;
880 _(" %d/%d base-def entries created\n"),
881 lastdfa
+ numtemps
, current_max_dfas
);
884 (" %d/%d (peak %d) nxt-chk entries created\n"),
885 tblend
, current_max_xpairs
, peakpairs
);
888 (" %d/%d (peak %d) template nxt-chk entries created\n"),
890 current_max_template_xpairs
,
892 fprintf (stderr
, _(" %d empty table entries\n"),
894 fprintf (stderr
, _(" %d protos created\n"),
897 _(" %d templates created, %d uses\n"),
902 tblsiz
= tblsiz
+ csize
;
905 (" %d/%d equivalence classes created\n"),
910 tblsiz
= tblsiz
+ numecs
;
913 (" %d/%d meta-equivalence classes created\n"),
919 (" %d (%d saved) hash collisions, %d DFAs equal\n"),
920 hshcol
, hshsave
, dfaeql
);
921 fprintf (stderr
, _(" %d sets of reallocations needed\n"),
923 fprintf (stderr
, _(" %d total table entries needed\n"),
927 FLEX_EXIT (exit_status
);
931 /* flexinit - initialize flex */
933 void flexinit (argc
, argv
)
937 int i
, sawcmpflag
, rv
, optind
;
941 printstats
= syntaxerror
= trace
= spprdflt
= false;
942 lex_compat
= posix_compat
= C_plus_plus
= backing_up_report
=
943 ddebug
= fulltbl
= false;
944 fullspd
= long_align
= nowarn
= yymore_used
= continued_action
=
946 do_yylineno
= yytext_is_array
= in_rule
= reject
= do_stdinit
=
948 yymore_really_used
= reject_really_used
= unspecified
;
949 interactive
= csize
= unspecified
;
950 do_yywrap
= gen_line_dirs
= usemecs
= useecs
= true;
951 reentrant
= bison_bridge_lval
= bison_bridge_lloc
= false;
952 performance_report
= 0;
956 use_read
= use_stdout
= false;
957 tablesext
= tablesverify
= false;
959 tablesfilename
= tablesname
= NULL
;
960 ansi_func_defs
= ansi_func_protos
= true;
964 /* Initialize dynamic array for holding the rule actions. */
965 action_size
= 2048; /* default size of action array in bytes */
966 action_array
= allocate_character_array (action_size
);
967 defs1_offset
= prolog_offset
= action_offset
= action_index
= 0;
968 action_array
[0] = '\0';
970 /* Initialize any buffers. */
971 buf_init (&userdef_buf
, sizeof (char)); /* one long string */
972 buf_init (&defs_buf
, sizeof (char *)); /* list of strings */
973 buf_init (&yydmap_buf
, sizeof (char)); /* one long string */
974 buf_init (&top_buf
, sizeof (char)); /* one long string */
977 const char * m4defs_init_str
[] = {"m4_changequote\n",
978 "m4_changequote([[, ]])\n"};
979 buf_init (&m4defs_buf
, sizeof (char *));
980 buf_append (&m4defs_buf
, &m4defs_init_str
, 2);
985 /* initialize regex lib */
988 /* Enable C++ if program name ends with '+'. */
989 program_name
= basename2 (argv
[0], 0);
991 if (program_name
[0] != '\0' &&
992 program_name
[strlen (program_name
) - 1] == '+')
996 sopt
= scanopt_init (flexopts
, argc
, argv
, 0);
998 /* This will only happen when flexopts array is altered. */
1000 _("Internal error. flexopts are malformed.\n"));
1004 while ((rv
= scanopt (sopt
, &arg
, &optind
)) != 0) {
1007 /* Scanopt has already printed an option-specific error message. */
1010 ("Try `%s --help' for more information.\n"),
1015 switch ((enum flexopt_flag_t
) rv
) {
1021 interactive
= false;
1025 backing_up_report
= true;
1031 case OPT_COMPRESSION
:
1039 for (i
= 0; arg
&& arg
[i
] != '\0'; i
++)
1067 ("unknown -C option '%c'"),
1082 useecs
= usemecs
= false;
1083 use_read
= fulltbl
= true;
1087 useecs
= usemecs
= false;
1088 use_read
= fullspd
= true;
1095 case OPT_INTERACTIVE
:
1099 case OPT_CASE_INSENSITIVE
:
1100 sf_set_case_ins(true);
1103 case OPT_LEX_COMPAT
:
1107 case OPT_POSIX_COMPAT
:
1108 posix_compat
= true;
1111 case OPT_PREPROC_LEVEL
:
1112 preproc_level
= strtol(arg
,NULL
,0);
1116 buf_strdefine (&userdef_buf
, "YY_MAIN", "1");
1121 buf_strdefine (&userdef_buf
, "YY_MAIN", "0");
1125 gen_line_dirs
= false;
1130 did_outfilename
= 1;
1137 case OPT_PERF_REPORT
:
1138 ++performance_report
;
1141 case OPT_BISON_BRIDGE
:
1142 bison_bridge_lval
= true;
1145 case OPT_BISON_BRIDGE_LOCATIONS
:
1146 bison_bridge_lval
= bison_bridge_lloc
= true;
1153 case OPT_NO_REENTRANT
:
1165 case OPT_NO_DEFAULT
:
1173 case OPT_NO_UNISTD_H
:
1174 //buf_strdefine (&userdef_buf, "YY_NO_UNISTD_H", "1");
1175 buf_m4_define( &m4defs_buf
, "M4_YY_NO_UNISTD_H",0);
1178 case OPT_TABLES_FILE
:
1180 tablesfilename
= arg
;
1183 case OPT_TABLES_VERIFY
:
1184 tablesverify
= true;
1196 printf (_("%s %s\n"), program_name
, flex_version
);
1223 case OPT_ALWAYS_INTERACTIVE
:
1224 buf_m4_define (&m4defs_buf
, "M4_YY_ALWAYS_INTERACTIVE", 0);
1227 case OPT_NEVER_INTERACTIVE
:
1228 buf_m4_define( &m4defs_buf
, "M4_YY_NEVER_INTERACTIVE", 0);
1232 yytext_is_array
= true;
1236 yytext_is_array
= false;
1247 case OPT_HEADER_FILE
:
1248 headerfilename
= arg
;
1255 case OPT_NO_META_ECS
:
1259 case OPT_PREPROCDEFINE
:
1261 /* arg is "symbol" or "symbol=definition". */
1265 *def
!= '\0' && *def
!= '='; ++def
) ;
1267 buf_strappend (&userdef_buf
, "#define ");
1269 buf_strappend (&userdef_buf
, arg
);
1270 buf_strappend (&userdef_buf
,
1274 buf_strnappend (&userdef_buf
, arg
,
1276 buf_strappend (&userdef_buf
, " ");
1277 buf_strappend (&userdef_buf
,
1279 buf_strappend (&userdef_buf
, "\n");
1289 //buf_strdefine (&userdef_buf, "YY_STACK_USED", "1");
1290 buf_m4_define( &m4defs_buf
, "M4_YY_STACK_USED",0);
1297 case OPT_NO_STDINIT
:
1309 case OPT_NO_YYLINENO
:
1310 do_yylineno
= false;
1322 yymore_really_used
= true;
1326 yymore_really_used
= false;
1330 reject_really_used
= true;
1334 reject_really_used
= false;
1337 case OPT_NO_ANSI_FUNC_DEFS
:
1338 ansi_func_defs
= false;
1341 case OPT_NO_ANSI_FUNC_PROTOS
:
1342 ansi_func_protos
= false;
1345 case OPT_NO_YY_PUSH_STATE
:
1346 //buf_strdefine (&userdef_buf, "YY_NO_PUSH_STATE", "1");
1347 buf_m4_define( &m4defs_buf
, "M4_YY_NO_PUSH_STATE",0);
1349 case OPT_NO_YY_POP_STATE
:
1350 //buf_strdefine (&userdef_buf, "YY_NO_POP_STATE", "1");
1351 buf_m4_define( &m4defs_buf
, "M4_YY_NO_POP_STATE",0);
1353 case OPT_NO_YY_TOP_STATE
:
1354 //buf_strdefine (&userdef_buf, "YY_NO_TOP_STATE", "1");
1355 buf_m4_define( &m4defs_buf
, "M4_YY_NO_TOP_STATE",0);
1358 //buf_strdefine (&userdef_buf, "YY_NO_UNPUT", "1");
1359 buf_m4_define( &m4defs_buf
, "M4_YY_NO_UNPUT",0);
1361 case OPT_NO_YY_SCAN_BUFFER
:
1362 //buf_strdefine (&userdef_buf, "YY_NO_SCAN_BUFFER", "1");
1363 buf_m4_define( &m4defs_buf
, "M4_YY_NO_SCAN_BUFFER",0);
1365 case OPT_NO_YY_SCAN_BYTES
:
1366 //buf_strdefine (&userdef_buf, "YY_NO_SCAN_BYTES", "1");
1367 buf_m4_define( &m4defs_buf
, "M4_YY_NO_SCAN_BYTES",0);
1369 case OPT_NO_YY_SCAN_STRING
:
1370 //buf_strdefine (&userdef_buf, "YY_NO_SCAN_STRING", "1");
1371 buf_m4_define( &m4defs_buf
, "M4_YY_NO_SCAN_STRING",0);
1373 case OPT_NO_YYGET_EXTRA
:
1374 //buf_strdefine (&userdef_buf, "YY_NO_GET_EXTRA", "1");
1375 buf_m4_define( &m4defs_buf
, "M4_YY_NO_GET_EXTRA",0);
1377 case OPT_NO_YYSET_EXTRA
:
1378 //buf_strdefine (&userdef_buf, "YY_NO_SET_EXTRA", "1");
1379 buf_m4_define( &m4defs_buf
, "M4_YY_NO_SET_EXTRA",0);
1381 case OPT_NO_YYGET_LENG
:
1382 //buf_strdefine (&userdef_buf, "YY_NO_GET_LENG", "1");
1383 buf_m4_define( &m4defs_buf
, "M4_YY_NO_GET_LENG",0);
1385 case OPT_NO_YYGET_TEXT
:
1386 //buf_strdefine (&userdef_buf, "YY_NO_GET_TEXT", "1");
1387 buf_m4_define( &m4defs_buf
, "M4_YY_NO_GET_TEXT",0);
1389 case OPT_NO_YYGET_LINENO
:
1390 //buf_strdefine (&userdef_buf, "YY_NO_GET_LINENO", "1");
1391 buf_m4_define( &m4defs_buf
, "M4_YY_NO_GET_LINENO",0);
1393 case OPT_NO_YYSET_LINENO
:
1394 //buf_strdefine (&userdef_buf, "YY_NO_SET_LINENO", "1");
1395 buf_m4_define( &m4defs_buf
, "M4_YY_NO_SET_LINENO",0);
1397 case OPT_NO_YYGET_IN
:
1398 //buf_strdefine (&userdef_buf, "YY_NO_GET_IN", "1");
1399 buf_m4_define( &m4defs_buf
, "M4_YY_NO_GET_IN",0);
1401 case OPT_NO_YYSET_IN
:
1402 //buf_strdefine (&userdef_buf, "YY_NO_SET_IN", "1");
1403 buf_m4_define( &m4defs_buf
, "M4_YY_NO_SET_IN",0);
1405 case OPT_NO_YYGET_OUT
:
1406 //buf_strdefine (&userdef_buf, "YY_NO_GET_OUT", "1");
1407 buf_m4_define( &m4defs_buf
, "M4_YY_NO_GET_OUT",0);
1409 case OPT_NO_YYSET_OUT
:
1410 //buf_strdefine (&userdef_buf, "YY_NO_SET_OUT", "1");
1411 buf_m4_define( &m4defs_buf
, "M4_YY_NO_SET_OUT",0);
1413 case OPT_NO_YYGET_LVAL
:
1414 //buf_strdefine (&userdef_buf, "YY_NO_GET_LVAL", "1");
1415 buf_m4_define( &m4defs_buf
, "M4_YY_NO_GET_LVAL",0);
1417 case OPT_NO_YYSET_LVAL
:
1418 //buf_strdefine (&userdef_buf, "YY_NO_SET_LVAL", "1");
1419 buf_m4_define( &m4defs_buf
, "M4_YY_NO_SET_LVAL",0);
1421 case OPT_NO_YYGET_LLOC
:
1422 //buf_strdefine (&userdef_buf, "YY_NO_GET_LLOC", "1");
1423 buf_m4_define( &m4defs_buf
, "M4_YY_NO_GET_LLOC",0);
1425 case OPT_NO_YYSET_LLOC
:
1426 //buf_strdefine (&userdef_buf, "YY_NO_SET_LLOC", "1");
1427 buf_m4_define( &m4defs_buf
, "M4_YY_NO_SET_LLOC",0);
1431 } /* while scanopt() */
1433 scanopt_destroy (sopt
);
1435 num_input_files
= argc
- optind
;
1436 input_files
= argv
+ optind
;
1437 set_input_file (num_input_files
> 0 ? input_files
[0] : NULL
);
1439 lastccl
= lastsc
= lastdfa
= lastnfa
= 0;
1440 num_rules
= num_eof_rules
= default_rule
= 0;
1441 numas
= numsnpairs
= tmpuses
= 0;
1442 numecs
= numeps
= eps2
= num_reallocs
= hshcol
= dfaeql
= totnst
=
1444 numuniq
= numdup
= hshsave
= eofseen
= datapos
= dataline
= 0;
1445 num_backing_up
= onesp
= numprots
= 0;
1446 variable_trailing_context_rules
= bol_needed
= false;
1448 linenum
= sectnum
= 1;
1451 /* Used in mkprot() so that the first proto goes in slot 1
1452 * of the proto queue.
1456 set_up_initial_allocations ();
1460 /* readin - read in the rules section of the input file(s) */
1464 static char yy_stdinit
[] = "FILE *yyin = stdin, *yyout = stdout;";
1465 static char yy_nostdinit
[] =
1466 "FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;";
1468 line_directive_out ((FILE *) 0, 1);
1471 pinpoint_message (_("fatal parse error"));
1478 /* If the user explicitly requested posix compatibility by specifing the
1479 * posix-compat option, then we check for conflicting options. However, if
1480 * the POSIXLY_CORRECT variable is set, then we quietly make flex as
1481 * posix-compatible as possible. This is the recommended behavior
1482 * according to the GNU Coding Standards.
1484 * Note: The posix option was added to flex to provide the posix behavior
1485 * of the repeat operator in regular expressions, e.g., `ab{3}'
1488 /* TODO: This is where we try to make flex behave according to
1489 * posiz, AND check for conflicting options. How far should we go
1490 * with this? Should we disable all the neat-o flex features?
1492 /* Update: Estes says no, since other flex features don't violate posix. */
1495 if (getenv ("POSIXLY_CORRECT")) {
1496 posix_compat
= true;
1499 if (backing_up_report
) {
1500 backing_up_file
= fopen (backing_name
, "w");
1501 if (backing_up_file
== NULL
)
1503 ("could not create backing-up info file %s"),
1508 backing_up_file
= NULL
;
1510 if (yymore_really_used
== true)
1512 else if (yymore_really_used
== false)
1513 yymore_used
= false;
1515 if (reject_really_used
== true)
1517 else if (reject_really_used
== false)
1520 if (performance_report
> 0) {
1524 ("-l AT&T lex compatibility option entails a large performance penalty\n"));
1527 (" and may be the actual source of other reported performance penalties\n"));
1530 else if (do_yylineno
) {
1533 ("%%option yylineno entails a performance penalty ONLY on rules that can match newline characters\n"));
1536 if (performance_report
> 1) {
1540 ("-I (interactive) entails a minor performance penalty\n"));
1545 ("yymore() entails a minor performance penalty\n"));
1551 ("REJECT entails a large performance penalty\n"));
1553 if (variable_trailing_context_rules
)
1556 ("Variable trailing context rules entail a large performance penalty\n"));
1562 if (variable_trailing_context_rules
)
1565 if ((fulltbl
|| fullspd
) && reject
) {
1568 ("REJECT cannot be used with -f or -F"));
1569 else if (do_yylineno
)
1571 ("%option yylineno cannot be used with REJECT"));
1574 ("variable trailing context rules cannot be used with -f or -F"));
1578 out_m4_define( "M4_YY_USES_REJECT", NULL
);
1579 //outn ("\n#define YY_USES_REJECT");
1585 outn ("\n#define yywrap(yyscanner) (/*CONSTCOND*/1)");
1587 outn ("\n#define yywrap() (/*CONSTCOND*/1)");
1589 outn ("#define YY_SKIP_YYWRAP");
1593 outn ("\n#define FLEX_DEBUG");
1597 outn ("typedef unsigned char YY_CHAR;");
1599 outn ("typedef char YY_CHAR;");
1603 outn ("#define yytext_ptr yytext");
1606 outn ("#define YY_INTERACTIVE");
1611 /* In reentrant scanner, stdinit is handled in flex.skl. */
1614 outn ("#ifdef VMS");
1615 outn ("#ifdef __VMS_POSIX");
1616 outn ("#define YY_STDINIT");
1619 outn ("#define YY_STDINIT");
1623 outn ("#ifdef VMS");
1624 outn ("#ifndef __VMS_POSIX");
1625 outn (yy_nostdinit
);
1636 outn (yy_nostdinit
);
1643 outn ("typedef yyconst struct yy_trans_info *yy_state_type;");
1644 else if (!C_plus_plus
)
1645 outn ("typedef int yy_state_type;");
1649 outn ("#define YY_FLEX_LEX_COMPAT");
1651 if (!C_plus_plus
&& !reentrant
) {
1652 outn ("extern int yylineno;");
1654 outn ("int yylineno = 1;");
1659 outn ("\n#include <FlexLexer.h>");
1662 outn("\nint yyFlexLexer::yywrap() { return 1; }");
1666 outn ("int yyFlexLexer::yylex()");
1668 outn ("\tLexerError( \"yyFlexLexer::yylex invoked but %option yyclass used\" );");
1669 outn ("\treturn 0;");
1672 out_str ("\n#define YY_DECL int %s::yylex()\n",
1679 /* Watch out: yytext_ptr is a variable when yytext is an array,
1680 * but it's a macro when yytext is a pointer.
1682 if (yytext_is_array
) {
1684 outn ("extern char yytext[];\n");
1688 outn ("#define yytext_ptr yytext_r");
1691 outn ("extern char *yytext;");
1692 outn ("#define yytext_ptr yytext");
1698 ("%option yyclass only meaningful for C++ scanners"));
1702 numecs
= cre8ecs (nextecm
, ecgroup
, csize
);
1706 /* Now map the equivalence class for NUL to its expected place. */
1707 ecgroup
[0] = ecgroup
[csize
];
1708 NUL_ec
= ABS (ecgroup
[0]);
1715 /* set_up_initial_allocations - allocate memory for internal tables */
1717 void set_up_initial_allocations ()
1719 maximum_mns
= (long_align
? MAXIMUM_MNS_LONG
: MAXIMUM_MNS
);
1720 current_mns
= INITIAL_MNS
;
1721 firstst
= allocate_integer_array (current_mns
);
1722 lastst
= allocate_integer_array (current_mns
);
1723 finalst
= allocate_integer_array (current_mns
);
1724 transchar
= allocate_integer_array (current_mns
);
1725 trans1
= allocate_integer_array (current_mns
);
1726 trans2
= allocate_integer_array (current_mns
);
1727 accptnum
= allocate_integer_array (current_mns
);
1728 assoc_rule
= allocate_integer_array (current_mns
);
1729 state_type
= allocate_integer_array (current_mns
);
1731 current_max_rules
= INITIAL_MAX_RULES
;
1732 rule_type
= allocate_integer_array (current_max_rules
);
1733 rule_linenum
= allocate_integer_array (current_max_rules
);
1734 rule_useful
= allocate_integer_array (current_max_rules
);
1735 rule_has_nl
= allocate_bool_array (current_max_rules
);
1737 current_max_scs
= INITIAL_MAX_SCS
;
1738 scset
= allocate_integer_array (current_max_scs
);
1739 scbol
= allocate_integer_array (current_max_scs
);
1740 scxclu
= allocate_integer_array (current_max_scs
);
1741 sceof
= allocate_integer_array (current_max_scs
);
1742 scname
= allocate_char_ptr_array (current_max_scs
);
1744 current_maxccls
= INITIAL_MAX_CCLS
;
1745 cclmap
= allocate_integer_array (current_maxccls
);
1746 ccllen
= allocate_integer_array (current_maxccls
);
1747 cclng
= allocate_integer_array (current_maxccls
);
1748 ccl_has_nl
= allocate_bool_array (current_maxccls
);
1750 current_max_ccl_tbl_size
= INITIAL_MAX_CCL_TBL_SIZE
;
1751 ccltbl
= allocate_Character_array (current_max_ccl_tbl_size
);
1753 current_max_dfa_size
= INITIAL_MAX_DFA_SIZE
;
1755 current_max_xpairs
= INITIAL_MAX_XPAIRS
;
1756 nxt
= allocate_integer_array (current_max_xpairs
);
1757 chk
= allocate_integer_array (current_max_xpairs
);
1759 current_max_template_xpairs
= INITIAL_MAX_TEMPLATE_XPAIRS
;
1760 tnxt
= allocate_integer_array (current_max_template_xpairs
);
1762 current_max_dfas
= INITIAL_MAX_DFAS
;
1763 base
= allocate_integer_array (current_max_dfas
);
1764 def
= allocate_integer_array (current_max_dfas
);
1765 dfasiz
= allocate_integer_array (current_max_dfas
);
1766 accsiz
= allocate_integer_array (current_max_dfas
);
1767 dhash
= allocate_integer_array (current_max_dfas
);
1768 dss
= allocate_int_ptr_array (current_max_dfas
);
1769 dfaacc
= allocate_dfaacc_union (current_max_dfas
);
1771 nultrans
= (int *) 0;
1775 /* extracts basename from path, optionally stripping the extension "\.*"
1776 * (same concept as /bin/sh `basename`, but different handling of extension). */
1777 static char *basename2 (path
, strip_ext
)
1779 int strip_ext
; /* boolean */
1784 for (b
= path
; *path
; path
++)
1787 else if (*path
== '.')
1790 if (strip_ext
&& e
&& e
> b
)
1799 if (!did_outfilename
) {
1800 snprintf (outfile_path
, sizeof(outfile_path
), outfile_template
,
1801 prefix
, C_plus_plus
? "cc" : "c");
1802 outfilename
= outfile_path
;
1805 fprintf (f
, _("Usage: %s [OPTIONS] [FILE]...\n"), program_name
);
1808 ("Generates programs that perform pattern-matching on text.\n"
1809 "\n" "Table Compression:\n"
1810 " -Ca, --align trade off larger tables for better memory alignment\n"
1811 " -Ce, --ecs construct equivalence classes\n"
1812 " -Cf do not compress tables; use -f representation\n"
1813 " -CF do not compress tables; use -F representation\n"
1814 " -Cm, --meta-ecs construct meta-equivalence classes\n"
1815 " -Cr, --read use read() instead of stdio for scanner input\n"
1816 " -f, --full generate fast, large scanner. Same as -Cfr\n"
1817 " -F, --fast use alternate table representation. Same as -CFr\n"
1818 " -Cem default compression (same as --ecs --meta-ecs)\n"
1820 " -d, --debug enable debug mode in scanner\n"
1821 " -b, --backup write backing-up information to %s\n"
1822 " -p, --perf-report write performance report to stderr\n"
1823 " -s, --nodefault suppress default rule to ECHO unmatched text\n"
1824 " -T, --trace %s should run in trace mode\n"
1825 " -w, --nowarn do not generate warnings\n"
1826 " -v, --verbose write summary of scanner statistics to stdout\n"
1828 " -o, --outfile=FILE specify output filename\n"
1829 " -S, --skel=FILE specify skeleton file\n"
1830 " -t, --stdout write scanner on stdout instead of %s\n"
1831 " --yyclass=NAME name of C++ class\n"
1832 " --header-file=FILE create a C header file in addition to the scanner\n"
1833 " --tables-file[=FILE] write tables to FILE\n" "\n"
1834 "Scanner behavior:\n"
1835 " -7, --7bit generate 7-bit scanner\n"
1836 " -8, --8bit generate 8-bit scanner\n"
1837 " -B, --batch generate batch scanner (opposite of -I)\n"
1838 " -i, --case-insensitive ignore case in patterns\n"
1839 " -l, --lex-compat maximal compatibility with original lex\n"
1840 " -X, --posix-compat maximal compatibility with POSIX lex\n"
1841 " -I, --interactive generate interactive scanner (opposite of -B)\n"
1842 " --yylineno track line count in yylineno\n"
1843 "\n" "Generated code:\n"
1844 " -+, --c++ generate C++ scanner class\n"
1845 " -Dmacro[=defn] #define macro defn (default defn is '1')\n"
1846 " -L, --noline suppress #line directives in scanner\n"
1847 " -P, --prefix=STRING use STRING as prefix instead of \"yy\"\n"
1848 " -R, --reentrant generate a reentrant C scanner\n"
1849 " --bison-bridge scanner for bison pure parser.\n"
1850 " --bison-locations include yylloc support.\n"
1851 " --stdinit initialize yyin/yyout to stdin/stdout\n"
1852 " --noansi-definitions old-style function definitions\n"
1853 " --noansi-prototypes empty parameter list in prototypes\n"
1854 " --nounistd do not include <unistd.h>\n"
1855 " --noFUNCTION do not generate a particular FUNCTION\n"
1856 "\n" "Miscellaneous:\n"
1857 " -c do-nothing POSIX option\n"
1858 " -n do-nothing POSIX option\n"
1860 " -h, --help produce this help message\n"
1861 " -V, --version report %s version\n"),
1862 backing_name
, program_name
, outfile_path
, program_name
);