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

隨筆-341  評論-2670  文章-0  trackbacks-0
    雖然說分析語法樹依賴于遞歸,但是你真的去寫遞歸那是一件很煩的事情,個人覺得煩事煩在你每次都要去RegexExpression.h里面聲明所有的虛函數之后復制過來一一運行。有沒有辦法僅編輯.cpp文件就能做到呢?也就是說,在如何不修改Expression一系列類的接口的情況下給Expression添加算法?一般來說對付樹形結構都是使用Visitor模式的。

    首先對于上一篇文章定義的樹來看,我們需要設計一個通用的Visitor接口:
 1         class IRegexExpressionAlgorithm : public Interface
 2         {
 3         public:
 4             virtual void                Visit(CharSetExpression* expression)=0;
 5             virtual void                Visit(LoopExpression* expression)=0;
 6             virtual void                Visit(SequenceExpression* expression)=0;
 7             virtual void                Visit(AlternateExpression* expression)=0;
 8             virtual void                Visit(BeginExpression* expression)=0;
 9             virtual void                Visit(EndExpression* expression)=0;
10             virtual void                Visit(CaptureExpression* expression)=0;
11             virtual void                Visit(MatchExpression* expression)=0;
12             virtual void                Visit(PositiveExpression* expression)=0;
13             virtual void                Visit(NegativeExpression* expression)=0;
14             virtual void                Visit(UsingExpression* expression)=0;
15         };

    接口定義好了之后,就給所有的表達式樹添加一個Apply(虛)函數來訪問相應的Visit函數:
 1         void CharSetExpression::Apply(IRegexExpressionAlgorithm& algorithm)
 2         {
 3             algorithm.Visit(this);
 4         }
 5 
 6         void LoopExpression::Apply(IRegexExpressionAlgorithm& algorithm)
 7         {
 8             algorithm.Visit(this);
 9         }
10 
11         void SequenceExpression::Apply(IRegexExpressionAlgorithm& algorithm)
12         {
13             algorithm.Visit(this);
14         }
15 
16         void AlternateExpression::Apply(IRegexExpressionAlgorithm& algorithm)
17         {
18             algorithm.Visit(this);
19         }
20 
21         void BeginExpression::Apply(IRegexExpressionAlgorithm& algorithm)
22         {
23             algorithm.Visit(this);
24         }
25 
26         void EndExpression::Apply(IRegexExpressionAlgorithm& algorithm)
27         {
28             algorithm.Visit(this);
29         }
30 
31         void CaptureExpression::Apply(IRegexExpressionAlgorithm& algorithm)
32         {
33             algorithm.Visit(this);
34         }
35 
36         void MatchExpression::Apply(IRegexExpressionAlgorithm& algorithm)
37         {
38             algorithm.Visit(this);
39         }
40 
41         void PositiveExpression::Apply(IRegexExpressionAlgorithm& algorithm)
42         {
43             algorithm.Visit(this);
44         }
45 
46         void NegativeExpression::Apply(IRegexExpressionAlgorithm& algorithm)
47         {
48             algorithm.Visit(this);
49         }
50 
51         void UsingExpression::Apply(IRegexExpressionAlgorithm& algorithm)
52         {
53             algorithm.Visit(this);
54         }

    于是我們可以去實現一個IRegexExpressionAlgorithm了。但是事情還沒完。如果每一個算法都要去實現一個IRegexExpressionAlgorithm的話,我們會發現因為算法所需要的參數不同,為了使用Visit這種無參數的函數,我們都需要為每一個具體的Apply實現一次參數的緩存工作。但是因為參數是未知的,而且模板函數又不能是虛函數(所以不能把Expression::Apply寫成模板函數),所以IRegexExpressionAlgorithm的Visit系列函數是沒有參數的。因此一個輔助類就應運而生了。

    這個輔助類用來給你很直接地寫具有一個參數的算法。你只要創建它,然后寫完所有的(算法類里面的)Apply函數就行了。那么你怎么在一個表達式上面調用你自己的算法呢?假設參數是p,我們希望只需要簡單地執行Invoke(expression, p)就可以調用到自己了。所以這里實現了一個RegexExpressionAlgorithm<ReturnType, ParameterType>。當然對于ReturnType==void的時候,我們還需要再特化一個,不過這個就不說了:
 1         template<typename ReturnType, typename ParameterType=void*>
 2         class RegexExpressionAlgorithm : public Object, public IRegexExpressionAlgorithm
 3         {
 4         private:
 5             ReturnType                    returnValue;
 6             void*                        parameterValue;
 7         public:
 8 
 9             ReturnType Invoke(Expression* expression, ParameterType parameter)
10             {
11                 parameterValue=(void*)&parameter;
12                 expression->Apply(*this);
13                 return returnValue;
14             }
15 
16             ReturnType Invoke(Expression::Ref expression, ParameterType parameter)
17             {
18                 parameterValue=(void*)&parameter;
19                 expression->Apply(*this);
20                 return returnValue;
21             }
22 
23             virtual ReturnType            Apply(CharSetExpression* expression, ParameterType parameter)=0;
24             virtual ReturnType            Apply(LoopExpression* expression, ParameterType parameter)=0;
25             virtual ReturnType            Apply(SequenceExpression* expression, ParameterType parameter)=0;
26             virtual ReturnType            Apply(AlternateExpression* expression, ParameterType parameter)=0;
27             virtual ReturnType            Apply(BeginExpression* expression, ParameterType parameter)=0;
28             virtual ReturnType            Apply(EndExpression* expression, ParameterType parameter)=0;
29             virtual ReturnType            Apply(CaptureExpression* expression, ParameterType parameter)=0;
30             virtual ReturnType            Apply(MatchExpression* expression, ParameterType parameter)=0;
31             virtual ReturnType            Apply(PositiveExpression* expression, ParameterType parameter)=0;
32             virtual ReturnType            Apply(NegativeExpression* expression, ParameterType parameter)=0;
33             virtual ReturnType            Apply(UsingExpression* expression, ParameterType parameter)=0;
34         public:
35             void Visit(CharSetExpression* expression)
36             {
37                 returnValue=Apply(expression, *((ParameterType*)parameterValue));
38             }
39 
40             void Visit(LoopExpression* expression)
41             {
42                 returnValue=Apply(expression, *((ParameterType*)parameterValue));
43             }
44 
45             void Visit(SequenceExpression* expression)
46             {
47                 returnValue=Apply(expression, *((ParameterType*)parameterValue));
48             }
49 
50             void Visit(AlternateExpression* expression)
51             {
52                 returnValue=Apply(expression, *((ParameterType*)parameterValue));
53             }
54 
55             void Visit(BeginExpression* expression)
56             {
57                 returnValue=Apply(expression, *((ParameterType*)parameterValue));
58             }
59 
60             void Visit(EndExpression* expression)
61             {
62                 returnValue=Apply(expression, *((ParameterType*)parameterValue));
63             }
64 
65             void Visit(CaptureExpression* expression)
66             {
67                 returnValue=Apply(expression, *((ParameterType*)parameterValue));
68             }
69 
70             void Visit(MatchExpression* expression)
71             {
72                 returnValue=Apply(expression, *((ParameterType*)parameterValue));
73             }
74 
75             void Visit(PositiveExpression* expression)
76             {
77                 returnValue=Apply(expression, *((ParameterType*)parameterValue));
78             }
79 
80             void Visit(NegativeExpression* expression)
81             {
82                 returnValue=Apply(expression, *((ParameterType*)parameterValue));
83             }
84 
85             void Visit(UsingExpression* expression)
86             {
87                 returnValue=Apply(expression, *((ParameterType*)parameterValue));
88             }
89         };

    好了,讓我們使用它來實現之前提到過的IsEqual功能吧。首先實現一個IsEqualAlgorithm:
  1         class IsEqualAlgorithm : public RegexExpressionAlgorithm<bool, Expression*>
  2         {
  3         public:
  4             bool Apply(CharSetExpression* expression, Expression* target)
  5             {
  6                 CharSetExpression* expected=dynamic_cast<CharSetExpression*>(target);
  7                 if(expected)
  8                 {
  9                     if(expression->reverse!=expected->reverse)return false;
 10                     if(expression->ranges.Count()!=expected->ranges.Count())return false;
 11                     for(int i=0;i<expression->ranges.Count();i++)
 12                     {
 13                         if(expression->ranges[i]!=expected->ranges[i])return false;
 14                     }
 15                     return true;
 16                 }
 17                 return false;
 18             }
 19 
 20             bool Apply(LoopExpression* expression, Expression* target)
 21             {
 22                 LoopExpression* expected=dynamic_cast<LoopExpression*>(target);
 23                 if(expected)
 24                 {
 25                     if(expression->min!=expected->min)return false;
 26                     if(expression->max!=expected->max)return false;
 27                     if(!Invoke(expression->expression, expected->expression.Obj()))return false;
 28                     return true;
 29                 }
 30                 return false;
 31             }
 32 
 33             bool Apply(SequenceExpression* expression, Expression* target)
 34             {
 35                 SequenceExpression* expected=dynamic_cast<SequenceExpression*>(target);
 36                 if(expected)
 37                 {
 38                     if(!Invoke(expression->left, expected->left.Obj()))return false;
 39                     if(!Invoke(expression->right, expected->right.Obj()))return false;
 40                     return true;
 41                 }
 42                 return false;
 43             }
 44 
 45             bool Apply(AlternateExpression* expression, Expression* target)
 46             {
 47                 AlternateExpression* expected=dynamic_cast<AlternateExpression*>(target);
 48                 if(expected)
 49                 {
 50                     if(!Invoke(expression->left, expected->left.Obj()))return false;
 51                     if(!Invoke(expression->right, expected->right.Obj()))return false;
 52                     return true;
 53                 }
 54                 return false;
 55             }
 56 
 57             bool Apply(BeginExpression* expression, Expression* target)
 58             {
 59                 BeginExpression* expected=dynamic_cast<BeginExpression*>(target);
 60                 if(expected)
 61                 {
 62                     return true;
 63                 }
 64                 return false;
 65             }
 66 
 67             bool Apply(EndExpression* expression, Expression* target)
 68             {
 69                 EndExpression* expected=dynamic_cast<EndExpression*>(target);
 70                 if(expected)
 71                 {
 72                     return true;
 73                 }
 74                 return false;
 75             }
 76 
 77             bool Apply(CaptureExpression* expression, Expression* target)
 78             {
 79                 CaptureExpression* expected=dynamic_cast<CaptureExpression*>(target);
 80                 if(expected)
 81                 {
 82                     if(expression->name!=expected->name)return false;
 83                     if(!Invoke(expression->expression, expected->expression.Obj()))return false;
 84                     return true;
 85                 }
 86                 return false;
 87             }
 88 
 89             bool Apply(MatchExpression* expression, Expression* target)
 90             {
 91                 MatchExpression* expected=dynamic_cast<MatchExpression*>(target);
 92                 if(expected)
 93                 {
 94                     if(expression->name!=expected->name)return false;
 95                     if(expression->index!=expected->index)return false;
 96                     return true;
 97                 }
 98                 return false;
 99             }
100 
101             bool Apply(PositiveExpression* expression, Expression* target)
102             {
103                 PositiveExpression* expected=dynamic_cast<PositiveExpression*>(target);
104                 if(expected)
105                 {
106                     if(!Invoke(expression->expression, expected->expression.Obj()))return false;
107                     return true;
108                 }
109                 return false;
110             }
111 
112             bool Apply(NegativeExpression* expression, Expression* target)
113             {
114                 NegativeExpression* expected=dynamic_cast<NegativeExpression*>(target);
115                 if(expected)
116                 {
117                     if(!Invoke(expression->expression, expected->expression.Obj()))return false;
118                     return true;
119                 }
120                 return false;
121             }
122 
123             bool Apply(UsingExpression* expression, Expression* target)
124             {
125                 UsingExpression* expected=dynamic_cast<UsingExpression*>(target);
126                 if(expected)
127                 {
128                     if(expression->name!=expected->name)return false;
129                     return true;
130                 }
131                 return false;
132             }
133         };

    譬如看AlternateExpression的IsEqual方法。AlternateExpression跟Expression是否相等只需要通過比較兩個子表達式是否相等即可,于是代碼就變成了:
 1             bool Apply(AlternateExpression* expression, Expression* target)
 2             {
 3                 AlternateExpression* expected=dynamic_cast<AlternateExpression*>(target);
 4                 if(expected)
 5                 {
 6                     if(!Invoke(expression->left, expected->left.Obj()))return false;
 7                     if(!Invoke(expression->right, expected->right.Obj()))return false;
 8                     return true;
 9                 }
10                 return false;
11             }

    如果將AlternateExpression* expression變為AlternateExpression* const this,將Invoke(a, b)換成a->IsEqual(b),就跟直接寫IsEqual虛函數沒兩樣了。于是自己調用自己還是很方便的。但是我們最終還是想做成a->IsEqual(b)的,于是還要在Expression基類中寫一點:
1         bool Expression::IsEqual(vl::regex_internal::Expression *expression)
2         {
3             IsEqualAlgorithm algorithm;
4             return algorithm.Invoke(this, expression);
5         }

    于是IsEqual的實現就結束了。雖然Visitor直接使用會很麻煩,但是我們可以通過稍微的改造一下讓其更好用。當然這里跟Visitor其實還不是完全一致,細節問題就不詳細討論了。至少文章的目標“不通過修改Expression的接口而添加新功能”的目標已經實現了。就結果來講,添加一個新的功能還是很方便的。
posted on 2009-10-17 17:34 陳梓瀚(vczh) 閱讀(2025) 評論(0)  編輯 收藏 引用 所屬分類: VL++3.0開發紀事
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            亚洲永久字幕| 亚洲欧美国产日韩天堂区| 欧美一区日韩一区| 国产精品99久久不卡二区| 欧美四级在线| 亚洲视频一区在线观看| 亚洲精品久久嫩草网站秘色| 欧美mv日韩mv亚洲| 99精品视频免费观看| 一区二区三区欧美激情| 亚洲一区二区久久| 欧美一区二区三区喷汁尤物| 国产综合色在线| 免费观看30秒视频久久| 欧美 日韩 国产在线| 99re热这里只有精品视频| 亚洲特色特黄| 黄色精品一区| 亚洲精品之草原avav久久| 国产精品福利网| 久久精品视频在线观看| 欧美成年视频| 亚洲欧美中文在线视频| 久久久久久久久久久一区| 亚洲精品视频免费在线观看| 亚洲午夜久久久久久久久电影院| 国产日韩视频| 亚洲欧洲日韩在线| 国产一区二区主播在线| 在线精品亚洲| 国产精品视频xxx| 久久九九热免费视频| 久久成人综合网| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 国产精品欧美日韩久久| 老司机久久99久久精品播放免费| 欧美日韩国产在线一区| 久久久久久夜| 欧美日韩国产成人| 蜜桃精品久久久久久久免费影院| 欧美理论电影网| 亚洲国产一区视频| 一本大道久久精品懂色aⅴ| 国产欧美视频一区二区三区| 亚洲国产精品成人综合色在线婷婷| 欧美视频一区二区三区在线观看| 麻豆久久久9性大片| 国产麻豆91精品| 亚洲国产日韩一级| 韩日欧美一区| 欧美亚洲免费在线| 亚洲天堂视频在线观看| 欧美成va人片在线观看| 美女精品网站| 国内外成人免费激情在线视频| 在线一区二区三区做爰视频网站| 亚洲精品乱码久久久久久按摩观| 性一交一乱一区二区洋洋av| 亚洲欧美日韩另类| 欧美色播在线播放| 日韩午夜高潮| 亚洲一级电影| 欧美日产在线观看| 亚洲日本中文字幕区| 亚洲精品乱码| 欧美精品一区二区三| 亚洲国产天堂网精品网站| 亚洲高清精品中出| 美腿丝袜亚洲色图| 欧美成人免费一级人片100| 精品99一区二区三区| 久久九九热免费视频| 男女精品网站| 亚洲日韩视频| 欧美精品乱码久久久久久按摩| 91久久嫩草影院一区二区| 日韩视频二区| 国产精品久久久久aaaa樱花| 亚洲一区二区三区免费观看| 欧美一区二区视频97| 国产亚洲一区二区精品| 欧美中文字幕久久| 蜜臀99久久精品久久久久久软件 | 亚洲视频电影图片偷拍一区| 午夜精品视频网站| 国产视频在线一区二区| 久久精品91久久久久久再现| 美女脱光内衣内裤视频久久影院 | 亚洲精品美女在线| 欧美片第一页| 午夜精品久久久久久久99樱桃 | 午夜日韩电影| 黄色欧美成人| 欧美另类99xxxxx| 亚洲欧美变态国产另类| 久久这里有精品视频| 亚洲国产另类久久精品| 国产精品激情电影| 久久久久国产精品www | 亚洲一级黄色片| 亚洲图片欧美一区| 在线观看视频欧美| 校园春色综合网| 亚洲第一二三四五区| 亚洲欧美日韩一区二区在线| 伊人成人在线| 国产精品jizz在线观看美国| 久久精品网址| 一本色道久久| 欧美国产乱视频| 性欧美暴力猛交69hd| 亚洲国产精品久久久久婷婷884| 国产精品国产三级国产a| 久久精品国产96久久久香蕉| 在线综合+亚洲+欧美中文字幕| 美腿丝袜亚洲色图| 午夜欧美电影在线观看| 日韩亚洲精品电影| 好吊一区二区三区| 国产精品美女久久久免费| 欧美激情视频免费观看| 欧美自拍偷拍| 亚洲欧美日韩一区二区在线| 日韩亚洲不卡在线| 欧美激情导航| 久久综合免费视频影院| 亚洲免费在线视频| 日韩亚洲在线| 亚洲国产一区二区三区在线播| 国产午夜精品全部视频播放| 欧美四级电影网站| 欧美日韩国产在线播放| 欧美国产日本在线| 蜜桃av一区| 久久久久综合网| 久久精品国产精品亚洲综合| 亚洲一区综合| 亚洲曰本av电影| 在线性视频日韩欧美| 日韩一级片网址| 99视频超级精品| 亚洲美女在线观看| 亚洲裸体俱乐部裸体舞表演av| 亚洲国产mv| 亚洲国产91色在线| 亚洲激情一区二区三区| 亚洲福利视频二区| 亚洲高清不卡在线观看| 欧美激情第二页| 亚洲欧洲在线看| 亚洲精品视频在线播放| 一区二区三区高清在线观看| 一本一本久久a久久精品牛牛影视| 亚洲韩国青草视频| 亚洲乱码国产乱码精品精98午夜| 亚洲人成人77777线观看| 亚洲毛片av在线| 亚洲影院污污.| 久久精品91| 欧美二区视频| 国产精品hd| 国产一区二区三区高清| 亚洲国产1区| 99精品国产在热久久| 亚洲欧美成aⅴ人在线观看| 久久国产视频网| 欧美成人伊人久久综合网| 亚洲高清视频在线观看| 亚洲视频1区| 久久精品导航| 欧美日韩日本视频| 国产一区二区三区免费观看| 在线国产精品播放| 日韩一二三在线视频播| 亚欧成人在线| 欧美国产精品专区| 亚洲免费视频成人| 久久综合免费视频影院| 欧美视频免费在线| 国语自产精品视频在线看| 一本色道久久综合亚洲精品不| 伊人天天综合| 欧美午夜欧美| 欧美一区午夜精品| 欧美黄色一区| 欧美日韩一区二区国产| 国产美女一区二区| 最新亚洲电影| 久久激情综合| 日韩小视频在线观看专区| 久久久综合激的五月天| 国产精品久久久久久久久免费| 亚洲第一福利在线观看| 亚洲欧美色婷婷| 亚洲国产精品久久久久秋霞不卡| 亚洲在线视频| 欧美人成在线| 亚洲国产第一| 久久久久久久999| 亚洲综合电影|