计算机二级

3773考试网计算机等级考试计算机二级正文

C++ 中Precept和NV类如何封装

来源:fjzsksw.com 2010-7-28 9:43:24

 

1 #pragma once

  2 #include "..\String\NWString.h"

  3 #include "..\AutoPtr\AutoPtr.h"

  4 #include "..\Common\List.h"

  5

  6 #define Type_Match_Content                                                0        // 匹配值

  7 #define Type_Match_Rule                                                    1        // 匹配一条表达式

  8 #define Type_Or                                                           -1

  9 #define Type_Choose                                                       -2

  10 #define Type_Loop_0                                                       -3

  11 #define Type_Loop_1                                                       -4

  12 #define Type_Opt                                                       -5

  13 #define Type_LQ                                                           -6

  14 #define Type_RQ                                                           -7

  15

  16 class Precept

  17 {

  18 public:

  19     int Left;

  20     List<int> Right;

  21

  22     Precept() : Left(0){}

  23     Precept(int L,List<int> R) : Left(L),Right(R){}

  24

  25     // +Precept

  26     friend NAutoPtr<Precept> operator+(NAutoPtr<Precept> P)

  27     {

  28         NAutoPtr<Precept> p = new Precept;

  29         p->Right.Add(Type_Loop_1);

  30         p->Right.Add(Type_LQ);

  31         p->Right.Add(P->Right);

  32         p->Right.Add(Type_RQ);

  33         return p;

  34     }

  35

  36     // Precept + Precept

  37     friend NAutoPtr<Precept> operator+(NAutoPtr<Precept> P1,NAutoPtr<Precept> P2)

  38     {

  39         NAutoPtr<Precept> p = new Precept;

  40         p->Right.Add(P1->Right);

  41         p->Right.Add(P2->Right);

  42         return p;

  43     }

  44

  45     // *Precept

  46     friend NAutoPtr<Precept> operator*(NAutoPtr<Precept> P)

  47     {

  48         NAutoPtr<Precept> p = new Precept;

  49         p->Right.Add(Type_Loop_0);

  50         p->Right.Add(Type_LQ);

  51         p->Right.Add(P->Right);

  52         p->Right.Add(Type_RQ);

  53         return p;

  54     }

  55

 56     // Precept | Precept

  57     friend NAutoPtr<Precept> operator|(NAutoPtr<Precept> P1,NAutoPtr<Precept> P2)

  58     {

  59         NAutoPtr<Precept> p = new Precept;

  60         p->Right.Add(Type_LQ);

  61         p->Right.Add(P1->Right);

  62         p->Right.Add(Type_RQ);

  63         p->Right.Add(Type_Or);

  64         p->Right.Add(Type_LQ);

  65         p->Right.Add(P2->Right);

  66         p->Right.Add(Type_RQ);

  67         return p;

  68     }

  69 };

  70

  71 class NV

  72 {

  73 public:

  74     NWString Content;

  75     int Type;                // Content Or Rule

  76     int Index;                // Index Of this

  77

  78     NV() : Index(0),Type(0){}

  79     NV(NWString C,NWString R,int T) : Content(C),Type(T){}

  80

  81     BOOL operator==(NV V)

  82     {

  83         return Content == V.Content && Type == V.Type;

  84     }

  85

  86     // Left->V

  87     NAutoPtr<Precept> SetRight(NAutoPtr<NV> V)

  88     {

  89         NAutoPtr<Precept> p = new Precept;

  90         p->Left = Index;

  91         p->Right.Add(V->Index);

  92         return p;

  93     }

  94

  95     // Left->Precept

  96     NAutoPtr<Precept> SetRight(NAutoPtr<Precept> P)

  97     {

  98         NAutoPtr<Precept> p = new Precept;

  99         p->Left = Index;

  100         p->Right.Add(P->Right);

  101         return p;

  102     }

  103

  104     // this + NV

  105     NAutoPtr<Precept> operator+(NAutoPtr<NV> V)

  106     {

  107         NAutoPtr<Precept> p = new Precept;

  108         p->Right.Add(Index);

  109         p->Right.Add(V->Index);

  110         return p;

  111     }

  112

  113     // NV + NV

  114     friend NAutoPtr<Precept> operator+(NAutoPtr<NV> V1,NAutoPtr<NV> V2)

  115     {

  116         NAutoPtr<Precept> p = new Precept;

  117         p->Right.Add(V1->Index);

  118         p->Right.Add(V2->Index);

  119         return p;

  120     }

  121

  122     // Precept + NV

  123     friend NAutoPtr<Precept> operator+(NAutoPtr<Precept> P,NAutoPtr<NV> V)

  124     {

  125         NAutoPtr<Precept> p = new Precept;

  126         p->Right.Add(P->Right);

  127         p->Right.Add(V->Index);

  128         return p;

  129     }

  130

  131     // NV + Precept

  132     friend NAutoPtr<Precept> operator+(NAutoPtr<NV> V,NAutoPtr<Precept> P)

  133     {

  134         NAutoPtr<Precept> p = new Precept;

  135         p->Right.Add(V->Index);

  136         p->Right.Add(P->Right);

  137         return p;

  138     }

  139

  140     // this | NV

  141     NAutoPtr<Precept> operator|(NAutoPtr<NV> V)

  142     {

  143         NAutoPtr<Precept> p = new Precept;

  144         p->Right.Add(Index);

  145         p->Right.Add(Type_Or);

  146         p->Right.Add(V->Index);

  147         return p;

  148     }

  149

  150     // NV | NV

  151     friend NAutoPtr<Precept> operator|(NAutoPtr<NV> V1,NAutoPtr<NV> V2)

  152     {

  153         NAutoPtr<Precept> p = new Precept;

  154         p->Right.Add(V1->Index);

  155         p->Right.Add(Type_Or);

  156         p->Right.Add(V2->Index);

  157         return p;

  158     }

  159

  160     // Precept | NV

  161     friend NAutoPtr<Precept> operator|(NAutoPtr<Precept> P,NAutoPtr<NV> V)

  162     {

  163         NAutoPtr<Precept> p = new Precept;

  164         p->Right.Add(Type_LQ);

  165         p->Right.Add(P->Right);

  166         p->Right.Add(Type_RQ);

  167         p->Right.Add(Type_Or);

  168         p->Right.Add(V->Index);

  169         return p;

  170     }

  171

  172     // NV | Precept

  173     friend NAutoPtr<Precept> operator|(NAutoPtr<NV> V,NAutoPtr<Precept> P)

  174     {

  175         NAutoPtr<Precept> p = new Precept;

  176         p->Right.Add(V->Index);

  177         p->Right.Add(Type_Or);

  178         p->Right.Add(Type_LQ);

  179         p->Right.Add(P->Right);

  180         p->Right.Add(Type_RQ);

  181         return p;

  182     }

  183

184     // +NV

  185     friend NAutoPtr<Precept> operator+(NAutoPtr<NV> V)

  186     {

  187         NAutoPtr<Precept> p = new Precept;

  188         p->Right.Add(Type_Loop_1);

  189         p->Right.Add(V->Index);

  190         return p;

  191     }

  192

  193     // *NV

  194     friend NAutoPtr<Precept> operator*(NAutoPtr<NV> V)

  195     {

  196         NAutoPtr<Precept> p = new Precept;

  197         p->Right.Add(Type_Loop_0);

  198         p->Right.Add(V->Index);

  199         return p;

  200     }

  201

  202     // Opt(NV)

  203     friend NAutoPtr<Precept> Opt(NAutoPtr<NV> V)

  204     {

  205         NAutoPtr<Precept> p = new Precept;

  206         p->Right.Add(Type_Opt);

  207         p->Right.Add(V->Index);

  208         return p;

  209     }

  210

  211     // Opt(Precept)

  212     friend NAutoPtr<Precept> Opt(NAutoPtr<Precept> P)

  213     {

  214         NAutoPtr<Precept> p = new Precept;

  215         p->Right.Add(Type_Opt);

  216         p->Right.Add(Type_LQ);

  217         p->Right.Add(P->Right);

  218         p->Right.Add(Type_RQ);

  219         return p;

  220     }

  221 };

  222

  说明:

  Precept类主要用于保存一条产生式

  NV类则用来保存一个终结符或非终结符

  对于以上操作符重载后你就可以像书写文法那样来写你的代码了.

  比如你要写一条产生式:Program->aaa [bbb+ + ccc*] | bbb+ | [ccc]

  那么你可以书写以下代码来生成这条产生式:

  1     NParserDFA DFA;

  2     NAutoPtr<NV> Program = new NV(L"program",L"",Type_Match_Content);

  3     NAutoPtr<NV> aaa = new NV(L"aaa",L"",Type_Match_Content);

  4     NAutoPtr<NV> bbb = new NV(L"bbb",L"",Type_Match_Content);

  5     NAutoPtr<NV> ccc = new NV(L"ccc",L"",Type_Match_Content);

  6     // 以上生成终结符和非终结符

  7     DFA.AddVn(Program);

  8     DFA.AddVt(aaa);

  9     DFA.AddVt(bbb);

  10     DFA.AddVt(ccc);

  11     // 将终结符和非终结符添加到表中

  12     DFA.SetStart(Program);

  13     // 设置起始非终结符

  14     List<NAutoPtr<Precept>> PreceptList;

  15     NAutoPtr<Precept> p;

  16     // Program->aaa [bbb+ + ccc*] | bbb+ | [ccc]

  17     p = Program->SetRight(aaa + Opt(+bbb + *ccc) | +bbb | Opt(ccc));

  18     // 添加产生式

  19     PreceptList.Add(p);

 

 

触屏版 电脑版
3773考试网 琼ICP备12003406号-1