From fcfaaacdcc0050e869839fe02ed80f167d8c8bb0 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Fri, 3 Sep 2021 02:33:45 +0200 Subject: [PATCH] patterns: Fix enum constant resolution --- plugins/libimhex/include/hex/lang/parser.hpp | 3 +- plugins/libimhex/include/hex/lang/token.hpp | 2 - plugins/libimhex/source/lang/lexer.cpp | 3 -- plugins/libimhex/source/lang/parser.cpp | 46 +++++++++++++++----- 4 files changed, 38 insertions(+), 16 deletions(-) diff --git a/plugins/libimhex/include/hex/lang/parser.hpp b/plugins/libimhex/include/hex/lang/parser.hpp index 808160365..9ea58e626 100644 --- a/plugins/libimhex/include/hex/lang/parser.hpp +++ b/plugins/libimhex/include/hex/lang/parser.hpp @@ -64,7 +64,8 @@ namespace hex::lang { ASTNode* parseFunctionCall(); ASTNode* parseStringLiteral(); - std::string parseScopeResolution(); + std::string parseNamespaceResolution(); + ASTNode* parseScopeResolution(); ASTNode* parseRValue(ASTNodeRValue::Path &path); ASTNode* parseFactor(); ASTNode* parseUnaryExpression(); diff --git a/plugins/libimhex/include/hex/lang/token.hpp b/plugins/libimhex/include/hex/lang/token.hpp index bb9f74c41..44e12bfb2 100644 --- a/plugins/libimhex/include/hex/lang/token.hpp +++ b/plugins/libimhex/include/hex/lang/token.hpp @@ -104,7 +104,6 @@ namespace hex::lang { SquareBracketClose, Comma, Dot, - ScopeResolution, EndOfExpression, EndOfProgram }; @@ -260,6 +259,5 @@ namespace hex::lang { #define SEPARATOR_SQUAREBRACKETCLOSE COMPONENT(Separator, SquareBracketClose) #define SEPARATOR_COMMA COMPONENT(Separator, Comma) #define SEPARATOR_DOT COMPONENT(Separator, Dot) -#define SEPARATOR_SCOPE_RESOLUTION COMPONENT(Separator, ScopeResolution) #define SEPARATOR_ENDOFEXPRESSION COMPONENT(Separator, EndOfExpression) #define SEPARATOR_ENDOFPROGRAM COMPONENT(Separator, EndOfProgram) \ No newline at end of file diff --git a/plugins/libimhex/source/lang/lexer.cpp b/plugins/libimhex/source/lang/lexer.cpp index 89aa5f11c..15d20f811 100644 --- a/plugins/libimhex/source/lang/lexer.cpp +++ b/plugins/libimhex/source/lang/lexer.cpp @@ -314,9 +314,6 @@ namespace hex::lang { } else if (c == '=') { tokens.emplace_back(TOKEN(Operator, Assignment)); offset += 1; - } else if (code.substr(offset, 2) == "::") { - tokens.emplace_back(TOKEN(Separator, ScopeResolution)); - offset += 2; } else if (c == ':') { tokens.emplace_back(TOKEN(Operator, Inherit)); offset += 1; diff --git a/plugins/libimhex/source/lang/parser.cpp b/plugins/libimhex/source/lang/parser.cpp index 03a1573d4..9ac137e55 100644 --- a/plugins/libimhex/source/lang/parser.cpp +++ b/plugins/libimhex/source/lang/parser.cpp @@ -21,7 +21,7 @@ namespace hex::lang { // Identifier([(parseMathematicalExpression)|<(parseMathematicalExpression),...>(parseMathematicalExpression)] ASTNode* Parser::parseFunctionCall() { - std::string functionName = parseScopeResolution(); + std::string functionName = parseNamespaceResolution(); if (!MATCHES(sequence(SEPARATOR_ROUNDBRACKETOPEN))) throwParseError("expected '(' after function name"); @@ -56,7 +56,7 @@ namespace hex::lang { return new ASTNodeStringLiteral(getValue(-1)); } - std::string Parser::parseScopeResolution() { + std::string Parser::parseNamespaceResolution() { std::string name; while (true) { @@ -73,6 +73,27 @@ namespace hex::lang { return name; } + ASTNode* Parser::parseScopeResolution() { + std::string typeName; + + while (true) { + typeName += getValue(-1); + + if (MATCHES(sequence(OPERATOR_SCOPERESOLUTION, IDENTIFIER))) { + if (peek(OPERATOR_SCOPERESOLUTION, 0) && peek(IDENTIFIER, 1)) { + typeName += "::"; + continue; + } else { + return new ASTNodeScopeResolution({ typeName, getValue(-1) }); + } + } + else + break; + } + + throwParseError("failed to parse scope resolution. Expected 'TypeName::Identifier'"); + } + // ASTNode* Parser::parseRValue(ASTNodeRValue::Path &path) { if (peek(IDENTIFIER, -1)) @@ -108,14 +129,16 @@ namespace hex::lang { return node; } else if (MATCHES(sequence(IDENTIFIER))) { auto originalPos = this->m_curr; - parseScopeResolution(); + parseNamespaceResolution(); bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN); this->m_curr = originalPos; + if (isFunction) { - return TO_NUMERIC_EXPRESSION(parseFunctionCall()); - } - else { + return TO_NUMERIC_EXPRESSION(this->parseFunctionCall()); + } else if (peek(OPERATOR_SCOPERESOLUTION, 0)) { + return TO_NUMERIC_EXPRESSION(this->parseScopeResolution()); + } else { ASTNodeRValue::Path path; return TO_NUMERIC_EXPRESSION(this->parseRValue(path)); } @@ -431,7 +454,7 @@ namespace hex::lang { needsSemicolon = false; } else if (MATCHES(sequence(IDENTIFIER))) { auto originalPos = this->m_curr; - parseScopeResolution(); + parseNamespaceResolution(); bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN); this->m_curr = originalPos; @@ -598,7 +621,7 @@ namespace hex::lang { endian = std::endian::big; if (MATCHES(sequence(IDENTIFIER))) { // Custom type - std::string typeName = parseScopeResolution(); + std::string typeName = parseNamespaceResolution(); if (this->m_types.contains(typeName)) return new ASTNodeTypeDecl({ }, this->m_types[typeName]->clone(), endian); @@ -768,7 +791,7 @@ namespace hex::lang { // enum Identifier : (parseType) { <...> } ASTNode* Parser::parseEnum() { - auto typeName = getNamespacePrefixedName(getValue(-2)); + auto typeName = getValue(-2); auto underlyingType = parseType(); if (underlyingType->getEndian().has_value()) throwParseError("underlying type may not have an endian specification", -2); @@ -779,6 +802,9 @@ namespace hex::lang { if (this->m_types.contains(typeName)) throwParseError(hex::format("redefinition of type '{}'", typeName)); + if (!MATCHES(sequence(SEPARATOR_CURLYBRACKETOPEN))) + throwParseError("expected '{' after enum definition", -1); + ASTNode *lastEntry = nullptr; while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) { if (MATCHES(sequence(IDENTIFIER, OPERATOR_ASSIGNMENT))) { @@ -962,7 +988,7 @@ namespace hex::lang { else if (peek(IDENTIFIER)) { auto originalPos = this->m_curr; this->m_curr++; - parseScopeResolution(); + parseNamespaceResolution(); bool isFunction = peek(SEPARATOR_ROUNDBRACKETOPEN); this->m_curr = originalPos;