⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flex.1

📁 flex 词法分析工具 类似于lex 此版本为较早前的版本
💻 1
📖 第 1 页 / 共 5 页
字号:
start condition.I scope.A start condition scope is begun with:.nf    <SCs>{.fiwhere.I SCsis a list of one or more start conditions.  Inside the start conditionscope, every rule automatically has the prefix.I <SCs>applied to it, until a.I '}'which matches the initial.I '{'.So, for example,.nf    <ESC>{        "\\\\n"   return '\\n';        "\\\\r"   return '\\r';        "\\\\f"   return '\\f';        "\\\\0"   return '\\0';    }.fiis equivalent to:.nf    <ESC>"\\\\n"  return '\\n';    <ESC>"\\\\r"  return '\\r';    <ESC>"\\\\f"  return '\\f';    <ESC>"\\\\0"  return '\\0';.fiStart condition scopes may be nested..PPThree routines are available for manipulating stacks of start conditions:.TP.B void yy_push_state(int new_state)pushes the current start condition onto the top of the start conditionstack and switches to.I new_stateas though you had used.B BEGIN new_state(recall that start condition names are also integers)..TP.B void yy_pop_state()pops the top of the stack and switches to it via.B BEGIN..TP.B int yy_top_state()returns the top of the stack without altering the stack's contents..PPThe start condition stack grows dynamically and so has no built-insize limitation.  If memory is exhausted, program execution aborts..PPTo use start condition stacks, your scanner must include a.B %option stackdirective (see Options below)..SH MULTIPLE INPUT BUFFERSSome scanners (such as those which support "include" files)require reading from several input streams.  As.I flexscanners do a large amount of buffering, one cannot controlwhere the next input will be read from by simply writing a.B YY_INPUTwhich is sensitive to the scanning context..B YY_INPUTis only called when the scanner reaches the end of its buffer, whichmay be a long time after scanning a statement such as an "include"which requires switching the input source..PPTo negotiate these sorts of problems,.I flexprovides a mechanism for creating and switching between multipleinput buffers.  An input buffer is created by using:.nf    YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ).fiwhich takes a.I FILEpointer and a size and creates a buffer associated with the givenfile and large enough to hold.I sizecharacters (when in doubt, use.B YY_BUF_SIZEfor the size).  It returns a.B YY_BUFFER_STATEhandle, which may then be passed to other routines (see below).  The.B YY_BUFFER_STATEtype is a pointer to an opaque.B struct yy_buffer_statestructure, so you may safely initialize YY_BUFFER_STATE variables to.B ((YY_BUFFER_STATE) 0)if you wish, and also refer to the opaque structure in order tocorrectly declare input buffers in source files other than thatof your scanner.  Note that the.I FILEpointer in the call to.B yy_create_bufferis only used as the value of.I yyinseen by.B YY_INPUT;if you redefine.B YY_INPUTso it no longer uses.I yyin,then you can safely pass a nil.I FILEpointer to.B yy_create_buffer.You select a particular buffer to scan from using:.nf    void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ).fiswitches the scanner's input buffer so subsequent tokens willcome from.I new_buffer.Note that.B yy_switch_to_buffer()may be used by yywrap() to set things up for continued scanning, insteadof opening a new file and pointing.I yyinat it.  Note also that switching input sources via either.B yy_switch_to_buffer()or.B yywrap()does.I notchange the start condition..nf    void yy_delete_buffer( YY_BUFFER_STATE buffer ).fiis used to reclaim the storage associated with a buffer.  (.B buffercan be nil, in which case the routine does nothing.)You can also clear the current contents of a buffer using:.nf    void yy_flush_buffer( YY_BUFFER_STATE buffer ).fiThis function discards the buffer's contents,so the next time the scanner attempts to match a token from thebuffer, it will first fill the buffer anew using.B YY_INPUT..PP.B yy_new_buffer()is an alias for.B yy_create_buffer(),provided for compatibility with the C++ use of.I newand.I deletefor creating and destroying dynamic objects..PPFinally, the.B YY_CURRENT_BUFFERmacro returns a.B YY_BUFFER_STATEhandle to the current buffer..PPHere is an example of using these features for writing a scannerwhich expands include files (the.B <<EOF>>feature is discussed below):.nf    /* the "incl" state is used for picking up the name     * of an include file     */    %x incl    %{    #define MAX_INCLUDE_DEPTH 10    YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];    int include_stack_ptr = 0;    %}    %%    include             BEGIN(incl);    [a-z]+              ECHO;    [^a-z\\n]*\\n?        ECHO;    <incl>[ \\t]*      /* eat the whitespace */    <incl>[^ \\t\\n]+   { /* got the include file name */            if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )                {                fprintf( stderr, "Includes nested too deeply" );                exit( 1 );                }            include_stack[include_stack_ptr++] =                YY_CURRENT_BUFFER;            yyin = fopen( yytext, "r" );            if ( ! yyin )                error( ... );            yy_switch_to_buffer(                yy_create_buffer( yyin, YY_BUF_SIZE ) );            BEGIN(INITIAL);            }    <<EOF>> {            if ( --include_stack_ptr < 0 )                {                yyterminate();                }            else                {                yy_delete_buffer( YY_CURRENT_BUFFER );                yy_switch_to_buffer(                     include_stack[include_stack_ptr] );                }            }.fiThree routines are available for setting up input buffers forscanning in-memory strings instead of files.  All of them createa new input buffer for scanning the string, and return a corresponding.B YY_BUFFER_STATEhandle (which you should delete with.B yy_delete_buffer()when done with it).  They also switch to the new buffer using.B yy_switch_to_buffer(),so the next call to.B yylex()will start scanning the string..TP.B yy_scan_string(const char *str)scans a NUL-terminated string..TP.B yy_scan_bytes(const char *bytes, int len)scans.I lenbytes (including possibly NUL's)starting at location.I bytes..PPNote that both of these functions create and scan a.I copyof the string or bytes.  (This may be desirable, since.B yylex()modifies the contents of the buffer it is scanning.)  You can avoid thecopy by using:.TP.B yy_scan_buffer(char *base, yy_size_t size)which scans in place the buffer starting at.I base,consisting of.I sizebytes, the last two bytes of which.I mustbe.B YY_END_OF_BUFFER_CHAR(ASCII NUL).These last two bytes are not scanned; thus, scanningconsists of.B base[0]through.B base[size-2],inclusive..IPIf you fail to set up.I basein this manner (i.e., forget the final two.B YY_END_OF_BUFFER_CHARbytes), then.B yy_scan_buffer()returns a nil pointer instead of creating a new input buffer..IPThe type.B yy_size_tis an integral type to which you can cast an integer expressionreflecting the size of the buffer..SH END-OF-FILE RULESThe special rule "<<EOF>>" indicatesactions which are to be taken when an end-of-file isencountered and yywrap() returns non-zero (i.e., indicatesno further files to process).  The action must finishby doing one of four things:.IP -assigning.I yyinto a new input file (in previous versions of flex, after doing theassignment you had to call the special action.B YY_NEW_FILE;this is no longer necessary);.IP -executing a.I returnstatement;.IP -executing the special.B yyterminate()action;.IP -or, switching to a new buffer using.B yy_switch_to_buffer()as shown in the example above..PP<<EOF>> rules may not be used with otherpatterns; they may only be qualified with a list of startconditions.  If an unqualified <<EOF>> rule is given, itapplies to.I allstart conditions which do not already have <<EOF>> actions.  Tospecify an <<EOF>> rule for only the initial start condition, use.nf    <INITIAL><<EOF>>.fi.PPThese rules are useful for catching things like unclosed comments.An example:.nf    %x quote    %%    ...other rules for dealing with quotes...    <quote><<EOF>>   {             error( "unterminated quote" );             yyterminate();             }    <<EOF>>  {             if ( *++filelist )                 yyin = fopen( *filelist, "r" );             else                yyterminate();             }.fi.SH MISCELLANEOUS MACROSThe macro.B YY_USER_ACTIONcan be defined to provide an actionwhich is always executed prior to the matched rule's action.  For example,it could be #define'd to call a routine to convert yytext to lower-case.When.B YY_USER_ACTIONis invoked, the variable.I yy_actgives the number of the matched rule (rules are numbered starting with 1).Suppose you want to profile how often each of your rules is matched.  Thefollowing would do the trick:.nf    #define YY_USER_ACTION ++ctr[yy_act].fiwhere.I ctris an array to hold the counts for the different rules.  Note thatthe macro.B YY_NUM_RULESgives the total number of rules (including the default rule, even ifyou use.B \-s),so a correct declaration for.I ctris:.nf    int ctr[YY_NUM_RULES];.fi.PPThe macro.B YY_USER_INITmay be defined to provide an action which is always executed beforethe first scan (and before the scanner's internal initializations are done).For example, it could be used to call a routine to readin a data table or open a logging file..PPThe macro.B yy_set_interactive(is_interactive)can be used to control whether the current buffer is considered.I interactive.An interactive buffer is processed more slowly,but must be used when the scanner's input source is indeedinteractive to avoid problems due to waiting to fill buffers(see the discussion of the.B \-Iflag below).  A non-zero valuein the macro invocation marks the buffer as interactive, a zero  value as non-interactive.  Note that use of this macro overrides.B %option always-interactiveor.B %option never-interactive(see Options below)..B yy_set_interactive()must be invoked prior to beginning to scan the buffer that is(or is not) to be considered interactive..PPThe macro.B yy_set_bol(at_bol)can be used to control whether the current buffer's scanningcontext for the next token match is done as though at thebeginning of a line.  A non-zero macro argument makes rules anchored with'^' active, while a zero argument makes '^' rules inactive..PPThe macro.B YY_AT_BOL()returns true if the next token scanned from the current bufferwill have '^' rules active, false otherwise..PPIn the generated scanner, the actions are all gathered in one largeswitch statement and separated using.B YY_BREAK,which may be redefined.  By default, it is simply a "break", to separateeach rule's action from the following rule's.Redefining.B YY_BREAKallows, for example, C++ users to#define YY_BREAK to do nothing (while being very careful that everyrule ends with a "break" or a "return"!) to avoid suffering fromunreachable statement warnings where because a rule's action ends with"return", the.B YY_BREAKis inaccessible..SH VALUES AVAILABLE TO THE USERThis section summarizes the various values available to the userin the rule actions..IP -.B char *yytextholds the text of the current token.  It may be modified but not lengthened(you cannot append characters to the end)..IPIf the special directive.B %arrayappears in the first section of the scanner description, then.B yytextis instead declared.B char yytext[YYLMAX],where.B YYLMAXis a macro definition that you can redefine in the first sectionif you don't like the default value (generally 8KB).  Using.B %arrayresults in somewhat slower scanners, but the value of.B yytextbecomes immune to calls to.I input()and.I unput(),which potentially destroy its value when.B yytextis a character pointer.  The opposite of.B %arrayis.B %pointer,which is the default..IPYou cannot use.B %arraywhen generating C++ scanner classes(the.B \-+flag)..IP -.B int yylengholds the length of the current token..IP -.B FILE *yyinis the file which by default.I flexreads from.  It may be redefined but doing so only makes sense beforescanning begins or after an EOF has been encountered.  Changing it inthe midst of scanning will have unexpected results since.I flexbuffers its input; use.B yyrestart()instead.Once scanning terminates because an end-of-filehas been seen, you can assign.I yyinat the new input file and then call the scanner again to continue scanning..IP -.B void yyrestart( FILE *new_file )may be called to point.I yyinat the new input file.  The switch-over to the new file is immediate

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -