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

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>
            一区二区在线看| 日韩午夜三级在线| 日韩亚洲欧美一区二区三区| 亚欧美中日韩视频| 一区二区三区国产精品| 一区二区三区在线观看欧美| 国产日韩欧美制服另类| 国产精品国产三级国产| 欧美日韩在线免费| 欧美精品v国产精品v日韩精品| 久久综合九色九九| 久久久高清一区二区三区| 久久久久天天天天| 欧美激情视频在线免费观看 欧美视频免费一 | 国产精品日韩高清| 国产酒店精品激情| 激情综合色综合久久综合| 亚洲人成网站影音先锋播放| 在线观看欧美日韩国产| 久久午夜视频| 欧美jjzz| 日韩亚洲欧美在线观看| 久久精品二区三区| 欧美人妖在线观看| 国产一区二区三区四区在线观看 | 精品69视频一区二区三区| 亚洲国产精品久久91精品| 亚洲午夜av在线| 牛人盗摄一区二区三区视频| 99国产精品国产精品毛片| 欧美在线视频免费播放| 欧美精品在线视频| 狠狠色伊人亚洲综合网站色| 亚洲伊人观看| 欧美成人精品三级在线观看| 亚洲欧美激情视频| 欧美激情免费在线| 韩日午夜在线资源一区二区| 在线一区二区视频| 欧美大片在线看免费观看| 亚洲视频图片小说| 欧美理论在线播放| 亚洲精品乱码| 欧美成人综合| 亚洲在线视频网站| 欧美亚洲不卡| 亚洲午夜久久久| 亚洲国产欧美一区二区三区丁香婷| 91久久午夜| 久久亚洲色图| 国内精品久久久久国产盗摄免费观看完整版 | 亚洲一区二区视频在线| 久久精品在线视频| 欧美日韩系列| 制服诱惑一区二区| 亚洲伦理在线观看| 男人插女人欧美| 在线观看一区视频| 老司机亚洲精品| 亚洲欧美在线磁力| 欧美日韩在线观看一区二区| 亚洲高清免费在线| 久久久亚洲欧洲日产国码αv | 久久综合综合久久综合| 国产亚洲欧洲| 久久免费视频网| 一区二区视频免费完整版观看| 欧美精品一线| 亚洲精品日韩欧美| 亚洲成人资源网| 免费欧美在线视频| 亚洲国产精品一区二区久| 牛牛国产精品| 麻豆国产精品一区二区三区| 在线观看91精品国产入口| 久久国产欧美| 久久久精品一区| 国产午夜精品全部视频播放 | 国产精品99久久久久久有的能看 | 欧美一二三视频| 国产欧美日本在线| 欧美呦呦网站| 欧美一区二区视频在线| 国产综合在线视频| 久久精品一区二区三区不卡牛牛 | 亚洲国产一区二区三区高清| 免费观看日韩av| 日韩午夜精品| 亚洲欧美日韩专区| 狠狠色丁香婷婷综合| 免费黄网站欧美| 免费人成精品欧美精品| 一区二区电影免费观看| 日韩一区二区免费看| 欧美三区免费完整视频在线观看| 欧美一级大片在线免费观看| 久久免费偷拍视频| 亚洲四色影视在线观看| 久久国产精品亚洲va麻豆| 亚洲精品国产系列| 亚洲影视九九影院在线观看| 影音先锋久久资源网| 99精品久久免费看蜜臀剧情介绍| 国产一区二区三区久久| 亚洲精品日韩久久| 狠狠综合久久| 亚洲宅男天堂在线观看无病毒| 亚洲高清久久网| 亚洲欧美中文字幕| 在线一区亚洲| 欧美成人精品不卡视频在线观看| 性欧美8khd高清极品| 欧美国产日韩精品| 噜噜爱69成人精品| 久久天天躁夜夜躁狠狠躁2022| 欧美sm极限捆绑bd| 久久视频一区| 国产欧美一区二区三区沐欲| 99re66热这里只有精品4| 亚洲国产欧美精品| 欧美一区二区免费| 亚洲已满18点击进入久久| 欧美成人精品影院| 女生裸体视频一区二区三区| 午夜精品一区二区三区四区| 国产精品久久久久99| 亚洲经典视频在线观看| 欧美国产极速在线| 欧美成年人视频| 亚洲高清网站| 日韩亚洲一区在线播放| 欧美一级大片在线免费观看| 欧美激情一区二区久久久| 久久婷婷综合激情| 欧美日韩一区二区视频在线| 国产日韩精品视频一区| 亚洲精品欧美在线| 久久综合色婷婷| av不卡在线| 女人天堂亚洲aⅴ在线观看| 欧美日本不卡| 亚洲国产一区二区三区在线播| 一本久道综合久久精品| 久久精品国产免费观看| 亚洲裸体俱乐部裸体舞表演av| 午夜视黄欧洲亚洲| 国产欧美日韩不卡免费| 亚洲综合大片69999| av成人免费在线观看| 欧美日韩国产成人在线免费 | 欧美激情在线狂野欧美精品| 99成人免费视频| 午夜激情综合网| 9国产精品视频| 国产精品一区2区| 欧美亚洲一区二区在线| 亚洲一区二区在线| 国产麻豆视频精品| 欧美在线观看天堂一区二区三区| 亚洲午夜在线观看| 国产伦精品一区二区三区四区免费 | 国产欧美一二三区| 午夜电影亚洲| 亚洲综合99| 亚洲电影一级黄| 日韩视频在线观看免费| 国产精品久久精品日日| 午夜天堂精品久久久久 | 亚洲桃花岛网站| 韩国三级在线一区| 亚洲黄网站在线观看| 欧美日韩亚洲一区二区三区| 亚洲字幕一区二区| 久久久www成人免费毛片麻豆| 亚洲欧洲精品一区二区精品久久久| 日韩网站在线观看| 韩日欧美一区二区| 亚洲午夜羞羞片| 亚洲天堂黄色| 欧美高清在线播放| 欧美国产精品久久| 国产欧美日韩亚洲| 日韩午夜免费| 一区二区三区www| 久久久综合网| 久久久国产成人精品| 欧美日韩色一区| 日韩视频免费观看高清完整版| 亚洲观看高清完整版在线观看| 先锋影院在线亚洲| 香蕉成人伊视频在线观看| 欧美日韩国产一区二区三区| 亚洲日本中文字幕区| 亚洲国产高潮在线观看| 久久伊人免费视频| 六十路精品视频| 亚洲精选一区| 欧美偷拍一区二区| 亚洲欧美一区在线| 久久中文字幕导航|