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

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

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

     一份文法的結構從數據結構上來看并不復雜。文法由詞法記號定義以及文法推導式定義組成,其中文法推導式子的表達式又有終結符、連接、分支以及可選等等。譬如下面的一份文法文件(給正在開發的代碼生成器用的)的內容是一種科學計算器的表達式文法。這個文法能夠分析數字、單目操作符、雙目操作符、括號以及函數調用:
 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 }

    我們用什么樣的數據結構來記錄這些內容呢?答案并不復雜,做一個基類表示抽象文法樹,其他的都是簡單的結構:
 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個類是有內容的,其中一部分類的基類GrammarBase是沒有內容的。因此GrammarAlgorithm類就有7個函數,分別用于接收不同對象的Apply函數的調用:
 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函數是如何被調用的呢?這里是重載,重載當然有其好處了,因為子類們的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     }

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

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

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

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

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

    虛函數所帶來的好處就被這個新的Algorithm解決了。現在拿到一個非常復雜的充滿了繼承的數據結構也不用怕了。我們可以不破壞原有的代碼,建立起自己的“虛函數”了。說到這里,我來用一用這個Algorithm。我將文法文件讀入GrammarDescription之后,用一個算法對象來將結果轉換為字符串:
 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     }

    看看結果吧!
  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,一切都很美好。我只要把文法文件本身需要遵守的文法寫進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)  編輯 收藏 引用 所屬分類: 腳本技術

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

不過傳來傳去還是因為我想用Apply來模擬虛函數的外觀,僅僅是為了好看。  回復  更多評論
  
# re: 項目實驗1:將算法與數據結構分開 2008-09-09 08:31 | 阿二
stl不就是將算法與數據結構分開的典范么  回復  更多評論
  
# re: 項目實驗1:將算法與數據結構分開 2008-09-10 04:33 | 陳梓瀚(vczh)
跟我這個概念不一樣。他能見算法與數據結構分開依賴于他很多數據結構都有很接近的接口的這個事實。但是這個假定在我這里是不成立的。  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            1024亚洲| 欧美一区二区三区在线视频 | 欧美一区二区三区在线免费观看| 最新国产成人av网站网址麻豆| 在线看片日韩| 在线欧美日韩国产| 亚洲激情专区| 亚洲无吗在线| 久久久久国产精品厨房| 久久这里只有| 夜夜嗨av色一区二区不卡| 蜜乳av另类精品一区二区| 免费观看成人www动漫视频| 欧美成人午夜77777| 欧美激情精品久久久久久变态| 亚洲成人在线网| 亚洲精品久久久久久久久| 宅男精品视频| 久久免费国产精品| 欧美日韩一区二区欧美激情| 国产欧美日韩另类一区| 亚洲欧洲精品一区二区三区 | 久久精品99国产精品| 欧美电影专区| 亚洲女人小视频在线观看| 久久久久国产免费免费| 欧美日韩午夜精品| 精品电影在线观看| 亚洲视频久久| 欧美福利视频在线| 亚洲天堂偷拍| 老司机免费视频久久| 欧美黄色网络| 国产一区视频观看| 一本一道久久综合狠狠老精东影业 | 尤物精品在线| 亚洲精品在线观看视频| 亚洲一级一区| 亚洲国产欧美日韩另类综合| 亚洲特级毛片| 欧美国产在线电影| 狠狠入ady亚洲精品经典电影| 亚洲五月六月| 亚洲人成毛片在线播放| 久久久国产精品一区二区中文| 欧美系列电影免费观看| 亚洲人成7777| 欧美成人免费在线观看| 欧美在线亚洲一区| 国产视频亚洲精品| 欧美一级淫片aaaaaaa视频| 亚洲免费观看高清完整版在线观看熊| 久久亚洲二区| 在线观看亚洲一区| 美女国产精品| 久久综合影音| 亚洲国产99| 欧美成人午夜激情在线| 久久精品国产91精品亚洲| 国产乱码精品一区二区三区五月婷| 免费一级欧美在线大片| 在线一区亚洲| 欧美色综合天天久久综合精品| 日韩一区二区久久| 亚洲片区在线| 欧美精品在线观看一区二区| 在线精品视频免费观看| 欧美不卡高清| 欧美成人国产| 亚洲最新合集| 一区二区精品国产| 国产精品九九| 欧美亚洲一区| 久久av一区二区三区| 国模精品一区二区三区色天香| 久久国产精品毛片| 久久九九精品99国产精品| 在线观看日韩精品| 最新日韩精品| 国产精品久久久久久久久久ktv | aaa亚洲精品一二三区| 91久久久亚洲精品| 欧美日韩hd| 香蕉精品999视频一区二区 | 亚洲精品一区二区三区99| 欧美日韩国产影院| 欧美一级视频免费在线观看| 久久激情网站| 99精品视频免费观看视频| 一区二区成人精品 | 午夜电影亚洲| 亚洲国产精品久久久久婷婷老年| 亚洲第一精品影视| 欧美视频网站| 久久字幕精品一区| 欧美日韩一区二区三区视频| 久久精品国产精品亚洲| 欧美韩日一区| 欧美伊久线香蕉线新在线| 老司机午夜精品视频在线观看| 一区二区三区色| 久久九九热免费视频| 一本色道久久88综合日韩精品| 欧美一区二区在线免费播放| 日韩亚洲欧美一区| 欧美专区在线观看| 亚洲一区二区三区精品在线观看| 久久精品一区二区| 在线亚洲电影| 噜噜噜躁狠狠躁狠狠精品视频| 午夜精品区一区二区三| 欧美成人嫩草网站| 狼人社综合社区| 国产嫩草影院久久久久 | 日韩视频在线一区二区| 一区二区高清在线观看| 在线免费日韩片| 亚洲综合第一| 日韩网站免费观看| 久久久久久久综合| 久久国产精品久久久久久久久久| 欧美人与性动交α欧美精品济南到| 久久人人爽人人爽爽久久| 欧美视频在线播放| 最新中文字幕一区二区三区| 极品少妇一区二区| 午夜久久美女| 欧美一区二区日韩| 欧美视频1区| 亚洲伦理在线观看| 亚洲精品一区二区三区在线观看| 久久精品国产在热久久| 欧美一级视频精品观看| 国产精品高潮呻吟视频| 亚洲乱码国产乱码精品精天堂| 亚洲精选一区| 欧美激情一区二区三区| 亚洲国产岛国毛片在线| 亚洲国产精品小视频| 久久久伊人欧美| 久久综合伊人77777| 激情久久五月| 久久久午夜视频| 久热精品在线| 在线精品视频一区二区| 老司机67194精品线观看| 免费在线观看日韩欧美| 亚洲国产欧美一区二区三区同亚洲| 久久欧美中文字幕| 久久躁狠狠躁夜夜爽| 亚洲福利在线看| 欧美韩国日本综合| 一区二区三区欧美亚洲| 欧美一区二区三区免费大片| 国产日韩欧美中文| 久久久青草婷婷精品综合日韩 | 亚洲尤物视频网| 国产精品久久久久久久久免费樱桃 | 久久精品官网| 亚洲国产精品va在线看黑人动漫| 亚洲精品久久7777| 国产精品www994| 欧美一区二区在线免费播放| 欧美成人国产| 亚洲午夜极品| 国产亚洲一区二区三区在线观看| 亚洲欧美日韩国产综合精品二区| 久久久免费精品视频| 伊人蜜桃色噜噜激情综合| 欧美1区2区3区| 亚洲尤物在线| 久热精品视频在线| av成人免费在线| 国产精品一区二区三区久久久 | 日韩视频三区| 一区二区高清视频在线观看| 欧美日韩国产高清视频| 亚洲自拍偷拍麻豆| 蜜臀va亚洲va欧美va天堂| 一区二区三区日韩精品视频| 国产精品区一区二区三区| 久久久www成人免费精品| 亚洲电影av在线| 欧美专区在线观看一区| 亚洲精品国产精品国自产在线 | 欧美激情欧美狂野欧美精品| 亚洲一区精品电影| 亚洲国产清纯| 国产啪精品视频| 欧美日本视频在线| 久久九九精品| 亚洲欧美日韩一区二区在线 | 宅男66日本亚洲欧美视频| 女人香蕉久久**毛片精品| 亚洲尤物视频在线| 日韩视频免费看| 最新成人在线| 亚洲国产精品一区在线观看不卡| 欧美日韩在线影院| 欧美大片在线观看一区|