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

                首先對于上一篇文章定義的樹來看,我們需要設(shè)計一個通用的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         };

                接口定義好了之后,就給所有的表達(dá)式樹添加一個Apply(虛)函數(shù)來訪問相應(yīng)的Visit函數(shù):
             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         }

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

                這個輔助類用來給你很直接地寫具有一個參數(shù)的算法。你只要創(chuàng)建它,然后寫完所有的(算法類里面的)Apply函數(shù)就行了。那么你怎么在一個表達(dá)式上面調(diào)用你自己的算法呢?假設(shè)參數(shù)是p,我們希望只需要簡單地執(zhí)行Invoke(expression, p)就可以調(diào)用到自己了。所以這里實現(xiàn)了一個RegexExpressionAlgorithm<ReturnType, ParameterType>。當(dāng)然對于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         };

                好了,讓我們使用它來實現(xiàn)之前提到過的IsEqual功能吧。首先實現(xiàn)一個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是否相等只需要通過比較兩個子表達(dá)式是否相等即可,于是代碼就變成了:
             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變?yōu)锳lternateExpression* const this,將Invoke(a, b)換成a->IsEqual(b),就跟直接寫IsEqual虛函數(shù)沒兩樣了。于是自己調(diào)用自己還是很方便的。但是我們最終還是想做成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的實現(xiàn)就結(jié)束了。雖然Visitor直接使用會很麻煩,但是我們可以通過稍微的改造一下讓其更好用。當(dāng)然這里跟Visitor其實還不是完全一致,細(xì)節(jié)問題就不詳細(xì)討論了。至少文章的目標(biāo)“不通過修改Expression的接口而添加新功能”的目標(biāo)已經(jīng)實現(xiàn)了。就結(jié)果來講,添加一個新的功能還是很方便的。
            posted on 2009-10-17 17:34 陳梓瀚(vczh) 閱讀(2019) 評論(0)  編輯 收藏 引用 所屬分類: VL++3.0開發(fā)紀(jì)事
            国产女人aaa级久久久级| 狠狠88综合久久久久综合网| 久久免费高清视频| 9191精品国产免费久久| 国产福利电影一区二区三区久久久久成人精品综合 | 久久se精品一区二区| 成人精品一区二区久久 | 亚洲中文久久精品无码ww16| 久久香蕉超碰97国产精品| 久久久久国产精品| 国内精品伊人久久久影院| 国产情侣久久久久aⅴ免费| 亚洲精品WWW久久久久久| 久久久久亚洲av无码专区喷水 | 久久AⅤ人妻少妇嫩草影院| 久久久久久久97| 91精品国产91久久| 伊人色综合久久天天人手人婷| 大蕉久久伊人中文字幕| 欧美一区二区三区久久综| 久久精品不卡| 国产精品免费福利久久| 亚洲人成无码久久电影网站| 91精品国产综合久久四虎久久无码一级| 久久夜色精品国产噜噜亚洲a| 亚洲精品高清久久| 成人资源影音先锋久久资源网| 2020久久精品亚洲热综合一本| 久久久久久青草大香综合精品| 久久91精品国产91久久麻豆| 精品久久久久香蕉网| 久久综合久久自在自线精品自| 超级97碰碰碰碰久久久久最新| 久久免费视频6| 久久久精品视频免费观看| 久久人人超碰精品CAOPOREN| 久久99国产一区二区三区| 久久久WWW成人| 一级a性色生活片久久无少妇一级婬片免费放 | 久久精品国产亚洲AV高清热 | 久久99精品久久久久久久久久|