• <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
            是一個可以根據用戶定義的正則表達式或是由正則表達式生成的狀態圖來生成健壯的,無依賴的可執行代碼,包括CC++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
            久久久久国产精品嫩草影院| 亚洲国产精品婷婷久久| 欧美色综合久久久久久| 午夜精品久久久久久久无码| 中文字幕精品久久久久人妻| 无码人妻久久一区二区三区免费| 久久久久亚洲AV无码麻豆| 国产免费久久精品99久久| 波多野结衣久久一区二区| 久久99国产精品一区二区| 亚洲国产成人久久笫一页| 国产精品99久久99久久久| 久久中文字幕视频、最近更新| 亚洲AV日韩精品久久久久久| 国产激情久久久久影院小草| 日韩精品久久无码中文字幕| 久久久久人妻一区精品| 国产午夜免费高清久久影院| 国产精品乱码久久久久久软件| 久久久久久综合一区中文字幕| 久久久亚洲裙底偷窥综合| 亚洲综合婷婷久久| 99久久精品午夜一区二区| 色8久久人人97超碰香蕉987| 2021国产精品久久精品| 亚洲欧美另类日本久久国产真实乱对白| 99久久精品国产麻豆| 国产69精品久久久久9999APGF| 热久久国产欧美一区二区精品| 99久久久久| 99久久精品费精品国产| 青青青青久久精品国产| 精品亚洲综合久久中文字幕| 亚洲va久久久噜噜噜久久天堂| 精品久久久无码21p发布| 久久久久亚洲AV成人网人人网站 | 亚洲综合久久夜AV | 国产亚州精品女人久久久久久| 丁香狠狠色婷婷久久综合| av无码久久久久久不卡网站| 久久精品国产亚洲AV电影|