1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "mdparser.h"
17
18 namespace MDGen {
ParseFile(const std::string & inputFile)19 bool MDParser::ParseFile(const std::string &inputFile)
20 {
21 lexer.PrepareFile(inputFile);
22 if (!ParseObjectStart()) {
23 return false;
24 }
25 if (lexer.GetCurKind() == kMDEOF) {
26 return true;
27 }
28 return EmitError("Unexpected input at begin");
29 }
30
IsObjectStart(MDTokenKind k) const31 bool MDParser::IsObjectStart(MDTokenKind k) const
32 {
33 return (k == kMDDef || k == kMDClass || k == kMDDefType);
34 }
35
ParseObjectStart()36 bool MDParser::ParseObjectStart()
37 {
38 while (IsObjectStart(lexer.NextToken())) {
39 if (!ParseObject()) {
40 return false;
41 }
42 }
43 return true;
44 }
45
ParseObject()46 bool MDParser::ParseObject()
47 {
48 switch (lexer.GetCurKind()) {
49 case kMDDefType:
50 return ParseDefType();
51 case kMDClass:
52 return ParseMDClass();
53 case kMDDef:
54 return ParseMDObject();
55 default:
56 return EmitError("Unexpected key word at start");
57 }
58 }
59
ParseDefType()60 bool MDParser::ParseDefType()
61 {
62 if (lexer.NextToken() != kMDIdentifier) {
63 return EmitError("Expect a name after a specific type defined");
64 }
65 unsigned int defTypeIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kTypeName);
66 if (defTypeIdx == UINT_MAX) {
67 return EmitError("InValid defType is defined");
68 }
69 if (lexer.NextToken() != kMDEqual) {
70 return EmitError("Expect a equal when a specific type is going to be instantiated");
71 }
72 std::set<unsigned int> defTypeMembers;
73 while (lexer.NextToken() != kMDSemi) {
74 switch (lexer.GetCurKind()) {
75 case kMDIdentifier: {
76 unsigned int defTypeMemberIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kTypeMemberName);
77 if (defTypeMemberIdx == UINT_MAX || !defTypeMembers.insert(defTypeMemberIdx).second) {
78 return EmitError("InValid defType member is defined");
79 }
80 break;
81 }
82 case kMDComma:
83 break;
84 default:
85 return EmitError("Unexpected token kind");
86 }
87 }
88 dataKeeper.AddDefinedType(defTypeIdx, defTypeMembers);
89 return (lexer.GetCurKind() == kMDSemi) ? true : EmitError("Expected an ending with a semicolon");
90 }
91
ParseMDClass()92 bool MDParser::ParseMDClass()
93 {
94 if (lexer.NextToken() != kMDIdentifier) {
95 return EmitError("Expect a name after a specific class defined");
96 }
97 unsigned int classIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kClassName);
98 if (classIdx == UINT_MAX) {
99 return EmitError("InValid class name. Please change a class name");
100 }
101 bool isAnon = true;
102 if (lexer.NextToken() == kMDColon) {
103 isAnon = false;
104 if (lexer.NextToken() != kMDIdentifier) {
105 return EmitError("Expect a name after a specific class defined");
106 }
107 if (lexer.GetStrToken() != "string") {
108 return EmitError("Only Support string as a class name type at current stage");
109 }
110 static_cast<void>(lexer.NextToken());
111 }
112 if (isAnon) {
113 dataKeeper.ModifyStrTyInTable(lexer.GetStrToken(), kAnonClassName);
114 }
115 MDClass oneMDclass(classIdx, isAnon);
116 if (lexer.GetCurKind() != kMDLess) {
117 return EmitError("Expect a 'less' before class structure being defined");
118 }
119
120 while (lexer.NextToken() != kMDGreater) {
121 if (!ParseMDClassBody(oneMDclass)) {
122 return false;
123 }
124 }
125 dataKeeper.AddMDClass(oneMDclass);
126 return (lexer.NextToken() == kMDSemi) ? true : EmitError("Expected an ending with a semicolon");
127 }
128
ParseMDClassBody(MDClass & oneClass)129 bool MDParser::ParseMDClassBody(MDClass &oneClass)
130 {
131 switch (lexer.GetCurKind()) {
132 case kMDIdentifier: {
133 StrInfo defTypeInfo = dataKeeper.GetStrInTable(lexer.GetStrToken());
134 if (defTypeInfo.idx == UINT_MAX || !oneClass.IsValidStructEle(defTypeInfo.sType)) {
135 return EmitError("Expect a defined Type to be a memeber of a class");
136 }
137 bool isVec = false;
138 if (lexer.ViewNextChar() == '[') {
139 if (lexer.NextToken() != kMDOpenSquare || lexer.NextToken() != kMDCloseSquare) {
140 return EmitError("Expect a \"[]\" to represent a list element");
141 }
142 isVec = true;
143 }
144 oneClass.BuildFormalTypes(defTypeInfo.idx, isVec);
145 break;
146 }
147 case kMDComma:
148 break;
149 default:
150 return EmitError("Unexpected token kind");
151 }
152 return true;
153 }
154
ParseMDObject()155 bool MDParser::ParseMDObject()
156 {
157 if (lexer.NextToken() != kMDIdentifier) {
158 return EmitError("Expect a name after a specific object defined");
159 }
160 StrInfo parentInfo = dataKeeper.GetStrInTable(lexer.GetStrToken());
161 if (parentInfo.idx == UINT_MAX || (parentInfo.sType != kClassName && parentInfo.sType != kAnonClassName)) {
162 return EmitError("A new object should be belong to a defined class");
163 }
164 MDClass parentClass = dataKeeper.GetOneMDClass(parentInfo.idx);
165 unsigned int objectIdx = UINT_MAX;
166 if (!parentClass.IsAnonymousClass()) {
167 if (lexer.NextToken() != kMDColon) {
168 return EmitError("Expect a colon when a object name is going to be defined");
169 }
170 if (lexer.NextToken() != kMDIdentifier) {
171 return EmitError("Expect a name for a specific object");
172 }
173 objectIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kObjectName);
174 if (objectIdx == UINT_MAX) {
175 return EmitError("InValid ObjectName!");
176 }
177 }
178 MDObject *curObj = mdMemPool->New<MDObject>(objectIdx, parentClass, *mdMemPool);
179 if (lexer.NextToken() != kMDOpenBrace) {
180 return EmitError("Expect a OpenBrace before a object body is defined");
181 }
182 if (!ParseMDObjBody(*curObj)) {
183 return false;
184 }
185 dataKeeper.FillMDClass(parentInfo.idx, *curObj);
186 return (lexer.NextToken() == kMDSemi) ? true : EmitError("Expected an ending with a semicolon");
187 }
188
ParseMDObjBody(MDObject & curObj)189 bool MDParser::ParseMDObjBody(MDObject &curObj)
190 {
191 bool hasDefault = false;
192 for (size_t i = 0; i < curObj.GetParentClass()->GetFormalTypeSize(); ++i) {
193 if (hasDefault) {
194 DefaultElement *defaultEle = mdMemPool->New<DefaultElement>();
195 curObj.AddMDElements(defaultEle);
196 continue;
197 }
198 MDTokenKind curKind = lexer.NextToken();
199 if (i != 0 && (curKind != kMDComma && curKind != kMDCloseBrace)) {
200 return EmitError("Unexpected Gramma when define a object");
201 }
202 if (curKind == kMDComma) {
203 curKind = lexer.NextToken();
204 }
205 if (curKind == kMDCloseBrace) {
206 hasDefault = true;
207 DefaultElement *defaultEle = mdMemPool->New<DefaultElement>();
208 curObj.AddMDElements(defaultEle);
209 continue;
210 }
211 unsigned int typeIdx = curObj.GetParentClass()->GetFormalTypes().at(i).first;
212 bool isVec = curObj.GetParentClass()->GetFormalTypes().at(i).second;
213 if (dataKeeper.GetStrTyByIdx(typeIdx) == kIntType) {
214 if (!ParseIntElement(curObj, isVec)) {
215 return false;
216 }
217 } else if (dataKeeper.GetStrTyByIdx(typeIdx) == kStringType) {
218 if (!ParseStrElement(curObj, isVec)) {
219 return false;
220 }
221 } else if (dataKeeper.GetStrTyByIdx(typeIdx) == kTypeName) {
222 std::set<unsigned int> childSet = dataKeeper.GetOneSpcType(typeIdx);
223 if (!ParseDefTyElement(curObj, isVec, childSet)) {
224 return false;
225 }
226 } else if (dataKeeper.GetStrTyByIdx(typeIdx) == kClassName) {
227 MDClass pClass = dataKeeper.GetOneMDClass(typeIdx);
228 if (!ParseDefObjElement(curObj, isVec, pClass)) {
229 return false;
230 }
231 }
232 }
233 if (lexer.GetCurKind() == kMDCloseBrace) {
234 return true;
235 }
236 return (lexer.NextToken() != kMDCloseBrace) ? EmitError("Expect a CloseBrace as end of object definition") : true;
237 }
238
ParseIntElement(MDObject & curObj,bool isVec)239 bool MDParser::ParseIntElement(MDObject &curObj, bool isVec)
240 {
241 if (isVec) {
242 if (lexer.GetCurKind() != kMDOpenSquare) {
243 return EmitError("Expect a OpenSquare before a list element defined");
244 }
245
246 VecElement *curEle = mdMemPool->New<VecElement>(*mdMemPool);
247 while (lexer.NextToken() != kMDCloseSquare) {
248 switch (lexer.GetCurKind()) {
249 case kMDIntVal: {
250 IntElement *singleEle = mdMemPool->New<IntElement>(lexer.GetIntVal());
251 curEle->appendElement(singleEle);
252 break;
253 }
254 case kMDComma:
255 break;
256 default:
257 return EmitError("Unexpected token kind");
258 }
259 }
260 curObj.AddMDElements(curEle);
261 } else {
262 if (lexer.GetCurKind() != kMDIntVal) {
263 return EmitError("Expect a integer elemet as defined");
264 }
265 IntElement *curEle = mdMemPool->New<IntElement>(lexer.GetIntVal());
266 curObj.AddMDElements(curEle);
267 }
268 return true;
269 }
270
ParseStrElement(MDObject & curObj,bool isVec)271 bool MDParser::ParseStrElement(MDObject &curObj, bool isVec)
272 {
273 if (isVec) {
274 if (lexer.GetCurKind() != kMDOpenSquare) {
275 return EmitError("Expect a OpenSquare before a list element defined");
276 }
277 VecElement *curEle = mdMemPool->New<VecElement>(*mdMemPool);
278 while (lexer.NextToken() != kMDCloseSquare) {
279 switch (lexer.GetCurKind()) {
280 case kMDIdentifier: {
281 unsigned int elementIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kElementName);
282 if (elementIdx == UINT_MAX) {
283 return EmitError("Duplicate string name has already been defined");
284 }
285 StringElement *singleEle = mdMemPool->New<StringElement>(elementIdx);
286 curEle->appendElement(singleEle);
287 break;
288 }
289 case kMDComma:
290 break;
291 default:
292 return EmitError("Unexpected token kind");
293 }
294 }
295 curObj.AddMDElements(curEle);
296 } else {
297 if (lexer.GetCurKind() != kMDIdentifier) {
298 return EmitError("Expect a string elemet as defined");
299 }
300 unsigned int elementIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kElementName);
301 if (elementIdx == UINT_MAX) {
302 return EmitError("Duplicate string name has already been defined");
303 }
304 StringElement *curEle = mdMemPool->New<StringElement>(elementIdx);
305 curObj.AddMDElements(curEle);
306 }
307 return true;
308 }
309
ParseDefTyElement(MDObject & curObj,bool isVec,const std::set<unsigned int> & childSet)310 bool MDParser::ParseDefTyElement(MDObject &curObj, bool isVec, const std::set<unsigned int> &childSet)
311 {
312 if (isVec) {
313 if (lexer.GetCurKind() != kMDOpenSquare) {
314 return EmitError("Expect a OpenSquare before a list element defined");
315 }
316 VecElement *curEle = mdMemPool->New<VecElement>(*mdMemPool);
317 while (lexer.NextToken() != kMDCloseSquare) {
318 switch (lexer.GetCurKind()) {
319 case kMDIdentifier: {
320 StrInfo defTypeInfo = dataKeeper.GetStrInTable(lexer.GetStrToken());
321 DefTyElement *singleEle = mdMemPool->New<DefTyElement>();
322 if (!singleEle->SetContent(defTypeInfo, childSet)) {
323 return EmitError("Expect a input element which has been defined as a type");
324 }
325 curEle->appendElement(singleEle);
326 break;
327 }
328 case kMDComma:
329 break;
330 default:
331 return EmitError("Unexpected token kind");
332 }
333 }
334 curObj.AddMDElements(curEle);
335 } else {
336 if (lexer.GetCurKind() != kMDIdentifier) {
337 return EmitError("Expect a string elemet as defined");
338 }
339 StrInfo defTypeInfo = dataKeeper.GetStrInTable(lexer.GetStrToken());
340 DefTyElement *curEle = mdMemPool->New<DefTyElement>();
341 if (!curEle->SetContent(defTypeInfo, childSet)) {
342 return EmitError("Expect a input element which has been defined as a type");
343 }
344 curObj.AddMDElements(curEle);
345 }
346 return true;
347 }
348
ParseDefObjElement(MDObject & curObj,bool isVec,const MDClass & pClass)349 bool MDParser::ParseDefObjElement(MDObject &curObj, bool isVec, const MDClass &pClass)
350 {
351 if (isVec) {
352 if (lexer.GetCurKind() != kMDOpenSquare) {
353 return EmitError("Expect a OpenSquare before a list element defined");
354 }
355 VecElement *curEle = mdMemPool->New<VecElement>(*mdMemPool);
356 while (lexer.NextToken() != kMDCloseSquare) {
357 switch (lexer.GetCurKind()) {
358 case kMDIdentifier: {
359 StrInfo defObjInfo = dataKeeper.GetStrInTable(lexer.GetStrToken());
360 DefObjElement *singleEle = mdMemPool->New<DefObjElement>();
361 if (!singleEle->SetContent(defObjInfo, pClass)) {
362 return EmitError("Expect a input element which has been defined as a object");
363 }
364 curEle->appendElement(singleEle);
365 break;
366 }
367 case kMDComma:
368 break;
369 default:
370 return EmitError("Unexpected token kind");
371 }
372 }
373 curObj.AddMDElements(curEle);
374 } else {
375 if (lexer.GetCurKind() != kMDIdentifier) {
376 return EmitError("Expect a integer elemet as defined");
377 }
378 StrInfo defObjInfo = dataKeeper.GetStrInTable(lexer.GetStrToken());
379 DefObjElement *curEle = mdMemPool->New<DefObjElement>();
380 if (!curEle->SetContent(defObjInfo, pClass)) {
381 return EmitError("Expect a input element which has been defined as a object");
382 }
383 curObj.AddMDElements(curEle);
384 }
385 return true;
386 }
387
EmitError(const std::string & errMsg)388 bool MDParser::EmitError(const std::string &errMsg)
389 {
390 maple::LogInfo::MapleLogger() << errMsg << "\n";
391 maple::LogInfo::MapleLogger() << "A Error Appear At Line " << lexer.GetLineNumber() << "\n";
392 maple::LogInfo::MapleLogger() << "Source code : " << lexer.GetStrLine() << "\n";
393 return false;
394 }
395 } /* namespace MDGen */
396