From 7da8a5b1d88bd28f9d5dccd59272a2d462a99507 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sun, 26 Sep 2021 18:27:18 +0200 Subject: [PATCH] patterns: Unified expression body parsing --- .../include/hex/pattern_language/ast_node.hpp | 5 +- .../include/hex/pattern_language/parser.hpp | 1 + .../source/pattern_language/parser.cpp | 54 +++++++++++-------- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/plugins/libimhex/include/hex/pattern_language/ast_node.hpp b/plugins/libimhex/include/hex/pattern_language/ast_node.hpp index dbe994d03..b9b0ab808 100644 --- a/plugins/libimhex/include/hex/pattern_language/ast_node.hpp +++ b/plugins/libimhex/include/hex/pattern_language/ast_node.hpp @@ -481,6 +481,9 @@ namespace hex::pl { ASTNodeWhileStatement(const ASTNodeWhileStatement &other) : ASTNode(other) { this->m_condition = other.m_condition->clone(); + + for (auto &statement : other.m_body) + this->m_body.push_back(statement->clone()); } [[nodiscard]] ASTNode* clone() const override { @@ -1377,7 +1380,7 @@ namespace hex::pl { continue; } else { bool found = false; - for (const auto &variable : searchScope | std::views::reverse) { + for (const auto &variable : (searchScope | std::views::reverse)) { if (variable->getVariableName() == name) { auto newPattern = variable->clone(); delete currPattern; diff --git a/plugins/libimhex/include/hex/pattern_language/parser.hpp b/plugins/libimhex/include/hex/pattern_language/parser.hpp index 5f9a8f2fd..0011d7697 100644 --- a/plugins/libimhex/include/hex/pattern_language/parser.hpp +++ b/plugins/libimhex/include/hex/pattern_language/parser.hpp @@ -93,6 +93,7 @@ namespace hex::pl { ASTNode* parseFunctionStatement(); ASTNode* parseFunctionVariableAssignment(); ASTNode* parseFunctionReturnStatement(); + std::vector parseStatementBody(); ASTNode* parseFunctionConditional(); ASTNode* parseFunctionWhileLoop(); diff --git a/plugins/libimhex/source/pattern_language/parser.cpp b/plugins/libimhex/source/pattern_language/parser.cpp index d2a791510..eff67fa41 100644 --- a/plugins/libimhex/source/pattern_language/parser.cpp +++ b/plugins/libimhex/source/pattern_language/parser.cpp @@ -533,6 +533,27 @@ namespace hex::pl { return create(new ASTNodeReturnStatement(this->parseMathematicalExpression())); } + std::vector Parser::parseStatementBody() { + std::vector body; + + auto bodyCleanup = SCOPE_GUARD { + for (auto &node : body) + delete node; + }; + + if (MATCHES(sequence(SEPARATOR_CURLYBRACKETOPEN))) { + while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { + body.push_back(parseFunctionStatement()); + } + } else { + body.push_back(parseFunctionStatement()); + } + + bodyCleanup.release(); + + return body; + } + ASTNode* Parser::parseFunctionConditional() { auto condition = parseMathematicalExpression(); std::vector trueBody, falseBody; @@ -545,22 +566,13 @@ namespace hex::pl { delete statement; }; - if (MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE, SEPARATOR_CURLYBRACKETOPEN))) { - while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { - trueBody.push_back(parseFunctionStatement()); - } - } else if (MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE))) { - trueBody.push_back(parseFunctionStatement()); - } else - throwParseError("expected body of conditional statement"); + if (!MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE))) + throwParseError("expected closing ')' after statement head"); - if (MATCHES(sequence(KEYWORD_ELSE, SEPARATOR_CURLYBRACKETOPEN))) { - while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { - falseBody.push_back(parseFunctionStatement()); - } - } else if (MATCHES(sequence(KEYWORD_ELSE))) { - falseBody.push_back(parseFunctionStatement()); - } + trueBody = parseStatementBody(); + + if (MATCHES(sequence(KEYWORD_ELSE))) + falseBody = parseStatementBody(); cleanup.release(); @@ -577,14 +589,10 @@ namespace hex::pl { delete statement; }; - if (MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE, SEPARATOR_CURLYBRACKETOPEN))) { - while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { - body.push_back(parseFunctionStatement()); - } - } else if (MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE))) { - body.push_back(parseFunctionStatement()); - } else - throwParseError("expected body of conditional statement"); + if (!MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE))) + throwParseError("expected closing ')' after statement head"); + + body = parseStatementBody(); cleanup.release();