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 // 匹配一條表達(dá)式
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
說(shuō)明:
Precept類主要用于保存一條產(chǎn)生式
NV類則用來(lái)保存一個(gè)終結(jié)符或非終結(jié)符
對(duì)于以上操作符重載后你就可以像書寫文法那樣來(lái)寫你的代碼了.
比如你要寫一條產(chǎn)生式:Program->aaa [bbb+ + ccc*] | bbb+ | [ccc]
那么你可以書寫以下代碼來(lái)生成這條產(chǎn)生式:
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 // 以上生成終結(jié)符和非終結(jié)符
7 DFA.AddVn(Program);
8 DFA.AddVt(aaa);
9 DFA.AddVt(bbb);
10 DFA.AddVt(ccc);
11 // 將終結(jié)符和非終結(jié)符添加到表中
12 DFA.SetStart(Program);
13 // 設(shè)置起始非終結(jié)符
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 // 添加產(chǎn)生式
19 PreceptList.Add(p);
編譯你的分析器的同時(shí)編譯器就為你檢查了文法有無(wú)書寫錯(cuò)誤,并且再?gòu)?fù)雜的表達(dá)式都能成功被編譯.
posted on 2010-07-22 23:23
lwch 閱讀(1227)
評(píng)論(0) 編輯 收藏 引用 所屬分類:
NScript