• <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>

            woaidongmao

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

            Ragel 狀態機簡介

            從今天開始我把我前一段時間用到的狀態機工具Ragel的使用方法做一些總結,希望大家斧正!


            (
            如果大家對狀態機概念有模糊的話,請參考<<編譯原理>>一書,基本上有詳盡的介紹)

            好閑言少敘,言歸正傳

            Ragel
            可以從正規表達式生成可執行有限狀態機,它可以生成C,C++,Object-C,D,JavaRuby可執行代碼

            官方網站:http://www.cs.queensu.ca/home/thurston/ragel/

            第一回

            Ragel
            是一個可以生成協議處理代碼的工具. 

            先舉個例子,簡簡單單的幾行代碼,實現的功能為將一個數字字符串轉換成整數:

            [Copy to clipboard] [ - ]

            CODE:

            int atoi( char *str )
            {
            char *p = str;
            int cs, val = 0;
            bool neg = false;

            %%{       //Ragel
            的關鍵字,用于聲明狀態機代碼段的開始
              action see_neg {
               neg = true;
              }

              action add_digit {
               val = val * 10 + (fc - '0');
              }

              main :=
               ( '-'@see_neg | '+' )? ( digit @add_digit )+
               '\n' @{ fbreak; };

              # Initialize and execute.
              write init;                                  //
            狀態機關鍵字,這個會再接下來的內容中介紹
              write exec noend;                     //
            同上
            }%%                                        //
            狀態機代碼段結束標記

            if ( neg )
              val = -1 * val;

            if ( cs < atoi_first_final )
              cerr << "atoi: there was an error" << endl;

            return val;
            };


            c里面那500多行實現的atoi函數更加高效

            上面這段代碼,生成的C語言代碼如下:

            [Copy to clipboard] [ - ]

            CODE:

            int atoi( char *str )
            {
            char *p = str;
            int cs, val = 0;
            bool neg = false;

            #line 27 "atoi.c"
            {
            cs = atoi_start;
            }

            #line 31 "atoi.c"
            {
            switch ( cs )
            {
            case 1:
            switch( (*p) ) {
              case 43: goto st2;
              case 45: goto tr2;
            }
            if ( 48 <= (*p) && (*p) <= 57 )
              goto tr3;
            goto st0;
            st0:
            goto _out0;
            tr2:
            #line 23 "atoi.rl"
            {
               neg = true;
              }
            goto st2;
            st2:
            p += 1;
            case 2:
            #line 52 "atoi.c"
            if ( 48 <= (*p) && (*p) <= 57 )
              goto tr3;
            goto st0;
            tr3:
            #line 27 "atoi.rl"
            {
               val = val * 10 + ((*p) - '0');
              }
            goto st3;
            st3:
            p += 1;
            case 3:
            #line 63 "atoi.c"
            if ( (*p) == 10 )
              goto tr4;
            if ( 48 <= (*p) && (*p) <= 57 )
              goto tr3;
            goto st0;
            tr4:
            #line 33 "atoi.rl"
            { goto _out4; }
            goto st4;
            st4:
            p += 1;
            case 4:
            #line 74 "atoi.c"
            goto st0;
            }
            _out0: cs = 0; goto _out;
            _out4: cs = 4; goto _out;

            _out: {}
            }
            #line 38 "atoi.rl"


            if ( neg )
              val = -1 * val;

            if ( cs < atoi_first_final )
              cerr << "atoi: there was an error" << endl;

            return val;
            };


            對應的狀態圖如下圖所示:

            clip_image001

             

            正則表達式廣泛應用于解析器中。它們通常被用來作為黑盒與程序邏輯聯系在一起。對正則表達式引擎在執行某些解析工作之后,調用用戶自定義行為。加入新的自定義行為,需要重新定義原來的格局,然后粘貼到程序邏輯中。自定義行為越多,正規表達式的優勢越小。

            Ragel
            是一個可以根據用戶定義的正則表達式或是由正則表達式生成的狀態圖來生成健壯的,無依賴的可執行代碼,包括C,C++,Object-C, Java, Ruby 等等. 可以靈活控制已經生成狀態機的變動,利用已經嵌入自定義行為的模式重構掃描器

            Ragel
            基于任何正規語言能被轉化為有限狀態自動機的原理

            基本的使用步驟如下:

            首先,根據你的業務流程邏輯與需要,按照ragel提供的語法與關鍵字編寫.rl文件

            1
                    編寫.rl文件, 如下所示:

            [Copy to clipboard] [ - ]

            CODE:

            /*
            * to parse a string started with “table” or “div”
            */

            #include <stdlib.h>
            #include <string.h>
            #include <stdio.h>

            %%{
                            #
            狀態機的名字(必須有一個名字而且必須符合命名規則,和變通的變量聲明一樣)
                    machine par_str;
                    write data;
            }%%
            //
            函數聲明,用于在用戶自定義行為中調用,用到了參數的傳遞,此函數也可以是類成員函數
            void printtable(int len)
            {
               printf("there is a table,length is:%d\n",len);
            }

            //
            另外一個函數,功能同上,只是參數傳遞用的是引用傳遞
            void printdiv(char *p)
            {
              printf("%s\n",(*p));
            }
            //
            主處理函數
            void par_str( char *str,int len )
            {
                    char *p = str, *pe = str + strlen( str );
                    int cs;        //
            狀態機關鍵字,用于說明當明狀態,以整型值標識(current status的縮寫)
                            //
            狀態機自定義行為塊
                    %%{
                                    #
            調用自定義函數
                                    action see_table {
                                             printtable(len);
                            }
                           #invoke prindiv function to show the table information, as same as above
                           action see_div {
                                              printdiv(p);
                           }
                           #
            正則表達式聲明,用于在狀態機初始化時,按照此規則匹配目標
                           main :=
                                            ([t][a][b][l][e]@see_table) ([d][i][v]@see_div)+'\n';
                           #
            初始化
                           write init;
                           write exec;
                    }%%

                            if ( cs < par_str_first_final )
                            fprintf( stderr, "par_str: there was an error\n" );
            };

            #define BUFSIZE 1024
            //
            主函數,用于測試生成的狀態機
            int main()
            {
                    char buf[BUFSIZE];
                    while ( fgets( buf, sizeof(buf), stdin ) != 0 )
            {
            par_str(buf,10);
            }
                            return 0;
            }


            接下來,ragel命令生成目的語言文件

            CODE:

            ragel -o test.cpp test.rl


            用代碼生成工具,直接生成可執行代碼

            CODE:

            rlcodegen -o hello.cpp test.cpp


            最后編寫對此代碼的Makefile,make........


             

             

            posted on 2008-12-24 15:18 肥仔 閱讀(3119) 評論(1)  編輯 收藏 引用 所屬分類: 狀態機 & 自動機 & 形式語言

            評論

            # re: Ragel 狀態機簡介  回復  更多評論   

            2009-04-19 19:36 | jans2002
            www.久久热.com| 久久久99精品成人片中文字幕| 国产精品青草久久久久福利99| 久久久久久一区国产精品| 日韩久久久久中文字幕人妻 | 人妻精品久久无码区| 精品国产福利久久久| 亚洲午夜久久久| 精品久久久久久| 国内精品久久久久影院亚洲| 久久天堂AV综合合色蜜桃网| 欧美久久综合性欧美| 99久久精品国产一区二区| 美女久久久久久| 99久久夜色精品国产网站| 亚洲欧美久久久久9999| 国产精品一区二区久久精品| 一本久久免费视频| 99热热久久这里只有精品68| 99蜜桃臀久久久欧美精品网站 | 嫩草影院久久国产精品| 无码人妻久久一区二区三区 | 99久久精品国产一区二区| 国产精品女同久久久久电影院| 久久久久精品国产亚洲AV无码| 色婷婷狠狠久久综合五月| 91精品国产综合久久婷婷| 99精品久久久久久久婷婷| 日韩va亚洲va欧美va久久| 国产99久久久久久免费看| 精品午夜久久福利大片| 中文字幕久久波多野结衣av| 久久久久亚洲av综合波多野结衣| 久久久久久亚洲精品不卡| 久久AAAA片一区二区| 三级韩国一区久久二区综合 | 狠狠色丁香婷婷综合久久来| 久久综合亚洲鲁鲁五月天| 久久久久99这里有精品10| 亚洲中文字幕无码一久久区| 欧美成a人片免费看久久|