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

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

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

     一份文法的結(jié)構(gòu)從數(shù)據(jù)結(jié)構(gòu)上來看并不復(fù)雜。文法由詞法記號定義以及文法推導(dǎo)式定義組成,其中文法推導(dǎo)式子的表達(dá)式又有終結(jié)符、連接、分支以及可選等等。譬如下面的一份文法文件(給正在開發(fā)的代碼生成器用的)的內(nèi)容是一種科學(xué)計算器的表達(dá)式文法。這個文法能夠分析數(shù)字、單目操作符、雙目操作符、括號以及函數(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)來記錄這些內(nèi)容呢?答案并不復(fù)雜,做一個基類表示抽象文法樹,其他的都是簡單的結(jié)構(gòu):
 1 /*********************************************************************************************************
 2 語法樹
 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     };

    大家注意到這里有一個GrammarAlgorithm,這個是訪問者模式所帶來的一個接口類。上面一共有7個類是有內(nèi)容的,其中一部分類的基類GrammarBase是沒有內(nèi)容的。因此GrammarAlgorithm類就有7個函數(shù),分別用于接收不同對象的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)然有其好處了,因為子類們的this都是有確切的類型的:
 1 /*********************************************************************************************************
 2 語法樹
 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     }

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

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

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

    這個NewAlgorithm肯定也要有自己的一組帶有返回結(jié)果和參數(shù)的Visit函數(shù)族了。于是我們可以在原來的Visit函數(shù)族里面做返回值和參數(shù)的間接處理,當(dāng)然還是用成員變量最簡單了。不過為了保護(hù),我們將繼承修改為private,然后用一個隱式轉(zhuǎn)換來得到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ù)吧。這個函數(shù)就是新的Algorithm的關(guān)鍵。我們可以隨便來一個什么對象就result=Apply(obj,parameters);,然后Apply填好參數(shù),調(diào)用obj->Apply(*this);。這里*this調(diào)用operator GrammarAlgorithm*()得到需要的類型,然后由obj自己發(fā)配到原來的Visit上。原來的Visit填好返回值,Apply返回,調(diào)用成功!

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

    虛函數(shù)所帶來的好處就被這個新的Algorithm解決了。現(xiàn)在拿到一個非常復(fù)雜的充滿了繼承的數(shù)據(jù)結(jié)構(gòu)也不用怕了。我們可以不破壞原有的代碼,建立起自己的“虛函數(shù)”了。說到這里,我來用一用這個Algorithm。我將文法文件讀入GrammarDescription之后,用一個算法對象來將結(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 }

    至于分析器本身是怎么寫的呢?用了Vczh牌Syngram,一切都很美好。我只要把文法文件本身需要遵守的文法寫進(jìn)C++,那么我就有了一個分析器了。能處理左遞歸的哦,跟某些受人崇拜的C++庫不一樣。
  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) 閱讀(2639) 評論(10)  編輯 收藏 引用 所屬分類: 腳本技術(shù)

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

不過傳來傳去還是因為我想用Apply來模擬虛函數(shù)的外觀,僅僅是為了好看。  回復(fù)  更多評論
  
# re: 項目實驗1:將算法與數(shù)據(jù)結(jié)構(gòu)分開 2008-09-09 08:31 | 阿二
stl不就是將算法與數(shù)據(jù)結(jié)構(gòu)分開的典范么  回復(fù)  更多評論
  
# re: 項目實驗1:將算法與數(shù)據(jù)結(jié)構(gòu)分開 2008-09-10 04:33 | 陳梓瀚(vczh)
跟我這個概念不一樣。他能見算法與數(shù)據(jù)結(jié)構(gòu)分開依賴于他很多數(shù)據(jù)結(jié)構(gòu)都有很接近的接口的這個事實。但是這個假定在我這里是不成立的。  回復(fù)  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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久久免费看 | 久热re这里精品视频在线6| 99国产精品自拍| 亚洲在线电影| 欧美在线一二三四区| 欧美sm重口味系列视频在线观看| 欧美激情亚洲另类| 亚洲视频精品在线| 久久久精品国产免大香伊| 欧美国产日韩一二三区| 国产精品任我爽爆在线播放| 在线播放国产一区中文字幕剧情欧美 | 久久影院午夜片一区| 欧美成人国产| 一区二区三区久久久| 久久免费视频网| 欧美亚男人的天堂| 在线观看亚洲专区| 先锋资源久久| 日韩视频―中文字幕| 久久欧美中文字幕| 国产欧美在线观看| 99在线|亚洲一区二区| 久热成人在线视频| 亚洲综合首页| 国产精品久久久久久av福利软件| 亚洲国产精品福利| 久久国内精品自在自线400部| 亚洲国产综合在线看不卡| 久久精品国产一区二区三区免费看| 欧美日韩不卡一区| 最新成人在线| 欧美波霸影院| 久久精品国产综合精品| 国产精品久久久久久久久搜平片 | 日韩一区二区精品视频| 久久精品91| 亚洲午夜在线| 国产精品二区二区三区| 野花国产精品入口| 亚洲国产精品免费| 蜜桃av一区| 亚洲国产成人精品视频| 久久手机精品视频| 欧美在线你懂的| 国产日韩欧美不卡| 性做久久久久久久久| 一区二区精品在线观看| 欧美日韩八区| 亚洲欧美电影院| 中国成人黄色视屏| 国产精品乱码妇女bbbb| 亚洲在线播放| 亚洲男人的天堂在线aⅴ视频| 欧美视频不卡| 欧美在线观看视频| 欧美在线观看视频一区二区三区| 国产拍揄自揄精品视频麻豆| 欧美一级在线播放| 亚洲欧美一区二区原创| 国产视频在线观看一区| 久久精品99久久香蕉国产色戒| 亚洲欧美美女| 国产在线精品自拍| 男人的天堂亚洲在线| 久久久亚洲精品一区二区三区 | 99精品福利视频| 久久久久www| 好看不卡的中文字幕| 久久精品视频亚洲| 久久精品国产一区二区三| 亚洲国产精品悠悠久久琪琪| 亚洲国产毛片完整版| 欧美日韩高清一区| 午夜免费久久久久| 欧美一区二区三区免费看| 怡红院av一区二区三区| 亚洲国产欧美日韩精品| 欧美深夜影院| 久久精品一本| 欧美成人精品影院| 亚洲免费在线视频一区 二区| 亚洲欧美中文在线视频| 亚洲大片在线观看| 在线视频一区二区| 激情久久久久久久| 亚洲精品国产欧美| 国产精品一区二区久久久久| 你懂的视频欧美| 欧美午夜精品久久久久久超碰| 久久激情视频久久| 欧美久久久久久蜜桃| 久久国产直播| 欧美日韩一区二区视频在线观看 | 开心色5月久久精品| 欧美黄色网络| 久久久久国产精品厨房| 欧美日韩精品一区二区天天拍小说 | 欧美日韩国产影院| 久久久中精品2020中文| 欧美精品在线观看| 另类激情亚洲| 国产欧美精品国产国产专区| 91久久线看在观草草青青| 国语自产在线不卡| 中文在线资源观看网站视频免费不卡 | 欧美 日韩 国产一区二区在线视频 | 91久久夜色精品国产九色| 亚洲精品一区二区三区99| 国产视频一区在线观看| 亚洲毛片网站| 亚洲国产精品成人久久综合一区| 亚洲视屏在线播放| 一区二区三区成人| 玖玖玖国产精品| 久久尤物电影视频在线观看| 国产精品福利av| 99精品国产在热久久| 亚洲精品乱码久久久久久日本蜜臀| 久久国产88| 久久久久国产一区二区三区| 国产欧美日韩免费| 午夜精品视频网站| 欧美专区18| 国产欧美一区二区在线观看| 亚洲综合色视频| 久久精品夜夜夜夜久久| 韩国女主播一区| 久久视频国产精品免费视频在线| 久久国产视频网站| 狠狠久久五月精品中文字幕| 欧美一级久久久久久久大片| 久久动漫亚洲| 狠狠做深爱婷婷久久综合一区 | 免费看亚洲片| 亚洲国产精品成人久久综合一区| 久久免费偷拍视频| 欧美激情一区在线| 99在线热播精品免费99热| 欧美日韩一区二区三区免费| 亚洲最新在线视频| 小黄鸭视频精品导航| 国产婷婷成人久久av免费高清 | 亚洲天堂网在线观看| 亚洲欧美日韩在线观看a三区| 国产精品最新自拍| 久久成人精品视频| 欧美激情日韩| 亚洲一区三区视频在线观看| 国产精品久久国产三级国电话系列| 亚洲欧美日韩精品久久奇米色影视| 久久xxxx| 亚洲精品国产系列| 国产精品久久久久久久浪潮网站 | 欧美二区在线播放| 亚洲图片你懂的| 国产亚洲午夜| 欧美成人久久| 亚洲尤物视频在线| 嫩草成人www欧美| 亚洲婷婷综合久久一本伊一区| 国产婷婷成人久久av免费高清 | 激情小说另类小说亚洲欧美 | 激情欧美一区二区| 欧美久久久久久久久| 国产精品乱人伦一区二区| 99在线热播精品免费| 欧美一级播放| 亚洲欧洲一区二区三区久久| 国产精品久久久久av| 久久免费视频一区| 亚洲女爱视频在线| 亚洲韩日在线| 久久精品网址| 亚洲视屏一区| 亚洲国内精品| 黑人巨大精品欧美一区二区小视频| 欧美不卡福利| 久久超碰97人人做人人爱| aaa亚洲精品一二三区| 欧美高清视频在线| 欧美中文字幕视频| 亚洲午夜精品久久久久久app| 在线欧美日韩| 国产亚洲欧美一区二区| 国产精品国产馆在线真实露脸| 米奇777超碰欧美日韩亚洲| 欧美一区二区在线播放| 亚洲午夜激情| av成人免费在线| 99热免费精品在线观看| 亚洲国产成人精品女人久久久 |