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

隨筆 - 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>
            久久国产精品电影| 激情欧美一区二区三区| 一本色道久久综合狠狠躁篇的优点 | 欧美不卡三区| 亚洲三级视频在线观看| 夜夜嗨av一区二区三区网站四季av| 欧美人成免费网站| 午夜国产不卡在线观看视频| 久久久久久自在自线| 亚洲人成绝费网站色www| 欧美视频在线视频| 久久爱www.| 亚洲精品视频在线观看网站| 欧美亚洲视频| 亚洲区一区二区三区| 国产精品视频| 免费91麻豆精品国产自产在线观看| 日韩视频在线你懂得| 久久久久国色av免费看影院| 亚洲美女免费视频| 国产精品永久免费在线| 蜜桃av噜噜一区| 亚洲综合精品四区| 亚洲经典在线| 性欧美xxxx视频在线观看| 欧美一区二区三区电影在线观看 | 猫咪成人在线观看| 亚洲淫性视频| 亚洲欧洲精品一区二区三区波多野1战4| 亚洲影院色在线观看免费| 在线成人av| 国产精品久久久久一区二区三区共| 久久久久欧美精品| 亚洲在线观看视频网站| 亚洲高清av在线| 久久精品国产久精国产思思| 宅男精品视频| 亚洲人被黑人高潮完整版| 国产日韩精品在线| 欧美香蕉大胸在线视频观看| 免费亚洲电影在线观看| 久久精品国产欧美激情| 亚洲一区二区久久| 日韩网站在线| 欧美激情在线有限公司| 久久免费观看视频| 欧美在线一级va免费观看| 亚洲天堂网在线观看| 亚洲人久久久| 亚洲高清不卡在线| 国内精品久久久久影院色| 国产精品入口福利| 国产精品v一区二区三区| 欧美人成网站| 欧美日韩精品在线视频| 欧美激情片在线观看| 老司机一区二区| 久久偷窥视频| 久久女同互慰一区二区三区| 欧美一区二区视频观看视频| 亚洲欧美中文日韩v在线观看| 亚洲视频高清| 亚洲主播在线| 性高湖久久久久久久久| 午夜视频久久久| 欧美亚洲在线播放| 欧美亚洲视频| 久久久国产精品一区| 久久久精品视频成人| 久久精品视频va| 久久久久久久高潮| 另类图片综合电影| 欧美激情1区2区3区| 欧美精品乱码久久久久久按摩| 欧美第一黄色网| 欧美精品在线一区| 国产精品mv在线观看| 国产精品毛片va一区二区三区| 国产精品久久久久久久一区探花| 国产精品女主播| 国产综合色在线视频区| 极品日韩久久| 亚洲精品视频一区| 一区二区三区鲁丝不卡| 亚洲在线播放电影| 久久精品一区二区三区四区 | 一本一本大道香蕉久在线精品| 一区二区不卡在线视频 午夜欧美不卡'| 亚洲精品久久久久久下一站 | 狠狠色丁香婷婷综合| 亚洲电影视频在线| 夜夜嗨av一区二区三区免费区| 亚洲一区二区网站| 久久精品视频在线看| 欧美激情一区二区三区成人| 亚洲精品一区二区网址| 亚洲一区免费网站| 久久先锋影音av| 欧美日本亚洲| 国产一区二区三区免费在线观看| 国内外成人免费视频| 亚洲免费观看高清完整版在线观看熊 | 亚洲在线第一页| 久久这里只有精品视频首页| 欧美区一区二| 国色天香一区二区| 一区二区三区免费看| 久久久99久久精品女同性| 亚洲大胆女人| 亚洲欧美日韩国产一区二区三区 | 精品99一区二区| 在线一区二区日韩| 老司机午夜免费精品视频| 亚洲精品小视频在线观看| 欧美亚洲系列| 欧美性开放视频| 亚洲国产日韩欧美在线图片| 午夜精品久久久久久久99水蜜桃 | 久久国产精品一区二区三区| 欧美巨乳在线| 在线观看国产精品淫| 亚洲尤物视频在线| 亚洲国产欧美国产综合一区| 欧美一级在线亚洲天堂| 欧美日韩一级大片网址| 亚洲成色999久久网站| 小黄鸭视频精品导航| 亚洲欧洲一二三| 久久这里只有| 国产自产在线视频一区| 亚洲综合第一页| 亚洲人成久久| 美女主播一区| 韩国视频理论视频久久| 欧美亚洲一区二区三区| 亚洲精品欧美| 欧美激情bt| 亚洲经典一区| 免费中文日韩| 久久精品男女| 国产有码一区二区| 性欧美1819sex性高清| 日韩网站在线观看| 欧美激情精品久久久久| 亚洲欧洲日产国产综合网| 另类综合日韩欧美亚洲| 久久成年人视频| 国产一区在线视频| 久久精品视频在线| 欧美中文字幕在线观看| 国产人成精品一区二区三| 亚洲尤物视频网| 一区二区三区四区国产| 欧美日韩网址| 亚洲午夜在线视频| 9色精品在线| 国产精品国产三级国产普通话99| 亚洲天天影视| 亚洲永久免费| 国产婷婷一区二区| 久久久久久久久久看片| 久久精品国产96久久久香蕉| 狠狠色丁香久久婷婷综合丁香 | 亚洲黄色视屏| 欧美日本在线| 亚洲综合色自拍一区| 亚洲尤物在线| 国产一区二区精品丝袜| 久久综合给合久久狠狠狠97色69| 久久精品国产99国产精品澳门| 黄色一区二区在线观看| 欧美成人有码| 欧美久久婷婷综合色| 亚洲一区二区精品| 亚洲欧美日韩在线| 黄色影院成人| 亚洲激情一区二区| 国产精品99免费看 | 一区二区三区四区国产精品| 国产精品福利在线观看网址| 欧美一区二区精美| 久久狠狠亚洲综合| 亚洲精品国产欧美| 99视频国产精品免费观看| 国产精品一页| 欧美电影在线免费观看网站| 欧美激情中文不卡| 午夜影院日韩| 久色成人在线| 亚洲欧美国产77777| 欧美在线视频免费播放| 亚洲精品在线一区二区| 亚洲视频播放| 亚洲国产精品一区二区三区| 一本色道久久综合精品竹菊| 国产一区二区三区免费在线观看 | 99精品99| 欧美一区1区三区3区公司| 亚洲精品视频在线播放| 亚洲一区在线看|