/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mdparser.h" namespace MDGen { bool MDParser::ParseFile(const std::string &inputFile) { lexer.PrepareFile(inputFile); if (!ParseObjectStart()) { return false; } if (lexer.GetCurKind() == kMDEOF) { return true; } return EmitError("Unexpected input at begin"); } bool MDParser::IsObjectStart(MDTokenKind k) const { return (k == kMDDef || k == kMDClass || k == kMDDefType); } bool MDParser::ParseObjectStart() { while (IsObjectStart(lexer.NextToken())) { if (!ParseObject()) { return false; } } return true; } bool MDParser::ParseObject() { switch (lexer.GetCurKind()) { case kMDDefType: return ParseDefType(); case kMDClass: return ParseMDClass(); case kMDDef: return ParseMDObject(); default: return EmitError("Unexpected key word at start"); } } bool MDParser::ParseDefType() { if (lexer.NextToken() != kMDIdentifier) { return EmitError("Expect a name after a specific type defined"); } unsigned int defTypeIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kTypeName); if (defTypeIdx == UINT_MAX) { return EmitError("InValid defType is defined"); } if (lexer.NextToken() != kMDEqual) { return EmitError("Expect a equal when a specific type is going to be instantiated"); } std::set defTypeMembers; while (lexer.NextToken() != kMDSemi) { switch (lexer.GetCurKind()) { case kMDIdentifier: { unsigned int defTypeMemberIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kTypeMemberName); if (defTypeMemberIdx == UINT_MAX || !defTypeMembers.insert(defTypeMemberIdx).second) { return EmitError("InValid defType member is defined"); } break; } case kMDComma: break; default: return EmitError("Unexpected token kind"); } } dataKeeper.AddDefinedType(defTypeIdx, defTypeMembers); return (lexer.GetCurKind() == kMDSemi) ? true : EmitError("Expected an ending with a semicolon"); } bool MDParser::ParseMDClass() { if (lexer.NextToken() != kMDIdentifier) { return EmitError("Expect a name after a specific class defined"); } unsigned int classIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kClassName); if (classIdx == UINT_MAX) { return EmitError("InValid class name. Please change a class name"); } bool isAnon = true; if (lexer.NextToken() == kMDColon) { isAnon = false; if (lexer.NextToken() != kMDIdentifier) { return EmitError("Expect a name after a specific class defined"); } if (lexer.GetStrToken() != "string") { return EmitError("Only Support string as a class name type at current stage"); } static_cast(lexer.NextToken()); } if (isAnon) { dataKeeper.ModifyStrTyInTable(lexer.GetStrToken(), kAnonClassName); } MDClass oneMDclass(classIdx, isAnon); if (lexer.GetCurKind() != kMDLess) { return EmitError("Expect a 'less' before class structure being defined"); } while (lexer.NextToken() != kMDGreater) { if (!ParseMDClassBody(oneMDclass)) { return false; } } dataKeeper.AddMDClass(oneMDclass); return (lexer.NextToken() == kMDSemi) ? true : EmitError("Expected an ending with a semicolon"); } bool MDParser::ParseMDClassBody(MDClass &oneClass) { switch (lexer.GetCurKind()) { case kMDIdentifier: { StrInfo defTypeInfo = dataKeeper.GetStrInTable(lexer.GetStrToken()); if (defTypeInfo.idx == UINT_MAX || !oneClass.IsValidStructEle(defTypeInfo.sType)) { return EmitError("Expect a defined Type to be a memeber of a class"); } bool isVec = false; if (lexer.ViewNextChar() == '[') { if (lexer.NextToken() != kMDOpenSquare || lexer.NextToken() != kMDCloseSquare) { return EmitError("Expect a \"[]\" to represent a list element"); } isVec = true; } oneClass.BuildFormalTypes(defTypeInfo.idx, isVec); break; } case kMDComma: break; default: return EmitError("Unexpected token kind"); } return true; } bool MDParser::ParseMDObject() { if (lexer.NextToken() != kMDIdentifier) { return EmitError("Expect a name after a specific object defined"); } StrInfo parentInfo = dataKeeper.GetStrInTable(lexer.GetStrToken()); if (parentInfo.idx == UINT_MAX || (parentInfo.sType != kClassName && parentInfo.sType != kAnonClassName)) { return EmitError("A new object should be belong to a defined class"); } MDClass parentClass = dataKeeper.GetOneMDClass(parentInfo.idx); unsigned int objectIdx = UINT_MAX; if (!parentClass.IsAnonymousClass()) { if (lexer.NextToken() != kMDColon) { return EmitError("Expect a colon when a object name is going to be defined"); } if (lexer.NextToken() != kMDIdentifier) { return EmitError("Expect a name for a specific object"); } objectIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kObjectName); if (objectIdx == UINT_MAX) { return EmitError("InValid ObjectName!"); } } MDObject *curObj = mdMemPool->New(objectIdx, parentClass, *mdMemPool); if (lexer.NextToken() != kMDOpenBrace) { return EmitError("Expect a OpenBrace before a object body is defined"); } if (!ParseMDObjBody(*curObj)) { return false; } dataKeeper.FillMDClass(parentInfo.idx, *curObj); return (lexer.NextToken() == kMDSemi) ? true : EmitError("Expected an ending with a semicolon"); } bool MDParser::ParseMDObjBody(MDObject &curObj) { bool hasDefault = false; for (size_t i = 0; i < curObj.GetParentClass()->GetFormalTypeSize(); ++i) { if (hasDefault) { DefaultElement *defaultEle = mdMemPool->New(); curObj.AddMDElements(defaultEle); continue; } MDTokenKind curKind = lexer.NextToken(); if (i != 0 && (curKind != kMDComma && curKind != kMDCloseBrace)) { return EmitError("Unexpected Gramma when define a object"); } if (curKind == kMDComma) { curKind = lexer.NextToken(); } if (curKind == kMDCloseBrace) { hasDefault = true; DefaultElement *defaultEle = mdMemPool->New(); curObj.AddMDElements(defaultEle); continue; } unsigned int typeIdx = curObj.GetParentClass()->GetFormalTypes().at(i).first; bool isVec = curObj.GetParentClass()->GetFormalTypes().at(i).second; if (dataKeeper.GetStrTyByIdx(typeIdx) == kIntType) { if (!ParseIntElement(curObj, isVec)) { return false; } } else if (dataKeeper.GetStrTyByIdx(typeIdx) == kStringType) { if (!ParseStrElement(curObj, isVec)) { return false; } } else if (dataKeeper.GetStrTyByIdx(typeIdx) == kTypeName) { std::set childSet = dataKeeper.GetOneSpcType(typeIdx); if (!ParseDefTyElement(curObj, isVec, childSet)) { return false; } } else if (dataKeeper.GetStrTyByIdx(typeIdx) == kClassName) { MDClass pClass = dataKeeper.GetOneMDClass(typeIdx); if (!ParseDefObjElement(curObj, isVec, pClass)) { return false; } } } if (lexer.GetCurKind() == kMDCloseBrace) { return true; } return (lexer.NextToken() != kMDCloseBrace) ? EmitError("Expect a CloseBrace as end of object definition") : true; } bool MDParser::ParseIntElement(MDObject &curObj, bool isVec) { if (isVec) { if (lexer.GetCurKind() != kMDOpenSquare) { return EmitError("Expect a OpenSquare before a list element defined"); } VecElement *curEle = mdMemPool->New(*mdMemPool); while (lexer.NextToken() != kMDCloseSquare) { switch (lexer.GetCurKind()) { case kMDIntVal: { IntElement *singleEle = mdMemPool->New(lexer.GetIntVal()); curEle->appendElement(singleEle); break; } case kMDComma: break; default: return EmitError("Unexpected token kind"); } } curObj.AddMDElements(curEle); } else { if (lexer.GetCurKind() != kMDIntVal) { return EmitError("Expect a integer elemet as defined"); } IntElement *curEle = mdMemPool->New(lexer.GetIntVal()); curObj.AddMDElements(curEle); } return true; } bool MDParser::ParseStrElement(MDObject &curObj, bool isVec) { if (isVec) { if (lexer.GetCurKind() != kMDOpenSquare) { return EmitError("Expect a OpenSquare before a list element defined"); } VecElement *curEle = mdMemPool->New(*mdMemPool); while (lexer.NextToken() != kMDCloseSquare) { switch (lexer.GetCurKind()) { case kMDIdentifier: { unsigned int elementIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kElementName); if (elementIdx == UINT_MAX) { return EmitError("Duplicate string name has already been defined"); } StringElement *singleEle = mdMemPool->New(elementIdx); curEle->appendElement(singleEle); break; } case kMDComma: break; default: return EmitError("Unexpected token kind"); } } curObj.AddMDElements(curEle); } else { if (lexer.GetCurKind() != kMDIdentifier) { return EmitError("Expect a string elemet as defined"); } unsigned int elementIdx = dataKeeper.CreateStrInTable(lexer.GetStrToken(), kElementName); if (elementIdx == UINT_MAX) { return EmitError("Duplicate string name has already been defined"); } StringElement *curEle = mdMemPool->New(elementIdx); curObj.AddMDElements(curEle); } return true; } bool MDParser::ParseDefTyElement(MDObject &curObj, bool isVec, const std::set &childSet) { if (isVec) { if (lexer.GetCurKind() != kMDOpenSquare) { return EmitError("Expect a OpenSquare before a list element defined"); } VecElement *curEle = mdMemPool->New(*mdMemPool); while (lexer.NextToken() != kMDCloseSquare) { switch (lexer.GetCurKind()) { case kMDIdentifier: { StrInfo defTypeInfo = dataKeeper.GetStrInTable(lexer.GetStrToken()); DefTyElement *singleEle = mdMemPool->New(); if (!singleEle->SetContent(defTypeInfo, childSet)) { return EmitError("Expect a input element which has been defined as a type"); } curEle->appendElement(singleEle); break; } case kMDComma: break; default: return EmitError("Unexpected token kind"); } } curObj.AddMDElements(curEle); } else { if (lexer.GetCurKind() != kMDIdentifier) { return EmitError("Expect a string elemet as defined"); } StrInfo defTypeInfo = dataKeeper.GetStrInTable(lexer.GetStrToken()); DefTyElement *curEle = mdMemPool->New(); if (!curEle->SetContent(defTypeInfo, childSet)) { return EmitError("Expect a input element which has been defined as a type"); } curObj.AddMDElements(curEle); } return true; } bool MDParser::ParseDefObjElement(MDObject &curObj, bool isVec, const MDClass &pClass) { if (isVec) { if (lexer.GetCurKind() != kMDOpenSquare) { return EmitError("Expect a OpenSquare before a list element defined"); } VecElement *curEle = mdMemPool->New(*mdMemPool); while (lexer.NextToken() != kMDCloseSquare) { switch (lexer.GetCurKind()) { case kMDIdentifier: { StrInfo defObjInfo = dataKeeper.GetStrInTable(lexer.GetStrToken()); DefObjElement *singleEle = mdMemPool->New(); if (!singleEle->SetContent(defObjInfo, pClass)) { return EmitError("Expect a input element which has been defined as a object"); } curEle->appendElement(singleEle); break; } case kMDComma: break; default: return EmitError("Unexpected token kind"); } } curObj.AddMDElements(curEle); } else { if (lexer.GetCurKind() != kMDIdentifier) { return EmitError("Expect a integer elemet as defined"); } StrInfo defObjInfo = dataKeeper.GetStrInTable(lexer.GetStrToken()); DefObjElement *curEle = mdMemPool->New(); if (!curEle->SetContent(defObjInfo, pClass)) { return EmitError("Expect a input element which has been defined as a object"); } curObj.AddMDElements(curEle); } return true; } bool MDParser::EmitError(const std::string &errMsg) { maple::LogInfo::MapleLogger() << errMsg << "\n"; maple::LogInfo::MapleLogger() << "A Error Appear At Line " << lexer.GetLineNumber() << "\n"; maple::LogInfo::MapleLogger() << "Source code : " << lexer.GetStrLine() << "\n"; return false; } } /* namespace MDGen */