diff --git a/plugins/libimhex/include/hex/pattern_language/ast_node.hpp b/plugins/libimhex/include/hex/pattern_language/ast_node.hpp index 8b5789510..45f2a5e4f 100644 --- a/plugins/libimhex/include/hex/pattern_language/ast_node.hpp +++ b/plugins/libimhex/include/hex/pattern_language/ast_node.hpp @@ -346,17 +346,10 @@ namespace hex::pl { ASTNodeTypeDecl(const ASTNodeTypeDecl& other) : ASTNode(other), Attributable(other) { this->m_name = other.m_name; - if (other.m_type != nullptr) - this->m_type = other.m_type->clone(); - else - this->m_type = nullptr; + this->m_type = other.m_type; this->m_endian = other.m_endian; } - ~ASTNodeTypeDecl() override { - delete this->m_type; - } - [[nodiscard]] ASTNode* clone() const override { return new ASTNodeTypeDecl(*this); } diff --git a/plugins/libimhex/include/hex/pattern_language/parser.hpp b/plugins/libimhex/include/hex/pattern_language/parser.hpp index 4b5adfbf9..5f9a8f2fd 100644 --- a/plugins/libimhex/include/hex/pattern_language/parser.hpp +++ b/plugins/libimhex/include/hex/pattern_language/parser.hpp @@ -117,6 +117,8 @@ namespace hex::pl { std::vector parseNamespace(); std::vector parseStatements(); + ASTNodeTypeDecl* addType(const std::string &name, ASTNode *node, std::optional endian = std::nullopt); + std::vector parseTillToken(Token::Type endTokenType, const auto value) { std::vector program; auto guard = SCOPE_GUARD { diff --git a/plugins/libimhex/source/pattern_language/parser.cpp b/plugins/libimhex/source/pattern_language/parser.cpp index 601413eae..d2a791510 100644 --- a/plugins/libimhex/source/pattern_language/parser.cpp +++ b/plugins/libimhex/source/pattern_language/parser.cpp @@ -684,7 +684,7 @@ namespace hex::pl { auto *type = dynamic_cast(parseType()); if (type == nullptr) throwParseError("invalid type used in variable declaration", -1); - return create(new ASTNodeTypeDecl(name, type, type->getEndian())); + return addType(name, type, type->getEndian()); } // padding[(parseMathematicalExpression)] @@ -707,14 +707,14 @@ namespace hex::pl { auto variableCleanup = SCOPE_GUARD { for (auto var : variables) delete var; }; do { - variables.push_back(create(new ASTNodeVariableDecl(getValue(-1).get(), type->clone()))); + variables.push_back(create(new ASTNodeVariableDecl(getValue(-1).get(), type))); } while (MATCHES(sequence(SEPARATOR_COMMA, IDENTIFIER))); variableCleanup.release(); return create(new ASTNodeMultiVariableDecl(variables)); } else - return create(new ASTNodeVariableDecl(getValue(-1).get(), type->clone())); + return create(new ASTNodeVariableDecl(getValue(-1).get(), type)); } // (parseType) Identifier[(parseMathematicalExpression)] @@ -736,7 +736,7 @@ namespace hex::pl { sizeCleanup.release(); - return create(new ASTNodeArrayVariableDecl(name, type->clone(), size)); + return create(new ASTNodeArrayVariableDecl(name, type, size)); } // (parseType) *Identifier : (parseType) @@ -752,7 +752,7 @@ namespace hex::pl { throwParseError("invalid type used for pointer size", -1); } - return create(new ASTNodePointerVariableDecl(name, type->clone(), sizeType)); + return create(new ASTNodePointerVariableDecl(name, type, sizeType)); } // [(parsePadding)|(parseMemberVariable)|(parseMemberArrayVariable)|(parseMemberPointerVariable)] @@ -764,7 +764,6 @@ namespace hex::pl { // Some kind of variable definition auto type = parseType(); - ON_SCOPE_EXIT { delete type; }; if (MATCHES(sequence(IDENTIFIER, SEPARATOR_SQUAREBRACKETOPEN)) && sequence(SEPARATOR_SQUAREBRACKETOPEN)) member = parseMemberArrayVariable(type); @@ -798,9 +797,11 @@ namespace hex::pl { // struct Identifier { <(parseMember)...> } ASTNode* Parser::parseStruct() { - const auto structNode = create(new ASTNodeStruct()); const auto &typeName = getValue(-1).get(); - auto structGuard = SCOPE_GUARD { delete structNode; }; + + const auto structNode = create(new ASTNodeStruct()); + const auto typeDecl = addType(typeName, structNode); + auto structGuard = SCOPE_GUARD { delete structNode; delete typeDecl; }; if (MATCHES(sequence(OPERATOR_INHERIT, IDENTIFIER))) { // Inheritance @@ -826,14 +827,16 @@ namespace hex::pl { structGuard.release(); - return create(new ASTNodeTypeDecl(typeName, structNode)); + return typeDecl; } // union Identifier { <(parseMember)...> } ASTNode* Parser::parseUnion() { - const auto unionNode = create(new ASTNodeUnion()); const auto &typeName = getValue(-2).get(); - auto unionGuard = SCOPE_GUARD { delete unionNode; }; + + const auto unionNode = create(new ASTNodeUnion()); + const auto typeDecl = addType(typeName, unionNode); + auto unionGuard = SCOPE_GUARD { delete unionNode; delete typeDecl; }; while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { unionNode->addMember(parseMember()); @@ -841,7 +844,7 @@ namespace hex::pl { unionGuard.release(); - return create(new ASTNodeTypeDecl(typeName, unionNode)); + return typeDecl; } // enum Identifier : (parseType) { <...> } @@ -852,7 +855,8 @@ namespace hex::pl { if (underlyingType->getEndian().has_value()) throwParseError("underlying type may not have an endian specification", -2); const auto enumNode = create(new ASTNodeEnum(underlyingType)); - auto enumGuard = SCOPE_GUARD { delete enumNode; }; + const auto typeDecl = addType(typeName, enumNode); + auto enumGuard = SCOPE_GUARD { delete enumNode; delete typeDecl; }; if (!MATCHES(sequence(SEPARATOR_CURLYBRACKETOPEN))) throwParseError("expected '{' after enum definition", -1); @@ -891,7 +895,7 @@ namespace hex::pl { enumGuard.release(); - return create(new ASTNodeTypeDecl(typeName, enumNode)); + return typeDecl; } // bitfield Identifier { } @@ -899,7 +903,9 @@ namespace hex::pl { std::string typeName = getValue(-2).get(); const auto bitfieldNode = create(new ASTNodeBitfield()); - auto enumGuard = SCOPE_GUARD { delete bitfieldNode; }; + const auto typeDecl = addType(typeName, bitfieldNode); + + auto enumGuard = SCOPE_GUARD { delete bitfieldNode; delete typeDecl; }; while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { if (MATCHES(sequence(IDENTIFIER, OPERATOR_INHERIT))) { @@ -920,7 +926,7 @@ namespace hex::pl { enumGuard.release(); - return create(new ASTNodeTypeDecl(typeName, bitfieldNode)); + return typeDecl; } // (parseType) Identifier @ Integer @@ -1075,19 +1081,21 @@ namespace hex::pl { // Consume superfluous semicolons while (MATCHES(sequence(SEPARATOR_ENDOFEXPRESSION))); - if (auto typeDecl = dynamic_cast(statement); typeDecl != nullptr) { - auto typeName = getNamespacePrefixedName(typeDecl->getName()); - - if (this->m_types.contains(typeName)) - throwParseError(hex::format("redefinition of type '{}'", typeName)); - - typeDecl->setName(typeName); - this->m_types.insert({ typeName, typeDecl }); - } - return { statement }; } + ASTNodeTypeDecl* Parser::addType(const std::string &name, ASTNode *node, std::optional endian) { + auto typeName = getNamespacePrefixedName(name); + + if (this->m_types.contains(typeName)) + throwParseError(hex::format("redefinition of type '{}'", typeName)); + + auto typeDecl = create(new ASTNodeTypeDecl(typeName, node, endian)); + this->m_types.insert({ typeName, typeDecl }); + + return typeDecl; + } + // <(parseNamespace)...> EndOfProgram std::optional> Parser::parse(const std::vector &tokens) { this->m_curr = tokens.begin();