青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數(shù)據(jù)加載中……

flex詳解

flex
 
此篇不會講述規(guī)則表達(dá)式,自從.net流行之后,大量的原本只是在unix才使用的規(guī)則表達(dá)式現(xiàn)在廣泛使用在各種系統(tǒng)中。略.

1.內(nèi)置變量
  yy_create_buffer:
見后面的緩沖管理
  yy_delete_buffer:
見后面的緩沖管理
  yy_flex_debug:
見后面的緩沖管理
  yy_init_buffer:
見后面的緩沖管理
  yy_flush_buffer:
見后面的緩沖管理
  yy_load_buffer_state:
見后面的緩沖管理
  yy_switch_to_buffer:
見后面的緩沖管理
 
  yyin:
輸入緩沖流的文件指針,可以被替換以實現(xiàn)解析某個自定義的文件
  yyleng:
當(dāng)前匹配字串的長度
  yylex:
解析函數(shù),接口
  yylineno:
當(dāng)前匹配的文件行號
  yyout:  
輸出流的指針
  yyrestart:
手動調(diào)用yyrestart.會重啟解析
            yyrestart( yyin );
一般是打開某個文件之后,yyrestart(yyin)再解析.
  yytext
: 當(dāng)前匹配的字串
  yywrap
: 解析一個文件完畢之后,會調(diào)用yywrap:返回1表示結(jié)束,0表示繼續(xù)(此時最好重新打開yyin或者重置yyin)

2. 幾個重要函數(shù):
1). yymore(): yymore()
的含義是,當(dāng)當(dāng)前匹配的字串之后,想把后面配置的字串附加到這個字串后面,組成新的token返回.
 
比如:
            %%
          mega-    ECHO; yymore();
          kludge   ECHO;
 
如果:“mega-kludge" the following will write "mega-mega-kludge" to the output
 
為什么呢? 首先遇到 mega-,接著被more了一下,因此就會把kludga附加到mega-后面,而后面的kludge的動作又是打印,因此會打印出:mega-mega-kludge

2). yyless(): yyless()的含義是:當(dāng)當(dāng)前的匹配之后,我想只返回前面幾個字符,并且把后面回退到輸入
 
比如:
          %%
          foobar    ECHO; yyless(3);
          [a-z]+    ECHO;
        input "foobar" the following will write out     "foobarbar":
  
為什么呢? foobar輸入之后,匹配foobar,ECHO打印出來,接著yyless(3),則輸入流變?yōu)?span lang="EN-US">bar
(yytextfoo).接著再匹配,于是匹配    [a-z]+,因此再次打印出bar.
  
3).BEGIN: flex
下一個起始解析狀態(tài)。見第3節(jié),flex的狀態(tài).

4).REJECT:  相當(dāng)于拒絕此匹配,讓系統(tǒng)重新找下一個匹配。
"abcd", it
     will write "abcdabcaba" to the output:

          %%
          a        |
          ab       |
          abc      |
          abcd     ECHO; REJECT;
          .|\n     /* eat up any unmatched character */  
        
5).unput(c):
c重新放到輸入流。

6).input(): 讀取輸入流下一個字符

7).yyrestart(): 該函數(shù)迫使yylex重新解析。yyrestart有個函數(shù)指針流,可以再打開之后,重新使用yyrestart().


3.
解析源管理:
    1).
默認(rèn)是從yyin獲取,而yyin則是stdout,也可以是其它文件。
        if ( ! yyin )
         yyin = stdin;
       
        if ( ! yyout )
         yyout = stdout;
   
    2).
如果你打開了一個文件,并把yyin指向此文件,則從該文件中讀取.比如:
   
main中:
     FILE* fp = NULL;
     fp = fopen("hell.txt", "r");
     yyin = fp;
    
之后再使用 yylex()
   
flexhell.txt中讀取信息并解析.
   
    3).
從字符串中解析
       
先使用下列函數(shù),轉(zhuǎn)化緩沖,之后再使用 yylex()
       a. yy_scan_string(char*).
使用了yy_scan_string(char*)之后,flex會把char*放到yy的輸入緩沖中(會調(diào)用到yy_switch_to_buffer.)
       b. yy_scan_bytes(const char *base, int len);
       c. yy_scan_buffer(char *base, yy_size_t size)
      
這幾個函數(shù)內(nèi)部都使用的是緩沖切換的創(chuàng)建等函數(shù),見后面的章節(jié).

    4).利用EOF內(nèi)置規(guī)則,重新打開多個文件輸入:  
   
比如:
     <<EOF>>  {
          if ( *++filelist )
              yyin = fopen( *filelist, "r" );
          else
             yyterminate();
          }
    5).
多緩沖問題:
        a.
此問題可以按上面的 <<EOF>>或者 yywrap解決。
        b.
另外一種形式,比如:#include <iostream>或者類似于這種,這種形式的話,則不能使用yywrap<<EOF>>來解決了。
          
這就需要用到在flex動作中手動切換緩沖。flex對每個緩沖有個緩沖輸入流指針,指向當(dāng)前位置,各個被切換的緩沖互不相干擾,這恰好很好地解決了文件包含另外一個文件,而子文件也許要yylex的這種場合.
          
這就需要使用到flex底層的緩沖管理了.見下節(jié)
   

4. flex的緩沖管理:
    flex
本質(zhì)上都是對緩沖輸入流進(jìn)行yylex詞法分析. 緩沖是個結(jié)構(gòu)體,每個緩沖有個緩沖輸入流指針,指向當(dāng)前位置,各個被切換的緩沖互不相干擾,而相關(guān)yyin,yyrestart,yy_create_buffer,yy_scan_string系列函數(shù)都是操縱flex底層緩沖的.
    flex
緩沖是一個結(jié)構(gòu)體:   
我們以下面的詞法規(guī)則為例子:(來自flex官方網(wǎng)站的注解)
     /* 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] );
                 }
             }   
    YY_BUFFER_STATE
就是一個緩沖。該lex文法使用到了<incl>,這個是狀態(tài),見4節(jié)的flex的狀態(tài)管理.目前只需要知道它是個狀態(tài)即可.incl狀態(tài)下才進(jìn)行[ \t]*的規(guī)則匹配.
    <<EOF>>
見上面的描述,指某個輸入流到了末尾則到了這個狀態(tài).

    BEGIN(INITIAL)類似于BEGIN(0),表示狀態(tài)從開頭解析(0表示不帶狀態(tài)的解析,也就說規(guī)則前沒有<>這個標(biāo)記的狀態(tài).


   
上面的文法可以知道:
    a.
在遇到include之后,跳到incl狀態(tài)。
    b.
incl狀態(tài)中,跳過空白的字符,得到文件名(include file),先把當(dāng)前的flexBuffer保存到數(shù)組棧,然后打開新的文件,并把flex的當(dāng)前輸入流切換到剛打開的新文件的輸入流.
    c.
切換到INITIAL狀態(tài)(沒有<>在規(guī)則前的默認(rèn)的狀態(tài))
    d.
這里用到了幾個宏或者函數(shù): yy_switch_to_buffer, yy_create_bufferYY_CURRENT_BUFFERyy_delete_buffer.
   
這些函數(shù)看名字就應(yīng)該知道其作用了。 
       
4. flex
的狀態(tài)(Start conditions).
   
上面的緩沖管理已經(jīng)涉及到狀態(tài)管理了。flex的狀態(tài)管理相當(dāng)于普通詞法的擴展。通過flex的狀態(tài),大大擴充了詞法分析本身的功能。
   
比如:
     a.    <STRING>[^"]*        { /* eat up the string body ... */
                 ...
                 }
    
表示在STRING狀態(tài)下才進(jìn)行   [^"]*匹配。
     b.      <INITIAL,STRING,QUOTE>\.        { /* handle an escape ... */
                 ...
                 }
    
表示在INITIAL,STRING,QUOTE才匹配。\.  
     flex
的狀態(tài)怎么使用呢?
     a.
首先定義:%開頭(flex的申明本質(zhì)上所有的都是以%開頭)定義,2: %s,%x,其中%s = %x+INITIAL,也就說是%s的狀態(tài)為%x定義的+INITIAL狀態(tài)
     b.
在規(guī)則域中,使用<狀態(tài)>規(guī)則,比如 comment是個狀態(tài),則有 <comment>.\,其中.\是個lex規(guī)則文法,comment則就是一個狀態(tài)了.
     c.
有幾個特殊內(nèi)置的狀態(tài)。INITIAL,*.比如: <*>規(guī)則,則表示這個規(guī)則在任何狀態(tài)下有效. <INITIAL>是個默認(rèn)狀態(tài)。
     d.
某個規(guī)則可以支持多個狀態(tài),使用隔開。比如<INITIAL,STRING,QUOTE>規(guī)則.如果和<<EOF>>重用一個規(guī)則的話,則是<quote><<EOF>>
     e.flex
還提供了一套相關(guān)函數(shù):
     yy_push_state, yy_pop_state, yy_top_state, BEGIN()    
    
可以說有了狀態(tài)的支持,flex的功能更加強大了,簡單的文法分析甚至可以不借助于yacc/bison來做了。
    
   
一個完整的例子:
     %x str
    
     %%
             char string_buf[MAX_STR_CONST];
             char *string_buf_ptr;
    
     \"      string_buf_ptr = string_buf; BEGIN(str);
    
     <str>\"        { /* saw closing quote - all done */
             BEGIN(INITIAL);
             *string_buf_ptr = '\0';
             /* return string constant token type and
              * value to parser
              */
             }
    
     <str>\n        {
             /* error - unterminated string constant */
             /* generate error message */
             }
    
     <str>\\[0-7]{1,3} {
             /* octal escape sequence */
             int result;
    
             (void) sscanf( yytext + 1, "%o", &result );
    
             if ( result > 0xff )
                     /* error, constant is out-of-bounds */
    
             *string_buf_ptr++ = result;
             }
    
     <str>\\[0-9]+ {
             /* generate error - bad escape sequence; something
              * like '\48' or '\0777777'
              */
             }
    
     <str>\\n  *string_buf_ptr++ = '\n';
     <str>\\t  *string_buf_ptr++ = '\t';
     <str>\\r  *string_buf_ptr++ = '\r';
     <str>\\b  *string_buf_ptr++ = '\b';
     <str>\\f  *string_buf_ptr++ = '\f';
    
     <str>\\(.|\n)  *string_buf_ptr++ = yytext[1];
    
     <str>[^\\\n\"]+        {
             char *yptr = yytext;
    
             while ( *yptr )
                     *string_buf_ptr++ = *yptr++;
             }
   
   
5. flex C++
的支持
   
編譯時,使用flex -+ 文件,就可以得到.cc的文件,而且flex也會生成C++相關(guān)類,對應(yīng)的類和方法有:
    FlexLexer:
成員方法有:
        a. yylex(), YYText(), YYLeng(),lineno(), set_debug(),debug(),
        b.
構(gòu)造函數(shù)yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 )
        c.
緩沖:switch_streams(istream* new_in = 0, ostream* new_out = 0),yylex( istream* new_in = 0, ostream* new_out = 0 )
       
       
等等。
  
例子:
         // An example of using the flex C++ scanner class.
    
     %{
     int mylineno = 0;
     %}
    
     string  \"[^\n"]+\"
    
     ws      [ \t]+
    
     alpha   [A-Za-z]
     dig     [0-9]
     name    ({alpha}|{dig}|\$)({alpha}|{dig}|[_.\-/$])*
     num1    [-+]?{dig}+\.?([eE][-+]?{dig}+)?
     num2    [-+]?{dig}*\.{dig}+([eE][-+]?{dig}+)?
     number  {num1}|{num2}
    
     %%
    
     {ws}    /* skip blanks and tabs */
    
     "/*"    {
             int c;
    
             while((c = yyinput()) != 0)
                 {
                 if(c == '\n')
                     ++mylineno;
    
                 else if(c == '*')
                     {
                     if((c = yyinput()) == '/')
                         break;
                     else
                         unput(c);
                     }
                 }
             }
    
     {number}  cout << "number " << YYText() << '\n';
    
     \n        mylineno++;
    
     {name}    cout << "name " << YYText() << '\n';
    
     {string}  cout << "string " << YYText() << '\n';
    
     %%
    
     Version 2.5               December 1994                      
    
     int main( int /* argc */, char** /* argv */ )
         {
         FlexLexer* lexer = new yyFlexLexer;
         while(lexer->yylex() != 0)
             ;
         return 0;
         }    

posted on 2008-11-23 00:54 肥仔 閱讀(8172) 評論(2)  編輯 收藏 引用 所屬分類: LEX & YACC

評論

# re: flex詳解  回復(fù)  更多評論   

flex也就是幫你詞法之后將剩下的事情全部丟給你了。因為“剩下的事情”用的是C/C++,所以從各種意義上來看flex不僅僅是type 3 grammar,但是這是借助其他工具完成的,譬如說C/C++。
2008-11-23 16:31 | 陳梓瀚(vczh)

# re: flex詳解  回復(fù)  更多評論   

從各種意義上來看flex不僅僅是type 3 grammar,
http://www.uggeinkaufenboots.com/
2010-10-26 17:09 | ugg boots buy
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            免费久久99精品国产自在现线| 在线午夜精品自拍| 久久视频免费观看| 在线日本成人| 亚洲国产另类精品专区| 久久夜色撩人精品| 亚洲精品欧洲精品| 久久精品1区| 影音先锋在线一区| 亚洲国产成人av好男人在线观看| 女女同性女同一区二区三区91| 日韩午夜激情| 亚洲天堂第二页| 影音先锋中文字幕一区| 亚洲欧洲日产国产综合网| 国产精品久久久久久久电影| 久久精品国产一区二区三| 麻豆久久婷婷| 午夜精品一区二区三区电影天堂| 久久精品国产亚洲一区二区三区| 亚洲国产小视频在线观看| 一区二区三区国产盗摄| 黑人操亚洲美女惩罚| 亚洲精品亚洲人成人网| 国产日韩综合一区二区性色av| 欧美电影在线| 国产精品美女在线观看| 亚洲国产经典视频| 国产视频久久网| 亚洲人体大胆视频| 国语自产精品视频在线看| 日韩西西人体444www| 伊人成年综合电影网| 亚洲作爱视频| 亚洲精品国产精品国自产观看浪潮| 亚洲一区二区三区免费视频| 最新国产の精品合集bt伙计| 午夜精品久久久久久久男人的天堂 | 亚洲视频精品| 久久一区二区三区超碰国产精品| 亚洲欧美激情视频| 欧美激情一区在线观看| 麻豆成人小视频| 国产精品久久久久久久久果冻传媒| 欧美二区不卡| 一区二区三区在线看| 亚洲主播在线| 亚洲欧美日本国产有色| 欧美精品国产精品| 欧美激情欧美狂野欧美精品| 狠狠久久亚洲欧美| 欧美一级二区| 欧美一区二区三区在线看| 欧美激情第六页| 欧美激情久久久久| 亚洲国产欧美在线| 久久久综合香蕉尹人综合网| 久久九九有精品国产23| 国产噜噜噜噜噜久久久久久久久| 一本色道88久久加勒比精品| 一本大道久久a久久精品综合 | 在线午夜精品| 亚洲专区欧美专区| 欧美午夜不卡| 亚洲一区二区三区欧美| 久久不射电影网| 国产日产精品一区二区三区四区的观看方式 | 亚洲男人的天堂在线观看| 亚洲综合国产| 国产精品私房写真福利视频| 亚洲性夜色噜噜噜7777| 午夜精品99久久免费| 国产精品影视天天线| 午夜精品久久久久久久久久久| 久久精品国产亚洲一区二区三区| 国产亚洲精品美女| 久久久99免费视频| 欧美成人tv| 99视频精品在线| 国产精品久久久久久超碰| 亚洲影视综合| 乱中年女人伦av一区二区| 亚洲国产精品久久久久秋霞影院 | 亚洲一区二区三区涩| 欧美一区二区三区在线| 影音先锋日韩精品| 欧美精品日韩三级| 亚洲视频综合在线| 久久久久免费视频| 亚洲精品欧洲精品| 国产精品爽黄69| 久久欧美中文字幕| 亚洲精品一区在线观看香蕉| 亚洲欧美资源在线| 在线免费观看视频一区| 欧美性jizz18性欧美| 午夜在线观看欧美| 亚洲国产成人av好男人在线观看| 一本一本久久a久久精品综合妖精| 国产精品久久久久久久久免费樱桃 | 亚洲成色777777女色窝| 亚洲尤物在线视频观看| 一区二区视频免费在线观看| 欧美日韩国产va另类| 欧美一区二区在线看| 亚洲国产精品va在线看黑人动漫| 亚洲一区二区欧美| 樱桃国产成人精品视频| 欧美体内she精视频在线观看| 欧美一级夜夜爽| 日韩视频免费在线| 免费观看30秒视频久久| 午夜精品久久久久久久| 亚洲国产专区| 国产综合av| 国产精品日本| 欧美激情一区二区三区高清视频| 欧美一区二区三区电影在线观看| 亚洲精品日日夜夜| 免费成人高清视频| 久久久精品久久久久| 亚洲综合电影一区二区三区| 一本久久综合| 亚洲国产精品999| 国产午夜精品福利| 国产精品久久一区主播| 欧美色视频日本高清在线观看| 麻豆精品一区二区av白丝在线| 欧美在线黄色| 亚洲一区在线免费| 一本色道久久综合一区 | 中文一区字幕| 久久久久免费| 欧美日韩p片| 欧美国产日韩a欧美在线观看| 久久av资源网站| 亚洲综合色丁香婷婷六月图片| 日韩视频在线一区二区| 亚洲国产精品一区二区尤物区| 欧美.www| 欧美成人综合一区| 欧美大片在线观看一区| 欧美www视频在线观看| 久久视频这里只有精品| 欧美一区二区视频在线观看| 亚洲欧美激情精品一区二区| 性视频1819p久久| 欧美一区二区三区四区在线观看地址| 午夜一级久久| 欧美一区二区三区另类 | 国产色产综合产在线视频| 国产欧美一区二区精品性色| 国产日韩欧美电影在线观看| 国产偷久久久精品专区| 国内精品久久久久影院薰衣草| 国产在线高清精品| 亚洲福利视频二区| 亚洲理论在线观看| 国产精品99久久久久久久久久久久 | 亚洲一区制服诱惑| 午夜精品视频在线观看一区二区| 欧美在线视频观看免费网站| 久久久久久久尹人综合网亚洲 | 亚洲一区影音先锋| 久久久97精品| 欧美国产亚洲另类动漫| 亚洲日本中文字幕区| 日韩系列在线| 欧美资源在线| 欧美噜噜久久久xxx| 国产精品国产三级国产aⅴ浪潮| 国产精品亚洲一区二区三区在线| 国产亚洲精品v| 在线免费一区三区| 亚洲永久字幕| 欧美大香线蕉线伊人久久国产精品| 亚洲激情av| 亚欧美中日韩视频| 欧美福利影院| 国产私拍一区| 亚洲最新视频在线| 久久视频免费观看| 一区二区三欧美| 久久综合狠狠综合久久综合88| 欧美日韩国产在线| 在线看欧美日韩| 性色av一区二区三区| 欧美电影免费观看网站| 亚洲永久网站| 欧美精彩视频一区二区三区| 国产亚洲制服色| 亚洲性人人天天夜夜摸| 久久亚洲精品欧美| 亚洲午夜三级在线| 欧美黑人多人双交| 激情成人av在线| 性欧美18~19sex高清播放| 91久久黄色| 老牛嫩草一区二区三区日本| 国产精品视频一二三|