From ef1ad18332966afbf1755439f5473f1a752e8767 Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 20 Nov 2021 12:01:04 +0100 Subject: [PATCH] Recognize script numeric and int values as strings --- .../Menu/Matcher/MenuMatcherScriptInt.cpp | 29 ++++++++++++++ .../Menu/Matcher/MenuMatcherScriptInt.h | 13 ++++++ .../Menu/Matcher/MenuMatcherScriptNumeric.cpp | 29 ++++++++++++++ .../Menu/Matcher/MenuMatcherScriptNumeric.h | 13 ++++++ .../EventHandlerSetScopeSequences.cpp | 40 ++++++++++++------- 5 files changed, 110 insertions(+), 14 deletions(-) create mode 100644 src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptInt.cpp create mode 100644 src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptInt.h create mode 100644 src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptNumeric.cpp create mode 100644 src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptNumeric.h diff --git a/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptInt.cpp b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptInt.cpp new file mode 100644 index 00000000..1f45f84b --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptInt.cpp @@ -0,0 +1,29 @@ +#include "MenuMatcherScriptInt.h" + +MenuMatcherScriptInt::MenuMatcherScriptInt() += default; + +MatcherResult MenuMatcherScriptInt::CanMatch(ILexer*lexer, const unsigned tokenOffset) +{ + const auto& token = lexer->GetToken(tokenOffset); + + if (token.m_type == SimpleParserValueType::INTEGER) + return MatcherResult::Match(1); + + if (token.m_type != SimpleParserValueType::STRING) + return MatcherResult::NoMatch(); + + const auto& stringValue = token.StringValue(); + + if (stringValue.empty()) + return MatcherResult::NoMatch(); + + char* endPtr; + // The return result does not matter here + const auto _ = strtol(&stringValue[0], &endPtr, 10); + + if (endPtr != &stringValue[stringValue.size() - 1]) + return MatcherResult::NoMatch(); + + return MatcherResult::Match(1); +} diff --git a/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptInt.h b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptInt.h new file mode 100644 index 00000000..e6ed7e54 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptInt.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Parsing/Simple/SimpleParserValue.h" +#include "Parsing/Matcher/AbstractMatcher.h" + +class MenuMatcherScriptInt final : public AbstractMatcher +{ +protected: + MatcherResult CanMatch(ILexer* lexer, unsigned tokenOffset) override; + +public: + MenuMatcherScriptInt(); +}; diff --git a/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptNumeric.cpp b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptNumeric.cpp new file mode 100644 index 00000000..5ca14e43 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptNumeric.cpp @@ -0,0 +1,29 @@ +#include "MenuMatcherScriptNumeric.h" + +MenuMatcherScriptNumeric::MenuMatcherScriptNumeric() += default; + +MatcherResult MenuMatcherScriptNumeric::CanMatch(ILexer* lexer, const unsigned tokenOffset) +{ + const auto& token = lexer->GetToken(tokenOffset); + + if (token.m_type == SimpleParserValueType::FLOATING_POINT || token.m_type == SimpleParserValueType::INTEGER) + return MatcherResult::Match(1); + + if (token.m_type != SimpleParserValueType::STRING) + return MatcherResult::NoMatch(); + + const auto& stringValue = token.StringValue(); + + if (stringValue.empty()) + return MatcherResult::NoMatch(); + + char* endPtr; + // The return result does not matter here + const auto _ = strtod(&stringValue[0], &endPtr); + + if(endPtr != &stringValue[stringValue.size()]) + return MatcherResult::NoMatch(); + + return MatcherResult::Match(1); +} diff --git a/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptNumeric.h b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptNumeric.h new file mode 100644 index 00000000..e9325b29 --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherScriptNumeric.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Parsing/Simple/SimpleParserValue.h" +#include "Parsing/Matcher/AbstractMatcher.h" + +class MenuMatcherScriptNumeric final : public AbstractMatcher +{ +protected: + MatcherResult CanMatch(ILexer* lexer, unsigned tokenOffset) override; + +public: + MenuMatcherScriptNumeric(); +}; diff --git a/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.cpp b/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.cpp index b70ff9d2..e1f25029 100644 --- a/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.cpp +++ b/src/ObjLoading/Parsing/Menu/Sequence/EventHandlerSetScopeSequences.cpp @@ -9,6 +9,8 @@ #include "Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.h" #include "Parsing/Menu/Matcher/MenuCommonMatchers.h" #include "Parsing/Menu/Matcher/MenuMatcherFactory.h" +#include "Parsing/Menu/Matcher/MenuMatcherScriptInt.h" +#include "Parsing/Menu/Matcher/MenuMatcherScriptNumeric.h" using namespace menu; @@ -31,16 +33,16 @@ namespace menu _NODISCARD MatcherFactoryWrapper ScriptStrictNumeric() const { - return Or({ - Type(SimpleParserValueType::INTEGER).Transform([](const token_list_t& tokens)-> SimpleParserValue + return And({ + MatcherFactoryWrapper(std::make_unique()).Transform([](const token_list_t& tokens)-> SimpleParserValue { const auto& firstToken = tokens[0].get(); - return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.IntegerValue()))); - }), - Type(SimpleParserValueType::FLOATING_POINT).Transform([](const token_list_t& tokens)-> SimpleParserValue - { - const auto& firstToken = tokens[0].get(); - return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.FloatingPointValue()))); + + if (firstToken.m_type == SimpleParserValueType::INTEGER) + return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.IntegerValue()))); + if (firstToken.m_type == SimpleParserValueType::FLOATING_POINT) + return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.FloatingPointValue()))); + return SimpleParserValue::String(firstToken.GetPos(), new std::string(firstToken.StringValue())); }) }); } @@ -55,19 +57,29 @@ namespace menu Type(SimpleParserValueType::IDENTIFIER), }).Transform([](const token_list_t& tokens) -> SimpleParserValue { - return SimpleParserValue::Integer(tokens[0].get().GetPos(), static_cast(ExpectedScriptToken::INT)); + return SimpleParserValue::Integer(tokens[0].get().GetPos(), static_cast(ExpectedScriptToken::NUMERIC)); }) }); } + _NODISCARD MatcherFactoryWrapper ScriptStrictInt() const + { + return And({ + MatcherFactoryWrapper(std::make_unique()).Transform([](const token_list_t& tokens)-> SimpleParserValue + { + const auto& firstToken = tokens[0].get(); + + if (firstToken.m_type == SimpleParserValueType::INTEGER) + return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.IntegerValue()))); + return SimpleParserValue::String(firstToken.GetPos(), new std::string(firstToken.StringValue())); + }) + }); + } + _NODISCARD MatcherFactoryWrapper ScriptInt() const { return Or({ - Type(SimpleParserValueType::INTEGER).Transform([](const token_list_t& tokens)-> SimpleParserValue - { - const auto& firstToken = tokens[0].get(); - return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.IntegerValue()))); - }), + ScriptStrictInt(), Or({ Type(SimpleParserValueType::CHARACTER), Type(SimpleParserValueType::FLOATING_POINT),