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

隨筆 - 31  文章 - 128  trackbacks - 0
<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(5)

隨筆分類(38)

隨筆檔案(31)

收藏夾(4)

College

High School

最新隨筆

搜索

  •  

積分與排名

  • 積分 - 56669
  • 排名 - 407

最新評論

  • 1.?re: [yc]詳解link
  • 面試的時候面試官就問過我什么是編譯和鏈接,我說編譯就是把代碼文件生成目標文件,鏈接就是把目標文件生成可執(zhí)行文件,他說不對,又問我什么是動態(tài)鏈接,還問我預編譯都做什么處理。。。都在這里找到了答案!!!!
  • --王至乾
  • 2.?re: [yc]詳解link
  • @劉偉
    我是說博主,不是叫你啊
  • --溪流
  • 3.?re: [yc]詳解link
  • 誰是石老師,我不是哈@溪流
  • --劉偉
  • 4.?re: [yc]詳解link
  • 石老師?我是溪流~
  • --溪流
  • 5.?re: [yc]詳解link
  • 期待樓主下文啊,多謝樓主了
  • --劉偉

閱讀排行榜

評論排行榜

     摘要:   1。符號查找(對于函數(shù)此時只看名字,不看參數(shù))    大致順序是    (1)如果有限定名( XXX:: )那么就直接在XXX里查找    (2)函數(shù)局部名字空間    (3)(如果是成員)類名字空間    (4)遞歸向上至所有基類的...  閱讀全文
posted @ 2006-12-27 11:04 shifan3 閱讀(2148) | 評論 (8)編輯 收藏


發(fā)信人: shifan (學習浮云技術), 板面: C++
標  題: 偽typeof
發(fā)信站: 飄渺水云間 (Tue Dec 19 16:38:45 2006), 轉信
 1 /*
 2 用標準C++實現(xiàn)typeof是不可能的
 3 這個是我寫的一個approached typeof
 4 所有需要被靜態(tài)反射出來的類型必須先用DECL_TYPE注冊
 5 模板如果僅僅帶有1個參數(shù)可以用DECL_TEMPLATE_1注冊
 6 多個參數(shù)的模板還不支持。。
 7 主要是沒想好編碼
 8 
 9 總共能注冊64個類型
10 可以通過MAX_TYPE_NUMBER設置
11 
12 支持的模板嵌套層數(shù)大約為32 / log2(MAX_TYPE_NUMBER)
13 MAX_TYPE_NUMBER必須為2的整次數(shù)冪
14 */
15 namespace my_typeof
16 {
17 
18   const int MAX_TYPE_NUMBER = 64;
19 
20   template <int N>
21   struct dummy
22   {
23     int a[N];
24   };
25 
26 
27   template <int N, typename Arg1>
28   struct select_by_number_1;
29 
30   template <int N>
31   struct select_by_number
32   {
33     typedef typename select_by_number_1<% MAX_TYPE_NUMBER, typename
34 select_by_number</ MAX_TYPE_NUMBER>::type>::type type;
35   };
36 
37 
38   template <typename T>
39   struct number_of
40   {
41     static const int v = sizeof(generic_f(*(T*)0)) / sizeof(int);
42   };
43 
44 
45 #define DECL_TYPE(T, N) \
46   namespace my_typeof{  \
47   template<>\
48   struct select_by_number<N> \
49   {\
50     typedef T type;\
51   };\
52   dummy <N> generic_f(const T&);}
53 
54 
55 #define DECL_TEMPLATE_1(T, N) \
56   namespace my_typeof{        \
57   template<typename Arg1>\
58   struct select_by_number_1<N, Arg1>\
59   {\
60     typedef T<Arg1> type;\
61   };\
62   template <typename Arg1>\
63   dummy<+ number_of<Arg1>::v * MAX_TYPE_NUMBER > generic_f(const T<Arg1>&);}
64 
65 
66 
67 #define TYPE_OF(x) my_typeof::select_by_number<sizeof(my_typeof::generic_f(x)) /
68 sizeof (int)>::type
69 
70 }
71 
72 
73 //sample
74 #include <iostream>
75 #include <vector>
76 #include <list>
77 
78 
79 DECL_TYPE(int1);
80 DECL_TEMPLATE_1(std::vector, 2);
81 DECL_TEMPLATE_1(std::list, 3);
82 DECL_TYPE(double4)
83 
84 using namespace std;
85 int main(intchar*[])
86 {
87   vector<list<vector<list<double> > > > v1;
88   TYPE_OF(v1) v2;
89   v1 = v2;
90   return 0;
91 }
92 
93 


--
You well 撒法!You well all 撒法!

※ 內(nèi)容修改:·shifan 于 Dec 21 14:21:57 修改本文內(nèi)容·[FROM: shifan]
※ 來源:·飄渺水云間 freecity.cn·[FROM: shifan]
posted @ 2006-12-21 14:29 shifan3 閱讀(2675) | 評論 (8)編輯 收藏

真令人傷感,每過幾年就是離別時。

我站在窗前,無奈的看著朋友們?yōu)榱斯ぷ鞅甲撸?br />而不能幫上哪怕一點忙。
就像十年前,就像六年前,就像三年前
就像每一次與人擦肩而過卻故意目不斜視。
但這一次也許好一點,畢竟我們以后可能還能時常相聚,
而不像現(xiàn)在只能看著從前的好友的博客獨自傷感。
那種陌生,令人心碎。

?

posted @ 2006-11-01 00:31 shifan3 閱讀(610) | 評論 (4)編輯 收藏

boost的integer/integer_mask.hpp僅僅做了單個位的bit mask
要多個位必須寫很多遍high_bit_mask_t
使用low_bits_mask_t也不能完全解決問題
所以自己用Typelist的那種寫法寫了一個

用法舉例
bit_mask<INT_LIST_2(2, 3)>::value返回一個值,該值的第2、3位被置為1
其余位為0

 

  1 
  2 namespace multi_bit_mask
  3 {
  4     namespace details
  5     {
  6 
  7         template <typename T>
  8         struct get_size
  9         {
 10             enum {size = sizeof(T)}; 
 11         };
 12 
 13         template <int Bit>
 14         struct bit_storage
 15         {
 16             typedef typename bit_storage<Bit - 1>::storage_type storage_type;
 17         };
 18 
 19         //---------platform dependency-----------------------
 20 
 21         typedef unsigned int smallest_storage_type;
 22         typedef unsigned long long largest_storage_type;
 23 
 24         
 25 
 26         template <>
 27         struct bit_storage<0>
 28         {
 29             typedef smallest_storage_type storage_type;
 30         };
 31 
 32         template <>
 33         struct bit_storage<get_size<smallest_storage_type>::size * 8>
 34         {
 35             typedef largest_storage_type storage_type;
 36         };
 37 
 38         //disable the 65th bit
 39         template <>
 40         struct bit_storage<get_size<largest_storage_type>::size * 8>
 41         {
 42             typedef void storage_type;
 43         };
 44         
 45         //---------end of platform dependency----------------
 46 
 47 
 48         template <unsigned int N, typename Next>
 49         struct int_list
 50         {
 51             typedef typename bit_storage<N>::storage_type storage_type;
 52             static const storage_type value = N;
 53             typedef Next next;
 54         };
 55 
 56         struct null_type{};
 57 
 58         template<typename T1, typename T2, bool is_first>
 59         struct selector
 60         {
 61             typedef T1 type;
 62         };
 63 
 64         template<typename T1, typename T2>
 65         struct compare_type
 66         {
 67             const static bool is_larger = sizeof(T1) > sizeof(T2);
 68             typedef typename selector<T1, T2, is_larger>::type large_type;
 69             typedef typename selector<T1, T2, !is_larger>::type small_type;
 70         };
 71 
 72 
 73 
 74         template<typename T1, typename T2>
 75         struct selector<T1, T2, false>
 76         {
 77             typedef T2 type;
 78         };
 79 
 80         template <typename List>
 81         class find_largest_storage
 82         {
 83             typedef typename find_largest_storage<typename List::next>::storage_type T1;
 84             typedef typename bit_storage<List::value>::storage_type T2;
 85         public:
 86             typedef typename compare_type<T1, T2>::large_type storage_type;
 87         };
 88 
 89         template <>
 90         class find_largest_storage<null_type>
 91         {
 92         public:
 93             typedef smallest_storage_type storage_type;
 94         };    
 95 
 96         
 97     }
 98 
 99 
100         
101 
102 
103     template <int N>
104     struct single_bit_mask
105     {
106         typedef typename details::bit_storage<N>::storage_type storage_type;
107         static const storage_type value 
108             = static_cast<storage_type>(single_bit_mask<- 1>::value) * 2;
109     };
110 
111     template <>
112     struct single_bit_mask<0>
113     {
114         typedef details::bit_storage<0>::storage_type storage_type;
115         static const storage_type value = 1;
116     };
117 
118     
119     typedef details::null_type null_type;
120 
121     template <int N, typename Next>
122     struct int_list_t : public details::int_list<N, Next> {};
123 
124     template <typename List>
125     struct bit_mask
126     {
127     public:
128 
129         typedef typename details::find_largest_storage<List>::storage_type storage_type;
130     
131         static const storage_type value 
132             = static_cast<storage_type>(single_bit_mask<List::value>::value) 
133             | static_cast<storage_type>(bit_mask<typename List::next>::value);
134     };
135 
136     template <>
137     struct bit_mask<null_type>
138     {
139         typedef details::bit_storage<0>::storage_type storage_type;
140         static const storage_type value = 0;
141     };
142 
143     
144 
145     
146 
147     #define INT_LIST_1(n1) multi_bit_mask::int_list_t<n1, multi_bit_mask::null_type>
148     #define INT_LIST_2(n1, n2) multi_bit_mask::int_list_t<n1, INT_LIST_1(n2) > 
149     #define INT_LIST_3(n1, n2, n3) multi_bit_mask::int_list_t<n1, INT_LIST_2(n2, n3) > 
150     #define INT_LIST_4(n1, n2, n3, n4) multi_bit_mask::int_list_t<n1, INT_LIST_3(n2, n3, n4) > 
151     #define INT_LIST_5(n1, n2, n3, n4, n5) multi_bit_mask::int_list_t<n1, INT_LIST_4(n2, n3, n4, n5) > 
152     #define INT_LIST_6(n1, n2, n3, n4, n5, n6) multi_bit_mask::int_list_t<n1, INT_LIST_5(n2, n3, n4, n5, n6) > 
153     #define INT_LIST_7(n1, n2, n3, n4, n5, n6, n7) multi_bit_mask::int_list_t<n1, INT_LIST_6(n2, n3, n4, n5, n6, n7) > 
154     #define INT_LIST_8(n1, n2, n3, n4, n5, n6, n7, n8) multi_bit_mask::int_list_t<n1, INT_LIST_7(n2, n3, n4, n5, n6, n7, n8) > 
155     
156 }
157 
158 
159 


sample

#include  < iostream >
#include 
" multi_bit_mask.h "
using   namespace  std;
int  main()
{
    cout 
<<  multi_bit_mask::bit_mask < INT_LIST_1( 1 ) > ::value  <<  endl;
    cout 
<<  multi_bit_mask::bit_mask < INT_LIST_5( 0 1 2 3 4 ) > ::value  <<  endl;
    cout 
<<  multi_bit_mask::bit_mask < INT_LIST_7( 0 1 2 3 4 4 2 ) > ::value  <<  endl;
    
posted @ 2006-10-26 23:37 shifan3 閱讀(1475) | 評論 (2)編輯 收藏

    近日在學校bbs上與人討論C++的typeid關鍵字的實現(xiàn)問題,有人提到type_info的地址是存放在虛表的第一個位置上,頗覺得不妥,于是我在vc2003下實驗了一番

    在vc下,使用typeid的時候,如果typeid施加給的類型是沒有vptr的class或者根本不是class
那么匯編是
mov  dword ptr [addr],offset A `RTTI Type Descriptor' (42AD40h)
也就是編譯器生成一個簡單的type_info對象的表,并且在編譯期靜態(tài)決定下標,做一個簡單查表操作。

如果typeid的操作對象是具有vptr的class,但是并不是一個引用或者指針的解引用形式,例如

A a;
typeid(a);


那么仍然僅僅會做查表操作


如果typeid的操作對象是具有vptr的class,并且是引用或者指針的解引用形式,例如

* =   new  A;
A
&  r  =   * p;
typeid(
* p);
typeid(r);


那么就會調用一個叫___RTtypeid的函數(shù),并通過某種方法來獲取type_info對象
下面是___RTtypeid的反匯編,這里只列出關鍵的幾條指令

0041213E  mov         ecx,dword ptr [inptr]    ;inptr是對象的地址
00412141   mov         edx,dword ptr [ecx] 
00412143   mov         eax,dword ptr [edx - 4
0041215F  mov         ecx,dword ptr [eax
+ 0Ch] 
00412162   mov         dword ptr [ebp - 48h],ecx 
0041216C  mov         eax,dword ptr [ebp
- 48h] 


基本上等價于C語言的

int  a1  =  ( int )p;  // p是對象的地址
int  a2  =   * ( int * )a1  -   4 ;
int  a3  =   * ( int * )a2  +   12 ;
int  a4  =   * ( int * )a3;

 

那么從這段代碼可以看出vc下type_info對象的存放位置[如下圖]



也就虛表下標為-1的位置上存放了一個指向一個未知的表的指針(暫且將此表命名為runtime_info_table)
runtime_info_table的第4格上存放了type_info對象的地址
至于runtime_info_table里前3格上存放的是什么, 還需要再研究研究
一般來說它們?nèi)?, 但是對于多重虛繼承的類, 第二格上會是4, 可能和指針的偏移量有關.

posted @ 2006-10-26 10:46 shifan3 閱讀(3368) | 評論 (5)編輯 收藏
Xpressive是一個C++的正則表達式庫,目前是Boost的候選庫。
Xpressive和Boost.Regex的區(qū)別很大。首先,Xpressive是一個純頭文件的庫,也是說,在使用之前不需要預先編譯。其次,Xpressive支持類似于Spirit的靜態(tài)語義定義。

我們先來看一個例子:

 

#include <iostream>
#include 
<boost/xpressive/xpressive.hpp>

using namespace boost::xpressive;

int main()
{
    std::
string hello( "hello world!" );

    sregex rex 
= sregex::compile( "(\\w+) (\\w+)!" );
    smatch what;

    
if( regex_match( hello, what, rex ) )
    {
        std::cout 
<< what[0<< '\n'// whole match
        std::cout << what[1<< '\n'// first capture
        std::cout << what[2<< '\n'// second capture
    }

    
return 0;
}

這是使用Xpressive動態(tài)語義定義的例子,其中sregex::compile函數(shù)編譯一個表示正則文法的串,并返回一個正則對象sregex
使用regex_match來使用這個正則對象匹配一個串。結果儲存在what內(nèi)
其中what[0]返回整個串,what[1]~what[n]返回文法中用于標記的部分(用小括號括起來的部分)
最后將輸出
     hello world!
     hello
     world

如果想在一個串中查找符合該文法的子串,可以使用regex_search,用法和regex_match一樣,此外還可以用regex_replace來進行替換。

 


靜態(tài)文法:
Xpressive除了可以用compile來分析一個文法串之外,還可以用類似于Spirit的方式來靜態(tài)的指定文法:

sregex re = '$' >> +_d >> '.' >> _d >> _d;

這將定義一個表示金額的串,其中_d表示一個數(shù)字,相當于串 $\d+.\d\d
這樣定義文法將比之前的動態(tài)定義更加高效,并且還有一個附加的好處:
分級定義:

sregex re = '$' >> +_d >> '.' >> _d >> _d;
sregex s 
= '(' >> re >> ')';

這樣s表示為用括號括起來的re
通過分級定義,文法能被表示的更加清楚。
更加棒的是,分級定義還可以向后引用,因此能夠分析EBNF

sregex group, factor, term, expression;
group       
= '(' >> by_ref(expression) >> ')';
factor      
= +_d | group;
term        
= factor >> *(('*' >> factor) | ('/' >> factor));
expression  
= term >> *(('+' >> term) | ('-' >> term));

expression定義了一個四則表達式,注意其中group的定義。
這里必須使用by_ref是因為Xpressive默認是值拷貝,如果這里使用默認的方式,那么會造成一個無限循環(huán)。


Xpressive可以在這里下載
http://boost-consulting.com/vault/index.php?PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535&direction=0&order=&directory=Strings%20-%20Text%20Processing&PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535
內(nèi)有詳細的文檔

posted @ 2006-07-27 16:27 shifan3 閱讀(3144) | 評論 (4)編輯 收藏

看了546@C++@Freecity之后,發(fā)覺非常有意思,由此產(chǎn)生一些想法

很多時候寫一個類的時候,需要多個模版參數(shù),例如一個遺傳算法的算法類,需要一個模版參數(shù)來指定交配方式,另一個模版參數(shù)來指定子代選擇的方式,還要一個參數(shù)來指定變異的方式。那么一般來說,這個類會寫成:

template<class T                                                //描述問題的一個類
        , class CrossPolicy = AvgCrossPolicy                        //雜交方式
        , class SelectPolicy = DefaultSelectPolicy                //子代選擇的方式
        , class VariationPolicy = ReverseVariationPolicy>        //變異方式
class Gene
        : private AvgCrossPolicy
        , private SelectPolicy
        , private VariationPolicy
{
        ....
};

這樣用戶要使用該類的時候,可以直接指定T,就行了,然而如果要指定變異方式,那么就必須把所有的參數(shù)都顯式的寫出來,很不方便

546提供了一種有效的方法,可以讓我們僅僅指定變異參數(shù),而不用寫出另兩個Policy
甚至允許我們以任意的順序書寫幾個Policy參數(shù),都不會有問題

預備知識:
TypeList
一個TypeList是一個類型的容器
template <typename Type_, typename Next_>
struct TypeList
{
        typedef Type_ Type;
        typedef Next_ Next;
};
這就是一個TypeList。
看這個寫法,是不是像一個鏈表?
首先定義一個類型來表示鏈表尾:class NullType{};
現(xiàn)在一個包含了2個類型的TypeList就可以寫為:
TypeList<T1, TypeList<T2, NullType>  >

如何在一個TypeList中查找一個類型的子類?
首先要有一個IsDerivedFrom<Base, T>
這個比較簡單
template<class Base, class T>
class IsDerivedFrom
{
        struct large{char a[2];};
        static char pred(Base*);
        static large pred(...);
public:
        enum {Is = sizeof(pred((T*)0)) == sizeof(char)};
};

然后FindChild就容易了
template <class List, class Base>
struct FindChild
{
        template <bool IsChild>
        struct Select
        {
                typedef typename List::Type Type;
        };

        template <>
        struct Select<false>
        {
                typedef typename FindChild<typename List::Next, Base>::Type Type;
        };

        typedef typename Select<IsDerivedFrom<Base, typename List::Type> >::Type Type;
};

當然還要對一些特殊情況進行特化,例如NullType
template <class Base>
struct FindChild<NullType, Base>
{
        typedef NullType Type;
};
這里使用NullType來表明沒找到

實際操作:
首先需要給3個Policy3個基類,分別叫
class AvgCrossPolicyBase{};
class SelectPolicyBase{};
class VariationPolicyBase{};
內(nèi)容為空就行了,這樣也沒有虛函數(shù)調用的開銷


然后聲明一個類來表示默認情況:
class DefaultPolicy{};

定義一個宏
#define TYPELIST_3_N(a, b, c) TypeList<a, TypeList<b, TypeList<c, NullType> > >

下面要寫一些選擇器,用于把合適的類型選擇出來,如果沒找到,則要使用默認的類型
template <class List, class Base, class DefaultType>
struct Selector
{
        template <class RetType>
        struct Judge
        {
                typedef RetType Type;
        };
       
        template<>
        struct Judge<NullType>
        {
                typedef DefaultType Type;
        };
        typedef typename Judge<typename FindChild<List, Base>::Type >::Type Type;
};

好啦,現(xiàn)在整個類的聲明可以寫為

template<class T
        , class CrossPolicy_ = DefaultPolicy
        , class SelectPolicy_ = DefaultPolicy
        , class VariationPolicy_ = DefaultPolicy     //其后的參數(shù)用戶不可指定
        , class List = TYPELIST_3_N(CrossPolicy_, SelectPolicy_, VariationPolicy_)
        , class CrossPolicy = typename Selector<List, CrossPolicyBase,  AvgCrossPolicy>::Type
        , class SelectPolicy = typename Selector<List,  SelectPolicyBase,  DefaultSelectPolicy>::Type
        , class VariationPolicy = typename Selector<List,  VariationPolicyBase,  ReverseVariationPolicy>::Type
        >
class Gene
        : private CrossPolicy
        , private SelectPolicy
        , private VariationPolicy
{
       
        ....
};


其中第4-7個參數(shù)(List,CrossPolicy,SelectPolicy和VariationPolicy)是不由用戶指定的,僅僅是為了起一個別名
第一個參數(shù)T必須指定,然后2,3,4這3個參數(shù)就可以任意的改變順序了
例如,可以寫Gene<T, DefaultSelectPolicy, AvgCrossPolicy>而不會有任何問題
如果不想要最后面幾個參數(shù)的話也行,但是代碼就要稍微長一點
而且最好在類里面進行3個typedef
typedef typename Selector<List, CrossPolicyBase,  AvgCrossPolicy>::Type CrossPolicy;
等,以便在實現(xiàn)的時候使用

posted @ 2006-07-24 01:06 shifan3 閱讀(1032) | 評論 (9)編輯 收藏
     摘要: 發(fā)信人: shifan (家沒有豚豚 T.T), 板面: C++標  題: 如何實現(xiàn)Lambda[第二部分]發(fā)信站: 飄渺水云間 (Thu Jun  8 23:30:20 2006), 轉信 章節(jié):八:第一部分的小結九:簡化,如何減少Lambda代碼的冗余和依賴性十:bind的實現(xiàn)十一:實現(xiàn)phoenix 八.    中期總結目前的結果是這樣的...  閱讀全文
posted @ 2006-07-15 15:32 shifan3 閱讀(1017) | 評論 (0)編輯 收藏
     摘要: 一. 什么是Lambda所謂Lambda,簡單的說就是快速的小函數(shù)生成。在C++中,STL的很多算法都要求使用者提供一個函數(shù)對象。例如for_each函數(shù),會要求用戶提供一個表明“行為”的函數(shù)對象。以vector<bool>為例,如果想使用for_each對其中的各元素全部賦值為true,一般需要這么一個函數(shù)對象,     c...  閱讀全文
posted @ 2006-06-09 13:23 shifan3 閱讀(3012) | 評論 (7)編輯 收藏

    最近為了解析SQL語法,懷著試一試的心態(tài)去翻了翻boost的spirit庫,因為該庫的文檔的簡介里寫著LL parser framework  represents parsers directly as EBNF grammars in inlined C++。看著framework這個詞自然覺得這個庫很牛B,試用了一下果然如此。
    所謂EBNF即擴展巴克斯范式,是一種描述Context-Free Language的文法。在目前常見的非自然語言中,大部分都可以用EBNF表示。例如:
      group  ::='('exp
')'
      factor ::=integer|
group
      term   ::=factor(('*'factor)|('/'factor
))*
      exp    ::=term(('+'term)|('-'term
))*
這是一個整數(shù)表達式的EBNF。該段描述用spirit在C++中的實現(xiàn)則是:
   

   rule<> group, factor, term, exp;
   group  
= '(' >> exp >> ')';
   factor 
= int_p | group;
   term   
= factor >> *(('*' >> factor) | ('/' >> factor));
   exp    
= term >> *(('+' >> term) | ('-' >> term));

這里使用=代替::=, 用>>代替空格連接。并且由于C++語法所限,EBNF中后置的*在spirit中改為前置。
等式左邊的單詞被稱為一個rule,等式右邊為rule的定義。我們可以看出一個group是一個exp加上一對括號,一個factor是一個整數(shù)或者一個group,一個term是一個或多個factor用*/連接,一個exp是一個或多個term用+-連接。處于最頂端的exp可以據(jù)此識別出以下表達式
   

   12345
   
-12345
   
+12345
   
1 + 2
   
1 * 2
   
1/2 + 3/4
   
1 + 2 + 3 + 4
   
1 * 2 * 3 * 4
   (
1 + 2* (3 + 4)
   (
-1 + 2* (3 + -4)
   
1 + ((6 * 200- 20/ 6
   (
1 + (2 + (3 + (4 + 5))))

    得到一個rule之后,我們就可以用 parse函數(shù)對一個串進行識別了。例如
         

         parse( " (1 + (2 + (3 + (4 + 5)))) " , exp);


該函數(shù)返回一個結構parse_info,可以通過訪問其中的full成員來判斷是否成功識別,也可以訪問stop成員來獲知失敗的位置。這里要特別提一點,關于各個符號之間的空格,spirit的文檔的正文說的是給parse再傳一個參數(shù)space_p,通知parse跳過所有的空格,然而在FAQ中又提到,如果使用以上方法定義rule,第三個參數(shù)傳space_p會失敗。原因是使用rule默認定義的規(guī)則被稱為character level parsing,即字符級別解析,而parse的第3個參數(shù)僅適用于phrase level parsing,即語法級別解析。要使用第3個參數(shù)可以有幾種方法。
      1。在parse的第二個參數(shù)直接傳入一個EBNF表達式,不創(chuàng)建rule對象。
         

            parse( " hello world " * anychar_p, space_p);  


      2。以rule<phrase_scanner_t>創(chuàng)建rule。
         

            rule < phrase_scanner_t >  exp; 

注意雖然可以用這兩個辦法屏蔽空格,但是這樣可能完全改變EBNF文法的語義,尤其是在語言本身需要識別空格的時候。對于這種情況,可以不使用第三個參數(shù),并在需要出現(xiàn)空格的地方加上space_p,或者+space_p及*space_p,其中+和*分別表示后面的符號連續(xù)出現(xiàn)一次以上和0次以上。例如一個以空格分隔的整數(shù)列表可以寫成int_p >> *(+space_p >> int_p)
   如上使用parse可以識別一個串,但并不能做更多的操作,例如將語法里的各個成分提取出來。對于這樣的需求,可以通過actor實現(xiàn)。下面是使用actor的一個簡單例子
   

   bool
   parse_numbers(
char const* str, vector<double>& v)
   
{
      
return parse(str,

   
//  Begin grammar
      (
         real_p[push_back_a(v)] 
>> *(',' >> real_p[push_back_a(v)])
      )
      ,
      
//  End grammar
      space_p).full;
   }

注意到real_p后面的[],中括號里面是一個仿函數(shù)(函數(shù)指針或者函數(shù)對象),該仿函數(shù)具有如下調用型別
   

   void operator()(IterT first, IterT last) const;
   
void operator()(NumT val) const;
   
void operator()(CharT ch) const;


一旦spase發(fā)現(xiàn)了匹配real_p的子串,就會調用該functor。不同的rule可能會對應不同的調用型別。
第一個型別針對一般規(guī)則,first和last為兩個指向字符的迭代器(一般為char*),匹配的子串為[first, last)
第二個型別針對數(shù)字型規(guī)則,如real_p和int_p, 參數(shù)val是一個數(shù)字類型。
第三個性別針對單字符型規(guī)則,如space_p, 參數(shù)ch是一個字符類型。
real_p[push_back_a(v)]中的push_back_a是一個spirit已經(jīng)定義好的functor,它會將匹配好的內(nèi)容依照匹配到的時間順序調用v的push_back函數(shù)加入到v中。

   到此spirit的常用功能就都介紹完了。要詳細深入了解可以參考spirit的文檔。

最后在題一個注意要點。spirit的各種EBNF連接都是指針連接,因此才能在expression被賦值前就在group的定義里面使用。所以在使用EBNF的時候一定要小心不要將局部變量的rule提供給全局或者類成員變量使用,例如:
   

   class A
   
{
      rule
<> s;
      A()
      
{
         rule
<> r = int_p | hex_p;

         s 
= r >> *(+space_p >> r); //error, r destructed after return 
      }

   }
;

如果真想使用局部作用域,可以在局部的rule前面加上static.

posted @ 2005-12-18 12:02 shifan3 閱讀(7148) | 評論 (5)編輯 收藏
僅列出標題
共3頁: 1 2 3 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产精品亚洲第一区在线暖暖韩国| 亚洲午夜久久久久久久久电影院 | 亚洲欧洲一区二区天堂久久 | 久久精品女人| 久久精品国产精品亚洲精品| 久久精品亚洲| 久久综合中文字幕| 免费观看在线综合色| 欧美a级一区| 国产精品入口福利| 伊人精品成人久久综合软件| 亚洲精品一品区二品区三品区| 亚洲精品美女在线观看| 亚洲午夜一区二区三区| 久久激五月天综合精品| 欧美国产先锋| 亚洲一区二区三区中文字幕在线| 久久国产视频网站| 欧美日韩国产精品一区二区亚洲 | 亚洲麻豆一区| 亚洲欧美日韩区| 欧美1级日本1级| 一区二区三区www| 久久频这里精品99香蕉| 欧美日韩一区二区三区高清| 国产亚洲欧美色| 99综合在线| 欧美成人三级在线| 亚洲欧美日韩国产| 欧美日韩视频免费播放| 亚洲电影免费观看高清完整版在线 | 久久精品视频亚洲| 亚洲人成人一区二区三区| 亚洲一区二区三区午夜| 欧美电影免费观看大全| 国产一区二区三区四区五区美女| 亚洲美女诱惑| 欧美电影电视剧在线观看| 欧美一区=区| 国产精品久久久久久av福利软件 | 久久婷婷久久一区二区三区| 日韩午夜在线电影| 久久综合久久久| 国产一区二区电影在线观看| 亚洲午夜一区| 一级日韩一区在线观看| 欧美高清在线视频观看不卡| 在线高清一区| 久久久久国产精品人| 亚洲综合精品| 国产精品麻豆成人av电影艾秋| 日韩一区二区免费高清| 欧美国产视频一区二区| 欧美一区二区三区男人的天堂| 欧美国产精品人人做人人爱| 久久国产欧美精品| 韩国三级电影久久久久久| 久久er精品视频| 欧美一区观看| 国内精品视频在线观看| 久久久久久欧美| 性欧美8khd高清极品| 国产日韩欧美日韩| 久久精品三级| 久久蜜桃精品| 亚洲乱码精品一二三四区日韩在线 | 亚洲高清免费视频| 蜜臀99久久精品久久久久久软件 | 亚洲精品国产系列| 欧美激情第4页| 欧美日韩国产欧| 性欧美1819sex性高清| 午夜精品久久久久久久久| 国产亚洲欧美日韩美女| 蜜桃精品久久久久久久免费影院| 久久亚洲综合| 一本色道久久综合精品竹菊| 亚洲视频axxx| 国产综合色产在线精品| 欧美国产欧美亚州国产日韩mv天天看完整| 久热精品在线视频| 亚洲最新在线| 香蕉久久国产| 亚洲精品日韩激情在线电影 | 亚洲网站在线观看| 国产一区二区欧美日韩| 欧美华人在线视频| 国产精品一区久久久| 免费日韩成人| 国产精品久久久久久影院8一贰佰| 欧美主播一区二区三区美女 久久精品人| 欧美一区二区黄色| 99re亚洲国产精品| 国产精品一区二区你懂得| 欧美亚洲综合在线| 欧美在线精品免播放器视频| 亚洲激情视频在线观看| 亚洲午夜高清视频| 91久久在线观看| 亚洲欧美日本视频在线观看| 亚洲精品国产精品乱码不99按摩 | 性欧美暴力猛交69hd| 玖玖在线精品| 亚洲自啪免费| 欧美国产日韩精品免费观看| 久久www成人_看片免费不卡 | 亚洲欧美日韩中文播放| 亚洲国产高清高潮精品美女| 在线综合欧美| 最近中文字幕mv在线一区二区三区四区 | 欧美午夜不卡视频| 欧美成人一区二免费视频软件| 国产精品麻豆va在线播放| 亚洲第一页自拍| 狠狠做深爱婷婷久久综合一区| 一区二区三区精密机械公司| 亚洲人成在线播放| 久久精品一区二区三区不卡| 销魂美女一区二区三区视频在线| 欧美成人精品三级在线观看| 免费一区二区三区| 国产一区二区观看| 亚洲综合三区| 欧美一级在线播放| 国产精品igao视频网网址不卡日韩| 亚洲国产美女久久久久| 在线观看日韩专区| 久久国产日本精品| 久久人人爽人人爽| 狠狠色丁香久久综合频道| 亚洲欧美成人一区二区三区| 亚洲欧美激情在线视频| 欧美日韩精品高清| 亚洲人成小说网站色在线| 91久久精品国产91久久性色tv| 麻豆精品一区二区综合av| 久久久综合网站| 黑人极品videos精品欧美裸| 久久精品91久久香蕉加勒比| 久久免费视频一区| 激情综合在线| 免费在线看一区| 亚洲国产天堂久久综合网| 亚洲日本视频| 欧美日精品一区视频| 亚洲永久字幕| 久久久精品日韩欧美| 一区二区视频在线观看| 久久婷婷色综合| 欧美韩日一区二区三区| 99这里只有精品| 国产精品色婷婷| 久久精品国产一区二区电影| 你懂的亚洲视频| 一本大道久久a久久精品综合| 日韩亚洲欧美成人| 久热精品视频在线观看| 欧美日韩一区视频| 亚洲人成网在线播放| 91久久精品日日躁夜夜躁国产| 久久亚洲私人国产精品va| 免费成人av| 亚洲福利视频一区| 美国成人毛片| 亚洲美洲欧洲综合国产一区| 亚洲一区久久久| 国产午夜精品美女视频明星a级| 羞羞视频在线观看欧美| 久久久久久久综合日本| 精品1区2区| 亚洲视频在线视频| 国产精品a久久久久| 久久精品国产亚洲高清剧情介绍| 欧美成人国产| 亚洲一区二区三区四区视频 | 国产精品久久久久免费a∨大胸| 午夜日韩电影| 91久久精品一区二区三区| 亚洲欧美一区二区三区在线| 国产中文一区| 国产精品扒开腿做爽爽爽软件 | 国产精品亚洲综合一区在线观看 | 美女免费视频一区| 亚洲一区二区三区乱码aⅴ| 激情一区二区| 国产精品无码专区在线观看| 欧美在线首页| 一区二区三区视频在线播放| 欧美激情bt| 狼人社综合社区| 久久精品国产亚洲高清剧情介绍| 日韩视频在线你懂得| 一区二区三区在线观看欧美| 国产精品成人一区二区艾草| 欧美jizz19hd性欧美| 久久先锋资源| 久久久精品一区| 午夜欧美不卡精品aaaaa| 99热精品在线观看| 亚洲日本成人网|