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);
编译你的分析器的同时编译器就为你检查了文法有无书写错误,并且再复杂的表达式都能成功被编译.
posted on 2010-07-22 23:23
lwch 阅读(1216)
评论(0) 编辑 收藏 引用 所属分类:
NScript