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

隨筆-341  評(píng)論-2670  文章-0  trackbacks-0
    現(xiàn)在的OOP都提倡將操作與數(shù)據(jù)結(jié)構(gòu)結(jié)合在一起。為什么這里要提出將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi)呢?第一個(gè)原因是一個(gè)算法可能是用來(lái)處理一組數(shù)據(jù)結(jié)構(gòu)的。第二個(gè)原因是算法并不屬于操作。我們可以借鑒訪問(wèn)者模式來(lái)實(shí)現(xiàn)這個(gè)分離,但是這里有一個(gè)特別之處:我們要將訪問(wèn)者模式帶給我們的那個(gè)接口實(shí)現(xiàn)得讓我們用起來(lái)很漂亮。至于實(shí)現(xiàn)本身票不漂亮我是不管的,因?yàn)檫@種代碼應(yīng)該讓電腦來(lái)替我們寫(xiě)。

    訪問(wèn)者模式相信大家都很熟悉了,也被人講爛了,我就不重新教一次了。現(xiàn)在我們面對(duì)的問(wèn)題是這樣的:我們有一組數(shù)據(jù)結(jié)構(gòu),這組數(shù)據(jù)結(jié)構(gòu)是互相使用而且通過(guò)繼承關(guān)系結(jié)合在了一起。典型的譬如一個(gè)科學(xué)計(jì)算器的表達(dá)式數(shù)據(jù)結(jié)構(gòu),就有函數(shù)調(diào)用、數(shù)字、函數(shù)、運(yùn)算符等不同的數(shù)據(jù)結(jié)構(gòu),但肯定繼承與一個(gè)類似于『抽象表達(dá)式』之類的東西。我這次要實(shí)現(xiàn)一個(gè)生成使用Syngram的代碼的代碼,于是需要把周邊的數(shù)據(jù)結(jié)構(gòu)也一并搞定。我想到了一個(gè)模式,然后讓代碼生成器本身來(lái)使用,借以觀察是否能行。

     一份文法的結(jié)構(gòu)從數(shù)據(jù)結(jié)構(gòu)上來(lái)看并不復(fù)雜。文法由詞法記號(hào)定義以及文法推導(dǎo)式定義組成,其中文法推導(dǎo)式子的表達(dá)式又有終結(jié)符、連接、分支以及可選等等。譬如下面的一份文法文件(給正在開(kāi)發(fā)的代碼生成器用的)的內(nèi)容是一種科學(xué)計(jì)算器的表達(dá)式文法。這個(gè)文法能夠分析數(shù)字、單目操作符、雙目操作符、括號(hào)以及函數(shù)調(diào)用:
 1 lexical
 2 {
 3     num='\d+(.\d+)?'
 4     ident='[a-zA-Z_]\w*'
 5     plus='\+'
 6     minus='\-'
 7     mul='\*'
 8     div='\\'
 9     leftbrace='\('
10     rightbrace='\)'
11     comma=','
12 }
13 rule
14 {
15     factor=num                    ;
16     factor=[minus] factor                ;
17     factor=leftbrace exp rightbrace            ;
18     factor=ident[leftbrace param_list rightbrace]    ;
19     term=factor                    ;
20     term=term (mul|div) factor            ;
21     exp=term                    ;
22     exp=exp (plus|minus) term            ;
23     param_list=exp [comma param_list]        ;
24     program=exp                    ;
25 }

    我們用什么樣的數(shù)據(jù)結(jié)構(gòu)來(lái)記錄這些內(nèi)容呢?答案并不復(fù)雜,做一個(gè)基類表示抽象文法樹(shù),其他的都是簡(jiǎn)單的結(jié)構(gòu):
 1 /*********************************************************************************************************
 2 語(yǔ)法樹(shù)
 3 *********************************************************************************************************/
 4 
 5     class GrammarAlgorithm;
 6 
 7     class GrammarBase : public VL_Base
 8     {
 9     public:
10         typedef VL_AutoPtr<GrammarBase>                    Ptr;
11         typedef VL_List<Ptr , false , GrammarBase*>        List;
12 
13         virtual void                Apply(GrammarAlgorithm* Algorithm)=0;
14     };
15 
16     class GrammarBranch : public GrammarBase
17     {
18     public:
19         GrammarBase::List            Expressions;
20 
21         virtual void                Apply(GrammarAlgorithm* Algorithm);
22     };
23 
24     class GrammarSequence : public GrammarBase
25     {
26     public:
27         GrammarBase::List            Expressions;
28 
29         virtual void                Apply(GrammarAlgorithm* Algorithm);
30     };
31 
32     class GrammarOptional : public GrammarBase
33     {
34     public:
35         GrammarBase::Ptr            Expression;
36 
37         virtual void                Apply(GrammarAlgorithm* Algorithm);
38     };
39 
40     class GrammarUnit : public GrammarBase
41     {
42     public:
43         VUnicodeString                Name;
44 
45         virtual void                Apply(GrammarAlgorithm* Algorithm);
46     };
47 
48     class GrammarRule : public VL_Base
49     {
50     public:
51         typedef VL_AutoPtr<GrammarRule>                    Ptr;
52         typedef VL_List<Ptr , false , GrammarRule*>        List;
53 
54         VUnicodeString                Name;
55         GrammarBase::Ptr            Expression;
56 
57         virtual void                Apply(GrammarAlgorithm* Algorithm);
58     };
59 
60     class LexicalDecl : public VL_Base
61     {
62     public:
63         typedef VL_AutoPtr<LexicalDecl>                    Ptr;
64         typedef VL_List<Ptr , false , LexicalDecl*>        List;
65 
66         VUnicodeString                Name;
67         VUnicodeString                RegularExpression;
68 
69         virtual void                Apply(GrammarAlgorithm* Algorithm);
70     };
71 
72     class GrammarDescription : public VL_Base
73     {
74     public:
75         typedef VL_AutoPtr<GrammarDescription>            Ptr;
76 
77         LexicalDecl::List            Tokens;
78         GrammarRule::List            Rules;
79 
80         virtual void                Apply(GrammarAlgorithm* Algorithm);
81     };

    大家注意到這里有一個(gè)GrammarAlgorithm,這個(gè)是訪問(wèn)者模式所帶來(lái)的一個(gè)接口類。上面一共有7個(gè)類是有內(nèi)容的,其中一部分類的基類GrammarBase是沒(méi)有內(nèi)容的。因此GrammarAlgorithm類就有7個(gè)函數(shù),分別用于接收不同對(duì)象的Apply函數(shù)的調(diào)用:
 1 /*********************************************************************************************************
 2 算法
 3 *********************************************************************************************************/
 4 
 5     class GrammarAlgorithm : public VL_Base
 6     {
 7     public:
 8         virtual void                Visit(GrammarBranch* Obj)=0;
 9         virtual void                Visit(GrammarSequence* Obj)=0;
10         virtual void                Visit(GrammarOptional* Obj)=0;
11         virtual void                Visit(GrammarUnit* Obj)=0;
12         virtual void                Visit(GrammarRule* Obj)=0;
13         virtual void                Visit(LexicalDecl* Obj)=0;
14         virtual void                Visit(GrammarDescription* Obj)=0;
15     };

    那么這些Visit函數(shù)是如何被調(diào)用的呢?這里是重載,重載當(dāng)然有其好處了,因?yàn)樽宇悅兊膖his都是有確切的類型的:
 1 /*********************************************************************************************************
 2 語(yǔ)法樹(shù)
 3 *********************************************************************************************************/
 4 
 5     void GrammarBranch::Apply(GrammarAlgorithm* Algorithm)
 6     {
 7         Algorithm->Visit(this);
 8     }
 9 
10     void GrammarSequence::Apply(GrammarAlgorithm* Algorithm)
11     {
12         Algorithm->Visit(this);
13     }
14 
15     void GrammarOptional::Apply(GrammarAlgorithm* Algorithm)
16     {
17         Algorithm->Visit(this);
18     }
19 
20     void GrammarUnit::Apply(GrammarAlgorithm* Algorithm)
21     {
22         Algorithm->Visit(this);
23     }
24 
25     void GrammarRule::Apply(GrammarAlgorithm* Algorithm)
26     {
27         Algorithm->Visit(this);
28     }
29 
30     void LexicalDecl::Apply(GrammarAlgorithm* Algorithm)
31     {
32         Algorithm->Visit(this);
33     }
34 
35     void GrammarDescription::Apply(GrammarAlgorithm* Algorithm)
36     {
37         Algorithm->Visit(this);
38     }

    一切都很美好是吧?訪問(wèn)者模式到這里就結(jié)束了,但是事情還沒(méi)完。這里的大部分對(duì)象都是有子對(duì)象的(區(qū)別于子類,說(shuō)的是都在Algorithm中出現(xiàn)的類作為了成員變量)。如果我們的算法需要有其他參數(shù)和返回結(jié)果,難道繼承一個(gè)Algorithm之后加一堆參數(shù)和返回值用的成員變量,然后每次調(diào)用前填好,SomeObj->Visit(Algorithm);,然后獲取返回值變量?這當(dāng)然是在這個(gè)Algorithm中唯一的辦法,但是我們這么寫(xiě)的話,代碼是很亂七八糟的,也不好維護(hù)。因此我們可以在不破壞已經(jīng)存在的代碼的基礎(chǔ)上,添加新的Algorithm工具。

    想象一下,如果我們要從上面這棵樹(shù)構(gòu)造出一個(gè)字符串來(lái),我們是需要遞歸很多次的。為了遞歸我們不得不將算法對(duì)象自己放到別的對(duì)象里面去Apply。如果我們可以result=obj->apply(this,parameters);就好了。不過(guò)話說(shuō)回來(lái),我們是不能動(dòng)數(shù)據(jù)結(jié)構(gòu)的代碼的。因?yàn)槿绻覀冞@樣做的話就白白破壞了訪問(wèn)者模式所帶來(lái)的好處了。但是每一個(gè)算法的參數(shù)和返回值都是不同的。怎么辦呢?用C++的話,答案很清楚,就是模板類。

    參數(shù)的個(gè)數(shù)我們不用考慮,多了的話我們可以用一個(gè)struct去解決。好了,現(xiàn)在我們得到了一個(gè)新的算法類的大概外觀:
    template<typename _ResultType , typename _ParamType>
    class NewAlgorithm : public GrammarAlgorithm{...};

    這個(gè)NewAlgorithm肯定也要有自己的一組帶有返回結(jié)果和參數(shù)的Visit函數(shù)族了。于是我們可以在原來(lái)的Visit函數(shù)族里面做返回值和參數(shù)的間接處理,當(dāng)然還是用成員變量最簡(jiǎn)單了。不過(guò)為了保護(hù),我們將繼承修改為private,然后用一個(gè)隱式轉(zhuǎn)換來(lái)得到GrammarAlgorithm的指針類型:
 1     template<typename _ReturnType , typename _ParamType=void*>
 2     class GrammarAlgorithmEx : private GrammarAlgorithm
 3     {
 4     private:
 5         _ReturnType                    FReturnData;
 6         _ParamType                    FParamData;
 7 
 8         void Visit(GrammarBranch* Obj)
 9         {
10             FReturnData=Visit(Obj,FParamData);
11         }
12 
13         void Visit(GrammarSequence* Obj)
14         {
15             FReturnData=Visit(Obj,FParamData);
16         }
17 
18         void Visit(GrammarOptional* Obj)
19         {
20             FReturnData=Visit(Obj,FParamData);
21         }
22 
23         void Visit(GrammarUnit* Obj)
24         {
25             FReturnData=Visit(Obj,FParamData);
26         }
27 
28         void Visit(GrammarRule* Obj)
29         {
30             FReturnData=Visit(Obj,FParamData);
31         }
32 
33         void Visit(LexicalDecl* Obj)
34         {
35             FReturnData=Visit(Obj,FParamData);
36         }
37 
38         void Visit(GrammarDescription* Obj)
39         {
40             FReturnData=Visit(Obj,FParamData);
41         }
42 
43         operator GrammarAlgorithm*()
44         {
45             return this;
46         }
47     public:
48         template<typename _ObjectType>
49         _ReturnType Apply(_ObjectType* Obj , _ParamType ParamData)
50         {
51             FParamData=ParamData;
52             Obj->Apply(*this);
53             return FReturnData;
54         }
55 
56         template<typename _ObjectType>
57         _ReturnType Apply(VL_AutoPtr<_ObjectType> Obj , _ParamType ParamData)
58         {
59             FParamData=ParamData;
60             Obj->Apply(*this);
61             return FReturnData;
62         }
63     public:
64         virtual _ReturnType            Visit(GrammarBranch* Obj , _ParamType ParamData)=0;
65         virtual _ReturnType            Visit(GrammarSequence* Obj , _ParamType ParamData)=0;
66         virtual _ReturnType            Visit(GrammarOptional* Obj , _ParamType ParamData)=0;
67         virtual _ReturnType            Visit(GrammarUnit* Obj , _ParamType ParamData)=0;
68         virtual _ReturnType            Visit(GrammarRule* Obj , _ParamType ParamData)=0;
69         virtual _ReturnType            Visit(LexicalDecl* Obj , _ParamType ParamData)=0;
70         virtual _ReturnType            Visit(GrammarDescription* Obj , _ParamType ParamData)=0;
71     };

    注意到我們也有自己的Apply函數(shù)吧。這個(gè)函數(shù)就是新的Algorithm的關(guān)鍵。我們可以隨便來(lái)一個(gè)什么對(duì)象就result=Apply(obj,parameters);,然后Apply填好參數(shù),調(diào)用obj->Apply(*this);。這里*this調(diào)用operator GrammarAlgorithm*()得到需要的類型,然后由obj自己發(fā)配到原來(lái)的Visit上。原來(lái)的Visit填好返回值,Apply返回,調(diào)用成功!

    當(dāng)然,現(xiàn)在解決了Algorithm內(nèi)部的調(diào)用問(wèn)題。那么外部怎么辦呢?其實(shí)也要用Apply,不過(guò)我們需要?jiǎng)?chuàng)建對(duì)象。我們可以使用代碼result=YourAlgorithm().Apply(obj,parameters);來(lái)做到這件事情。這一來(lái)一回雖然不是一個(gè)好看的辦法,但是只要好用就好了。因?yàn)锳lgorithm將來(lái)是生成的,不需要人寫(xiě)。

    虛函數(shù)所帶來(lái)的好處就被這個(gè)新的Algorithm解決了。現(xiàn)在拿到一個(gè)非常復(fù)雜的充滿了繼承的數(shù)據(jù)結(jié)構(gòu)也不用怕了。我們可以不破壞原有的代碼,建立起自己的“虛函數(shù)”了。說(shuō)到這里,我來(lái)用一用這個(gè)Algorithm。我將文法文件讀入GrammarDescription之后,用一個(gè)算法對(duì)象來(lái)將結(jié)果轉(zhuǎn)換為字符串:
 1     class GrammarToString : public GrammarAlgorithmEx<VUnicodeString , VUnicodeString>
 2     {
 3     public:
 4         VUnicodeString            Visit(GrammarBranch* Obj , VUnicodeString Prefix);
 5         VUnicodeString            Visit(GrammarSequence* Obj , VUnicodeString Prefix);
 6         VUnicodeString            Visit(GrammarOptional* Obj , VUnicodeString Prefix);
 7         VUnicodeString            Visit(GrammarUnit* Obj , VUnicodeString Prefix);
 8         VUnicodeString            Visit(GrammarRule* Obj , VUnicodeString Prefix);
 9         VUnicodeString            Visit(LexicalDecl* Obj , VUnicodeString Prefix);
10         VUnicodeString            Visit(GrammarDescription* Obj , VUnicodeString Prefix);
11     };
12 
13 /*********************************************************************************************************
14 GrammarToString
15 *********************************************************************************************************/
16 
17     VUnicodeString GrammarToString::Visit(GrammarBranch* Obj , VUnicodeString Prefix)
18     {
19         VUnicodeString Result;
20         Result+=Prefix+L"branch {\r\n";
21         for(VInt i=0;i<Obj->Expressions.GetCount();i++)
22         {
23             Result+=Apply(Obj->Expressions[i],Prefix+L"  ");
24         }
25         Result+=Prefix+L"}\r\n";
26         return Result;
27     }
28 
29     VUnicodeString GrammarToString::Visit(GrammarSequence* Obj , VUnicodeString Prefix)
30     {
31         VUnicodeString Result;
32         Result+=Prefix+L"sequence {\r\n";
33         for(VInt i=0;i<Obj->Expressions.GetCount();i++)
34         {
35             Result+=Apply(Obj->Expressions[i],Prefix+L"  ");
36         }
37         Result+=Prefix+L"}\r\n";
38         return Result;
39     }
40 
41     VUnicodeString GrammarToString::Visit(GrammarOptional* Obj , VUnicodeString Prefix)
42     {
43         VUnicodeString Result;
44         Result+=Prefix+L"optional {\r\n";
45         Result+=Apply(Obj->Expression,Prefix+L"  ");
46         Result+=Prefix+L"}\r\n";
47         return Result;
48     }
49 
50     VUnicodeString GrammarToString::Visit(GrammarUnit* Obj , VUnicodeString Prefix)
51     {
52         return Prefix+Obj->Name+L"\r\n";
53     }
54 
55     VUnicodeString GrammarToString::Visit(GrammarRule* Obj , VUnicodeString Prefix)
56     {
57         VUnicodeString Result;
58         Result+=Prefix+L"rule {\r\n";
59         Result+=Prefix+L"  "+Obj->Name+L"\r\n";
60         Result+=Apply(Obj->Expression,Prefix+L"  ");
61         Result+=Prefix+L"}\r\n";
62         return Result;
63     }
64 
65     VUnicodeString GrammarToString::Visit(LexicalDecl* Obj , VUnicodeString Prefix)
66     {
67         VUnicodeString Result;
68         Result+=Prefix+L"lexical inference {\r\n";
69         Result+=Prefix+L"  "+Obj->Name+L"\r\n";
70         Result+=Prefix+L"  "+Obj->RegularExpression+L"\r\n";
71         Result+=Prefix+L"}\r\n";
72         return Result;
73     }
74 
75     VUnicodeString GrammarToString::Visit(GrammarDescription* Obj , VUnicodeString Prefix)
76     {
77         VUnicodeString Result;
78         Result+=Prefix+L"lexical inferences {\r\n";
79         for(VInt i=0;i<Obj->Tokens.GetCount();i++)
80         {
81             Result+=Apply(Obj->Tokens[i],Prefix+L"  ");
82         }
83         Result+=Prefix+L"}\r\n";
84         Result+=Prefix+L"syntax inferences {\r\n";
85         for(VInt i=0;i<Obj->Rules.GetCount();i++)
86         {
87             Result+=Apply(Obj->Rules[i],Prefix+L"  ");
88         }
89         Result+=Prefix+L"}\r\n";
90         return Result;
91     }

    看看結(jié)果吧!
  1 lexical inferences {
  2   lexical inference {
  3     num
  4     '\d+(.\d+)?'
  5   }
  6   lexical inference {
  7     ident
  8     '[a-zA-Z_]\w*'
  9   }
 10   lexical inference {
 11     plus
 12     '\+'
 13   }
 14   lexical inference {
 15     minus
 16     '\-'
 17   }
 18   lexical inference {
 19     mul
 20     '\*'
 21   }
 22   lexical inference {
 23     div
 24     '\\'
 25   }
 26   lexical inference {
 27     leftbrace
 28     '\('
 29   }
 30   lexical inference {
 31     rightbrace
 32     '\)'
 33   }
 34   lexical inference {
 35     comma
 36     ','
 37   }
 38 }
 39 syntax inferences {
 40   rule {
 41     factor
 42     num
 43   }
 44   rule {
 45     factor
 46     sequence {
 47       optional {
 48         minus
 49       }
 50       factor
 51     }
 52   }
 53   rule {
 54     factor
 55     sequence {
 56       leftbrace
 57       exp
 58       rightbrace
 59     }
 60   }
 61   rule {
 62     factor
 63     sequence {
 64       ident
 65       optional {
 66         sequence {
 67           leftbrace
 68           param_list
 69           rightbrace
 70         }
 71       }
 72     }
 73   }
 74   rule {
 75     term
 76     factor
 77   }
 78   rule {
 79     term
 80     sequence {
 81       term
 82       branch {
 83         mul
 84         div
 85       }
 86       factor
 87     }
 88   }
 89   rule {
 90     exp
 91     term
 92   }
 93   rule {
 94     exp
 95     sequence {
 96       exp
 97       branch {
 98         plus
 99         minus
100       }
101       term
102     }
103   }
104   rule {
105     param_list
106     sequence {
107       exp
108       optional {
109         sequence {
110           comma
111           param_list
112         }
113       }
114     }
115   }
116   rule {
117     program
118     exp
119   }
120 }

    至于分析器本身是怎么寫(xiě)的呢?用了Vczh牌Syngram,一切都很美好。我只要把文法文件本身需要遵守的文法寫(xiě)進(jìn)C++,那么我就有了一個(gè)分析器了。能處理左遞歸的哦,跟某些受人崇拜的C++庫(kù)不一樣。
  1         class InnerProvider : public VL_Base
  2         {
  3         public:
  4             CompreSyner                Syner;
  5             GrammarProvider*        Provider;
  6 
  7             InnerProvider(GrammarProvider* aProvider):Syner(true)
  8             {
  9                 Provider=aProvider;
 10                 Syner.AddLexicalErrorHandler(LexicalError_Handler);
 11                 Syner.SetUnexpectedEndOfFileHandler(SyntaxEOF_Handler);
 12                 Syner.SetDefaultHandler(SyntaxDefault_Handler);
 13                 Syner.SetLexicalData(Provider);
 14                 Syner.SetSemanticData(Provider);
 15                 Syner.SetErrorData(Provider);
 16                 Syner.Discard(L"\\s");
 17 
 18                 VSynTerm        _Lexical    = Syner.Token(L"\"lexical\""    ,L"lexical"                );
 19                 VSynTerm        _Rule        = Syner.Token(L"\"rule\""        ,L"rule"                );
 20                 VSynTerm        Id            = Syner.Token(L"<ID>"            ,L"[a-zA-Z_]\\w*"        );
 21                 VSynTerm        Regex        = Syner.Token(L"<REGEX>"        ,L"\'(\'\'|[^\'])*\'"    );
 22                 VSynTerm        Infer        = Syner.Token(L"\"=\""            ,L"="                    );
 23                 VSynTerm        Or            = Syner.Token(L"\"|\""            ,L"\\|"                    );
 24                 VSynTerm        OptLeft        = Syner.Token(L"\"[\""            ,L"\\["                    );
 25                 VSynTerm        OptRight    = Syner.Token(L"\"]\""            ,L"\\]"                    );
 26                 VSynTerm        DeclLeft    = Syner.Token(L"\"{\""            ,L"\\{"                    );
 27                 VSynTerm        DeclRight    = Syner.Token(L"\"}\""            ,L"\\}"                    );
 28                 VSynTerm        ExpLeft        = Syner.Token(L"\"(\""            ,L"\\("                    );
 29                 VSynTerm        ExpRight    = Syner.Token(L"\")\""            ,L"\\)"                    );
 30                 VSynTerm        Semicolon    = Syner.Token(L"\";\""            ,L";"                    );
 31 
 32                 VSynTerm        Name        = Syner.Rule(L"Name");
 33                 VSynTerm        LexInfer    = Syner.Rule(L"Lexical");
 34                 VSynTerm        RuleUnit    = Syner.Rule(L"RuleUnit");
 35                 VSynTerm        RuleSeq        = Syner.Rule(L"RuleSeq");
 36                 VSynTerm        RuleExp        = Syner.Rule(L"RuleExp");
 37                 VSynTerm        RuleInfer    = Syner.Rule(L"Rule");
 38                 VSynTerm        LexList        = Syner.Rule(L"LexList");
 39                 VSynTerm        RuleList    = Syner.Rule(L"RuleList");
 40                 VSynTerm        Program        = Syner.Rule(L"Program");
 41 
 42                 IVL_ErrorHandler*    ErrLostInfer        = Syner.Err(LostInfer_Handler);
 43                 IVL_ErrorHandler*    ErrLostRegex        = Syner.Err(LostRegex_Handler);
 44                 IVL_ErrorHandler*    ErrLostRule            = Syner.Err(LostRule_Handler);
 45                 IVL_ErrorHandler*    ErrLostOptRight        = Syner.Err(LostOptRight_Handler);
 46                 IVL_ErrorHandler*    ErrLostExpRight        = Syner.Err(LostExpRight_Handler);
 47                 IVL_ErrorHandler*    ErrLostDeclLeft        = Syner.Err(LostDeclLeft_Handler);
 48                 IVL_ErrorHandler*    ErrLostDeclRight    = Syner.Err(LostDeclRight_Handler);
 49                 IVL_ErrorHandler*    ErrLostSemicolon    = Syner.Err(LostSemicolon_Handler);
 50                 IVL_ErrorHandler*    ErrLostLexList        = Syner.Err(LostLexList_Handler);
 51                 IVL_ErrorHandler*    ErrLostRuleList        = Syner.Err(LostRuleList_Handler);
 52 
 53                 Syner.Infer(Name_Handler,        Name)        =    Id[0| _Lexical[0| _Rule[0];
 54                 Syner.Infer(LexInfer_Handler,    LexInfer)    =    Name[0+ Infer[ErrLostInfer] + Regex[1][ErrLostRegex];
 55                 Syner.Infer(RuleUnit_Handler,    RuleUnit)    =    Name[0];
 56                 Syner.Infer(Copy_Handler,        RuleUnit)    =    ExpLeft + RuleExp[0][ErrLostRule] + ExpRight[ErrLostExpRight];
 57                 Syner.Infer(RuleOpt_Handler,    RuleUnit)    =    OptLeft + RuleExp[0][ErrLostRule] + OptRight[ErrLostOptRight];
 58                 Syner.Infer(RuleSeq_Handler,    RuleSeq)    =    RuleUnit[1+ Opt(RuleSeq[0]);
 59                 Syner.Infer(RuleExp_Handler,    RuleExp)    =    RuleSeq[1+ Opt(Or + RuleExp[0]);
 60                 Syner.Infer(RuleInfer_Handler,    RuleInfer)    =    Name[0+ Infer[ErrLostInfer] + RuleExp[1][ErrLostRule] + Semicolon[ErrLostSemicolon];
 61                 Syner.Infer(LexList_Handler,    LexList)    =    LexInfer[1+ Opt(LexList[0]);
 62                 Syner.Infer(RuleList_Handler,    RuleList)    =    RuleInfer[1+ Opt(RuleList[0]);
 63 
 64                 Syner.Infer(Program_Handler,    Program)    =    _Lexical[ErrLostLexList] +
 65                                                                 DeclLeft[ErrLostDeclLeft] +
 66                                                                 LexList[0][ErrLostLexList] +
 67                                                                 DeclRight[ErrLostDeclRight] +
 68 
 69                                                                 _Rule[ErrLostRuleList] +
 70                                                                 DeclLeft[ErrLostDeclLeft] +
 71                                                                 RuleList[1][ErrLostRuleList] +
 72                                                                 DeclRight[ErrLostDeclRight];
 73 
 74                 Syner.Initialize(Program);
 75             }
 76 
 77             ~InnerProvider()
 78             {
 79             }
 80 
 81             GrammarDescription::Ptr Parse(VUnicodeString Code)
 82             {
 83                 VL_SynMacInsListList Results;
 84                 VL_SynTokenErrorList Errors;
 85                 Provider->GetErrors().Clear();
 86                 Syner.Parse(Code,Results,Errors);
 87 
 88                 for(VInt i=0;i<Errors.GetCount();i++)
 89                 {
 90                     CompreSyner::TokenData& TokenData=Syner.GetLexicalResult()->GetDataOfPosition(Errors[i].Position);
 91                     if(&TokenData)
 92                     {
 93                         Provider->GetErrors().Add(Convert(TokenData,Errors[i].Message));
 94                     }
 95                     else
 96                     {
 97                         GrammarError Error;
 98                         Error.LineInFile=-1;
 99                         Error.PosInFile=-1;
100                         Error.PosInLine=-1;
101                         Provider->GetErrors().Add(Error);
102                     }
103                 }
104 
105                 if(Provider->GetErrors().GetCount())
106                 {
107                     return 0;
108                 }
109                 else
110                 {
111                     return Syner.Transform(Results[0]);
112                 }
113             }
114         };
115     }
posted on 2008-09-02 04:43 陳梓瀚(vczh) 閱讀(2641) 評(píng)論(10)  編輯 收藏 引用 所屬分類: 腳本技術(shù)

評(píng)論:
# re: 項(xiàng)目實(shí)驗(yàn)1:將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi) 2008-09-02 06:12 | 空明流轉(zhuǎn)
你也是個(gè)濫用Visitor一族了。。。  回復(fù)  更多評(píng)論
  
# re: 項(xiàng)目實(shí)驗(yàn)1:將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi) 2008-09-02 06:19 | 陳梓瀚(vczh)
反正那是程序?qū)懙模植皇俏覍?xiě)的……  回復(fù)  更多評(píng)論
  
# re: 項(xiàng)目實(shí)驗(yàn)1:將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi) 2008-09-02 06:28 | Lnn
牛牛牛  回復(fù)  更多評(píng)論
  
# re: 項(xiàng)目實(shí)驗(yàn)1:將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi) 2008-09-02 07:31 | 空明流轉(zhuǎn)
日。你要是指東你程序向西你就牛逼了。  回復(fù)  更多評(píng)論
  
# re: 項(xiàng)目實(shí)驗(yàn)1:將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi) 2008-09-02 07:57 | 陳梓瀚(vczh)
通常這都是一些很嚴(yán)重的bug,修不了,稱為feature。  回復(fù)  更多評(píng)論
  
# re: 項(xiàng)目實(shí)驗(yàn)1:將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi) 2008-09-05 21:42 | 錢(qián)正平
就你的示例而言,在AlgorithmEx類里面加上數(shù)據(jù)成員就完事了,不需要把String傳來(lái)傳去。  回復(fù)  更多評(píng)論
  
# re: 項(xiàng)目實(shí)驗(yàn)1:將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi) 2008-09-05 21:46 | 錢(qián)正平
因?yàn)槲矣X(jué)得數(shù)據(jù)結(jié)構(gòu)和算法是不能分離的,雖然你將變動(dòng)后的算法和原有數(shù)據(jù)結(jié)構(gòu)(object structure for the ast)分離了,但是實(shí)際上新的算法只是多操作了一個(gè)數(shù)據(jù)結(jié)構(gòu)(String)而已,而你的AlgorithmEx中的visit一族實(shí)際上可以看出和數(shù)據(jù)結(jié)構(gòu)(新加入的String)緊密相關(guān),因此是否作為AlgorithmEx(當(dāng)然我一直是指Concrete的那個(gè)類)的成員就行了?  回復(fù)  更多評(píng)論
  
# re: 項(xiàng)目實(shí)驗(yàn)1:將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi) 2008-09-06 02:24 | 陳梓瀚(vczh)
新加入的string是作為算法的【內(nèi)部參數(shù)】而做的。當(dāng)然,是不是內(nèi)部參數(shù)還是要看算法的設(shè)計(jì)者是怎么想的,我有時(shí)候就會(huì)讓外部結(jié)果作為內(nèi)部參數(shù)的一部分而傳進(jìn)去。

不過(guò)傳來(lái)傳去還是因?yàn)槲蚁胗肁pply來(lái)模擬虛函數(shù)的外觀,僅僅是為了好看。  回復(fù)  更多評(píng)論
  
# re: 項(xiàng)目實(shí)驗(yàn)1:將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi) 2008-09-09 08:31 | 阿二
stl不就是將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi)的典范么  回復(fù)  更多評(píng)論
  
# re: 項(xiàng)目實(shí)驗(yàn)1:將算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi) 2008-09-10 04:33 | 陳梓瀚(vczh)
跟我這個(gè)概念不一樣。他能見(jiàn)算法與數(shù)據(jù)結(jié)構(gòu)分開(kāi)依賴于他很多數(shù)據(jù)結(jié)構(gòu)都有很接近的接口的這個(gè)事實(shí)。但是這個(gè)假定在我這里是不成立的。  回復(fù)  更多評(píng)論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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久久精品播放免费| 麻豆精品一区二区av白丝在线| 99精品国产高清一区二区| 欧美国产1区2区| 欧美日韩中文| 久久久国产精品亚洲一区 | 欧美在线观看一区| 亚洲高清在线播放| 日韩系列在线| 欧美日韩三区四区| 欧美在线视频免费| 免费高清在线视频一区·| 亚洲深爱激情| 久久精彩免费视频| 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 亚洲色诱最新| 激情自拍一区| 9久草视频在线视频精品| 国产日韩欧美二区| 亚洲国产精品悠悠久久琪琪 | 在线视频精品一区| 狠狠综合久久av一区二区老牛| 亚洲国产一区二区在线| 国产精品永久免费观看| 亚洲电影免费在线观看| 国产精品亚洲综合色区韩国| 欧美二区不卡| 国产毛片精品视频| 亚洲精品美女91| 好吊视频一区二区三区四区| 日韩视频不卡中文| 在线看不卡av| 亚洲影院在线| 日韩视频免费| 久久精品国产亚洲高清剧情介绍| 一区二区三区四区五区精品视频| 久久九九热免费视频| 亚洲综合日韩中文字幕v在线| 久久一区亚洲| 欧美一区二区三区另类| 欧美精品精品一区| 久久综合九色综合欧美就去吻| 欧美午夜激情视频| 欧美激情女人20p| 国产一区二区三区观看| 99国产精品国产精品毛片| 亚洲国产精品久久久久秋霞不卡 | 91久久国产综合久久91精品网站| 亚洲你懂的在线视频| 日韩一区二区免费看| 久久久综合网| 久久精品毛片| 国产精品久久久久aaaa| 亚洲人成网站777色婷婷| 精品69视频一区二区三区 | 欧美一区二区三区四区在线| 欧美精品一区二区精品网| 美国成人毛片| 国产日韩欧美一区二区三区在线观看 | 猫咪成人在线观看| 久久视频在线看| 国产精品男女猛烈高潮激情| 日韩午夜在线视频| 亚洲另类一区二区| 久久尤物电影视频在线观看| 久久久国产一区二区三区| 国产精品日韩精品| 99精品视频免费全部在线| 亚洲日本电影| 乱人伦精品视频在线观看| 久久亚洲美女| 狠狠久久亚洲欧美专区| 欧美一级久久久| 欧美一站二站| 国产精品视频xxx| 亚洲午夜一区二区三区| 亚洲欧美欧美一区二区三区| 欧美日韩亚洲综合| 亚洲乱码国产乱码精品精| 日韩午夜三级在线| 欧美国产一区二区在线观看| 亚洲国产激情| 亚洲精品中文字幕女同| 欧美 日韩 国产精品免费观看| 欧美成人69| 亚洲国产网站| 亚洲一区二区三区四区中文| 亚洲一区二区视频在线| 美女脱光内衣内裤视频久久影院| 久久久久久综合| 国内精品模特av私拍在线观看| 午夜久久久久久| 久久精品综合一区| 国产一区日韩一区| 久久国产精品99国产精| 久久综合给合久久狠狠狠97色69| 国内成人自拍视频| 久久精品人人做人人爽电影蜜月| 老司机免费视频一区二区| 怡红院精品视频在线观看极品| 久久人人97超碰国产公开结果| 免费观看国产成人| 亚洲国产精品va| 欧美国产高清| 日韩视频中文| 午夜精品福利一区二区三区av| 国产精品色一区二区三区| 午夜精品短视频| 久久在线视频| 91久久精品国产| 欧美日韩视频在线第一区| 一区二区三区毛片| 欧美在线关看| 在线观看国产精品网站| 欧美福利专区| 亚洲色诱最新| 久久久国产成人精品| 亚洲高清av在线| 欧美区二区三区| 亚洲性视频h| 久久亚洲精品欧美| 亚洲精品乱码久久久久久| 欧美日韩精品一区二区三区| 亚洲一区不卡| 麻豆成人小视频| 99re6这里只有精品| 国产精品麻豆va在线播放| 欧美在线播放视频| 亚洲国产精品女人久久久| 亚洲一二三区精品| 国模精品一区二区三区| 欧美成人精品福利| 在线中文字幕一区| 久久综合伊人77777| 日韩视频一区二区在线观看 | 亚洲午夜久久久| 久久久久久久一区二区三区| 亚洲欧洲日本国产| 国产精品美女久久福利网站| 久久久激情视频| 亚洲精品一区二区网址 | 国产日韩欧美一区二区三区在线观看 | 国产日产亚洲精品| 99视频精品全国免费| 久久久精品性| 亚洲免费高清| 国产日韩欧美一区二区三区四区| 免费成人av在线| 亚洲一区二区视频| 欧美夫妇交换俱乐部在线观看| 亚洲香蕉网站| 亚洲第一在线| 国产精品少妇自拍| 欧美电影电视剧在线观看| 亚洲欧美日韩电影| 亚洲激情啪啪| 久久精品一区二区国产| 99综合电影在线视频| 海角社区69精品视频| 欧美三级第一页| 久久综合伊人| 亚洲在线国产日韩欧美| 亚洲国产精品黑人久久久| 欧美制服第一页| 一区二区av在线| 在线看成人片| 国产精品亚洲网站| 欧美精品一区二| 久久久无码精品亚洲日韩按摩| 亚洲天堂成人| 亚洲国产精品综合| 久久久人成影片一区二区三区| 中文精品视频一区二区在线观看| 在线观看欧美视频| 国产欧美视频一区二区| 欧美日韩精品二区第二页| 久久天天躁狠狠躁夜夜av| 亚洲欧美在线免费| aa日韩免费精品视频一| 欧美激情成人在线| 久久五月激情| 欧美一区二区在线看| 亚洲丝袜av一区| 亚洲精品一二| 亚洲第一天堂av| 国产亚洲精品久久久久动| 国产精品久久久久久妇女6080| 欧美精品麻豆| 老司机成人网| 久久国产精品网站| 亚洲免费在线视频| 一区二区三区毛片| 亚洲免费观看高清在线观看| 亚洲国产乱码最新视频| 欧美a一区二区| 卡通动漫国产精品|