/* flex - tool to generate fast lexical analyzers */
/* Copyright (c) 1990 The Regents of the University of California. */ /* All rights reserved. */
/* This code is derived from software contributed to Berkeley by */ /* Vern Paxson. */
/* The United States Government has rights in this work pursuant */ /* to contract no. DE-AC03-76SF00098 between the United States */ /* Department of Energy and the University of California. */
/* This file is part of flex. */
/* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */
/* 1. Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* 2. Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in the */ /* documentation and/or other materials provided with the distribution. */
/* Neither the name of the University nor the names of its contributors */ /* may be used to endorse or promote products derived from this software */ /* without specific prior written permission. */
/* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR */ /* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED */ /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR */ /* PURPOSE. */
/* declare functions that have forward references */
void flexinit PROTO ((int, char **)); void readin PROTO ((void)); void set_up_initial_allocations PROTO ((void)); staticchar *basename2 PROTO ((char *path, int should_strip_ext));
/* these globals are all defined and commented in flexdef.h */ int printstats, syntaxerror, eofseen, ddebug, trace, nowarn, spprdflt; int interactive, lex_compat, posix_compat, do_yylineno,
useecs, fulltbl, usemecs; int fullspd, gen_line_dirs, performance_report, backing_up_report; int C_plus_plus, long_align, use_read, yytext_is_array, do_yywrap,
csize; int reentrant, bison_bridge_lval, bison_bridge_lloc; int yymore_used, reject, real_reject, continued_action, in_rule; int yymore_really_used, reject_really_used; int trace_hex = 0; int datapos, dataline, linenum;
FILE *skelfile = NULL; int skel_ind = 0; char *action_array; int action_size, defs1_offset, prolog_offset, action_offset,
action_index; char *infilename = NULL, *outfilename = NULL, *headerfilename = NULL; int did_outfilename; char *prefix, *yyclass, *extra_type = NULL; int do_stdinit, use_stdout; int onestate[ONE_STACK_SIZE], onesym[ONE_STACK_SIZE]; int onenext[ONE_STACK_SIZE], onedef[ONE_STACK_SIZE], onesp; int maximum_mns, current_mns, current_max_rules; int num_rules, num_eof_rules, default_rule, lastnfa; int *firstst, *lastst, *finalst, *transchar, *trans1, *trans2; int *accptnum, *assoc_rule, *state_type; int *rule_type, *rule_linenum, *rule_useful; int current_state_type; int variable_trailing_context_rules; int numtemps, numprots, protprev[MSP], protnext[MSP], prottbl[MSP]; int protcomst[MSP], firstprot, lastprot, protsave[PROT_SAVE_SIZE]; int numecs, nextecm[CSIZE + 1], ecgroup[CSIZE + 1], nummecs,
tecfwd[CSIZE + 1]; int tecbck[CSIZE + 1]; int lastsc, *scset, *scbol, *scxclu, *sceof; int current_max_scs; char **scname; int current_max_dfa_size, current_max_xpairs; int current_max_template_xpairs, current_max_dfas; int lastdfa, *nxt, *chk, *tnxt; int *base, *def, *nultrans, NUL_ec, tblend, firstfree, **dss, *dfasiz; union dfaacc_union *dfaacc; int *accsiz, *dhash, numas; int numsnpairs, jambase, jamstate; int lastccl, *cclmap, *ccllen, *cclng, cclreuse; int current_maxccls, current_max_ccl_tbl_size; Char *ccltbl; char nmstr[MAXLINE]; int sectnum, nummt, hshcol, dfaeql, numeps, eps2, num_reallocs; int tmpuses, totnst, peakpairs, numuniq, numdup, hshsave; int num_backing_up, bol_needed;
FILE *backing_up_file; int end_of_buffer_state; char **input_files; int num_input_files;
jmp_buf flex_main_jmp_buf; bool *rule_has_nl, *ccl_has_nl; int nlch = '\n'; bool ansi_func_defs, ansi_func_protos;
/* Make sure program_name is initialized so we don't crash if writing *outanerrormessagebeforegettingtheprogramnamefromargv[0].
*/ char *program_name = "flex";
staticchar outfile_path[MAXLINE]; staticint outfile_created = 0; staticchar *skelname = NULL; staticint _stdout_closed = 0; /* flag to prevent double-fclose() on stdout. */ constchar *escaped_qstart = "[[]]M4_YY_NOOP[M4_YY_NOOP[M4_YY_NOOP[[]]"; constchar *escaped_qend = "[[]]M4_YY_NOOP]M4_YY_NOOP]M4_YY_NOOP[[]]";
/* For debugging. The max number of filters to apply to skeleton. */ staticint preproc_level = 1000;
int flex_main PROTO ((int argc, char *argv[])); int main PROTO ((int argc, char *argv[]));
int flex_main (argc, argv) int argc; char *argv[];
{ int i, exit_status, child_status;
/* Set a longjmp target. Yes, I know it's a hack, but it gets worse: The *returnvalueofsetjmp,ifnon-zero,isthedesiredexitcodePLUSONE. *Forexample,ifyouwant'main'toreturnwithcode'2',thencall *longjmp()withanargumentof3.Thisisbecauseitisinvalidto *specifyavalueof0tolongjmp.FLEX_EXIT(n)shouldbeusedinsteadof *exit(n);
*/
exit_status = setjmp (flex_main_jmp_buf); if (exit_status){ if (stdout && !_stdout_closed && !ferror(stdout)){
fflush(stdout);
fclose(stdout);
} while (wait(&child_status) > 0){ if (!WIFEXITED (child_status)
|| WEXITSTATUS (child_status) != 0){ /* report an error of a child
*/ if( exit_status <= 1 )
exit_status = 2;
}
} return exit_status - 1;
}
flexinit (argc, argv);
readin ();
skelout (); /* %% [1.5] DFA */
ntod ();
for (i = 1; i <= num_rules; ++i) if (!rule_useful[i] && i != default_rule)
line_warning (_("rule cannot be matched"),
rule_linenum[i]);
if (spprdflt && !reject && rule_useful[default_rule])
line_warning (_
("-s option given but default rule can be matched"),
rule_linenum[default_rule]);
/* Generate the C state transition tables from the DFA. */
make_tables ();
/* Note, flexend does not return. It exits with its argument *asstatus.
*/
flexend (0);
return0; /* keep compilers/lint happy */
}
/* Wrapper around flex_main, so flex_main can be built as a library. */ int main (argc, argv) int argc; char *argv[];
{ #if ENABLE_NLS #if HAVE_LOCALE_H
setlocale (LC_MESSAGES, "");
setlocale (LC_CTYPE, "");
textdomain (PACKAGE);
bindtextdomain (PACKAGE, LOCALEDIR); #endif #endif
#if0 /* This makes no sense whatsoever. I'm removing it. */ if (do_yylineno) /* This should really be "maintain_backup_tables = true" */
reject_really_used = true; #endif
if (csize == unspecified) { if ((fulltbl || fullspd) && !useecs)
csize = DEFAULT_CSIZE; else
csize = CSIZE;
}
if (interactive == unspecified) { if (fulltbl || fullspd)
interactive = false; else
interactive = true;
}
if (fulltbl || fullspd) { if (usemecs)
flexerror (_
("-Cf/-CF and -Cm don't make sense together"));
if (interactive)
flexerror (_("-Cf/-CF and -I are incompatible"));
if (lex_compat)
flexerror (_
("-Cf/-CF are incompatible with lex-compatibility mode"));
if (fulltbl && fullspd)
flexerror (_
("-Cf and -CF are mutually exclusive"));
}
if (C_plus_plus && fullspd)
flexerror (_("Can't use -+ with -CF option"));
if (C_plus_plus && yytext_is_array) {
warn (_("%array incompatible with -+ option"));
yytext_is_array = false;
}
if (C_plus_plus && (reentrant))
flexerror (_("Options -+ and --reentrant are mutually exclusive."));
if (C_plus_plus && bison_bridge_lval)
flexerror (_("bison bridge not supported for the C++ scanner."));
if (useecs) { /* Set up doubly-linked equivalence classes. */
/* We loop all the way up to csize, since ecgroup[csize] is *thepositionusedforNULcharacters.
*/
ecgroup[1] = NIL;
for (i = 2; i <= csize; ++i) {
ecgroup[i] = i - 1;
nextecm[i - 1] = i;
}
nextecm[csize] = NIL;
}
else { /* Put everything in its own equivalence class. */ for (i = 1; i <= csize; ++i) {
ecgroup[i] = i;
nextecm[i] = BAD_SUBSCRIPT; /* to catch errors */
}
}
if (!ansi_func_defs)
buf_m4_define( &m4defs_buf, "M4_YY_NO_ANSI_FUNC_DEFS", NULL);
if (!ansi_func_protos)
buf_m4_define( &m4defs_buf, "M4_YY_NO_ANSI_FUNC_PROTOS", NULL);
if (extra_type)
buf_m4_define( &m4defs_buf, "M4_EXTRA_TYPE_DEFS", extra_type);
if (!use_stdout) {
FILE *prev_stdout;
if (!did_outfilename) { char *suffix;
if (C_plus_plus)
suffix = "cc"; else
suffix = "c";
/* For debugging, only run the requested number of filters. */ if (preproc_level > 0) {
filter_truncate(output_chain, preproc_level);
filter_apply_chain(output_chain);
}
yyout = stdout;
/* always generate the tablesverify flag. */
buf_m4_define (&m4defs_buf, "M4_YY_TABLES_VERIFY", tablesverify ? "1" : "0"); if (tablesext)
gentables = false;
if (tablesverify) /* force generation of C tables. */
gentables = true;
if (tablesext) {
FILE *tablesout; struct yytbl_hdr hdr; char *pname = 0; int nbytes = 0;
#if0
fprintf (header_out, "#ifdef YY_HEADER_EXPORT_START_CONDITIONS\n");
fprintf (header_out, "/* Beware! Start conditions are not prefixed. */\n");
/* Special case for "INITIAL" */
fprintf (header_out, "#undef INITIAL\n#define INITIAL 0\n"); for (i = 2; i <= lastsc; i++)
fprintf (header_out, "#define %s %d\n", scname[i], i - 1);
fprintf (header_out, "#endif /* YY_HEADER_EXPORT_START_CONDITIONS */\n\n");
/* Kill ALL flex-related macros. This is so the user
* can #include more than one generated header file. */
fprintf (header_out, "#ifndef YY_HEADER_NO_UNDEFS\n");
fprintf (header_out, "/* Undefine all internal macros, etc., that do no belong in the header. */\n\n");
if (printstats) {
fprintf (stderr, _("%s version %s usage statistics:\n"),
program_name, flex_version);
fprintf (stderr, _(" scanner options: -"));
if (C_plus_plus)
putc ('+', stderr); if (backing_up_report)
putc ('b', stderr); if (ddebug)
putc ('d', stderr); if (sf_case_ins())
putc ('i', stderr); if (lex_compat)
putc ('l', stderr); if (posix_compat)
putc ('X', stderr); if (performance_report > 0)
putc ('p', stderr); if (performance_report > 1)
putc ('p', stderr); if (spprdflt)
putc ('s', stderr); if (reentrant)
fputs ("--reentrant", stderr); if (bison_bridge_lval)
fputs ("--bison-bridge", stderr); if (bison_bridge_lloc)
fputs ("--bison-locations", stderr); if (use_stdout)
putc ('t', stderr); if (printstats)
putc ('v', stderr); /* always true! */ if (nowarn)
putc ('w', stderr); if (interactive == false)
putc ('B', stderr); if (interactive == true)
putc ('I', stderr); if (!gen_line_dirs)
putc ('L', stderr); if (trace)
putc ('T', stderr);
if (csize == unspecified) /* We encountered an error fairly early on, so csize *nevergotspecified.Defineitnow,toprevent *bogustablesizesbeingwrittenoutbelow.
*/
csize = 256;
if (long_align)
putc ('a', stderr); if (fulltbl)
putc ('f', stderr); if (fullspd)
putc ('F', stderr); if (useecs)
putc ('e', stderr); if (usemecs)
putc ('m', stderr); if (use_read)
putc ('r', stderr);
if (did_outfilename)
fprintf (stderr, " -o%s", outfilename);
if (skelname)
fprintf (stderr, " -S%s", skelname);
if (strcmp (prefix, "yy"))
fprintf (stderr, " -P%s", prefix);
/* Initialize dynamic array for holding the rule actions. */
action_size = 2048; /* default size of action array in bytes */
action_array = allocate_character_array (action_size);
defs1_offset = prolog_offset = action_offset = action_index = 0;
action_array[0] = '\0';
/* Initialize any buffers. */
buf_init (&userdef_buf, sizeof (char)); /* one long string */
buf_init (&defs_buf, sizeof (char *)); /* list of strings */
buf_init (&yydmap_buf, sizeof (char)); /* one long string */
buf_init (&top_buf, sizeof (char)); /* one long string */
/* read flags */
sopt = scanopt_init (flexopts, argc, argv, 0); if (!sopt) { /* This will only happen when flexopts array is altered. */
fprintf (stderr,
_("Internal error. flexopts are malformed.\n"));
FLEX_EXIT (1);
}
while ((rv = scanopt (sopt, &arg, &optind)) != 0) {
if (rv < 0) { /* Scanopt has already printed an option-specific error message. */
fprintf (stderr,
_
("Try `%s --help' for more information.\n"),
program_name);
FLEX_EXIT (1);
}
/* If the user explicitly requested posix compatibility by specifing the *posix-compatoption,thenwecheckforconflictingoptions.However,if *thePOSIXLY_CORRECTvariableisset,thenwequietlymakeflexas *posix-compatibleaspossible.Thisistherecommendedbehavior *accordingtotheGNUCodingStandards. * *Note:Theposixoptionwasaddedtoflextoprovidetheposixbehavior *oftherepeatoperatorinregularexpressions,e.g.,`ab{3}'
*/ if (posix_compat) { /* TODO: This is where we try to make flex behave according to *posiz,ANDcheckforconflictingoptions.Howfarshouldwego *withthis?Shouldwedisablealltheneat-oflexfeatures?
*/ /* Update: Estes says no, since other flex features don't violate posix. */
}
if (getenv ("POSIXLY_CORRECT")) {
posix_compat = true;
}
if (backing_up_report) {
backing_up_file = fopen (backing_name, "w"); if (backing_up_file == NULL)
lerr (_
("could not create backing-up info file %s"),
backing_name);
}
if (performance_report > 0) { if (lex_compat) {
fprintf (stderr,
_
("-l AT&T lex compatibility option entails a large performance penalty\n"));
fprintf (stderr,
_
(" and may be the actual source of other reported performance penalties\n"));
}
elseif (do_yylineno) {
fprintf (stderr,
_
("%%option yylineno entails a performance penalty ONLY on rules that can match newline characters\n"));
}
if (performance_report > 1) { if (interactive)
fprintf (stderr,
_
("-I (interactive) entails a minor performance penalty\n"));
if (yymore_used)
fprintf (stderr,
_
("yymore() entails a minor performance penalty\n"));
}
if (reject)
fprintf (stderr,
_
("REJECT entails a large performance penalty\n"));
if (variable_trailing_context_rules)
fprintf (stderr,
_
("Variable trailing context rules entail a large performance penalty\n"));
}
if (reject)
real_reject = true;
if (variable_trailing_context_rules)
reject = true;
if ((fulltbl || fullspd) && reject) { if (real_reject)
flexerror (_
("REJECT cannot be used with -f or -F")); elseif (do_yylineno)
flexerror (_
("%option yylineno cannot be used with REJECT")); else
flexerror (_
("variable trailing context rules cannot be used with -f or -F"));
}
if (reject){
out_m4_define( "M4_YY_USES_REJECT", NULL); //outn ("\n#define YY_USES_REJECT");
}
if (!do_yywrap) { if (!C_plus_plus) { if (reentrant)
outn ("\n#define yywrap(yyscanner) (/*CONSTCOND*/1)"); else
outn ("\n#define yywrap() (/*CONSTCOND*/1)");
}
outn ("#define YY_SKIP_YYWRAP");
}
out_str ("\n#define YY_DECL int %s::yylex()\n",
yyclass);
}
}
else {
/* Watch out: yytext_ptr is a variable when yytext is an array, *butit'samacrowhenyytextisapointer.
*/ if (yytext_is_array) { if (!reentrant)
outn ("extern char yytext[];\n");
} else { if (reentrant) {
outn ("#define yytext_ptr yytext_r");
} else {
outn ("extern char *yytext;");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.