Recognize script numeric and int values as strings

This commit is contained in:
Jan 2021-11-20 12:01:04 +01:00
parent ed329e6453
commit ef1ad18332
5 changed files with 110 additions and 14 deletions

View File

@ -0,0 +1,29 @@
#include "MenuMatcherScriptInt.h"
MenuMatcherScriptInt::MenuMatcherScriptInt()
= default;
MatcherResult<SimpleParserValue> MenuMatcherScriptInt::CanMatch(ILexer<SimpleParserValue>*lexer, const unsigned tokenOffset)
{
const auto& token = lexer->GetToken(tokenOffset);
if (token.m_type == SimpleParserValueType::INTEGER)
return MatcherResult<SimpleParserValue>::Match(1);
if (token.m_type != SimpleParserValueType::STRING)
return MatcherResult<SimpleParserValue>::NoMatch();
const auto& stringValue = token.StringValue();
if (stringValue.empty())
return MatcherResult<SimpleParserValue>::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<SimpleParserValue>::NoMatch();
return MatcherResult<SimpleParserValue>::Match(1);
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "Parsing/Simple/SimpleParserValue.h"
#include "Parsing/Matcher/AbstractMatcher.h"
class MenuMatcherScriptInt final : public AbstractMatcher<SimpleParserValue>
{
protected:
MatcherResult<SimpleParserValue> CanMatch(ILexer<SimpleParserValue>* lexer, unsigned tokenOffset) override;
public:
MenuMatcherScriptInt();
};

View File

@ -0,0 +1,29 @@
#include "MenuMatcherScriptNumeric.h"
MenuMatcherScriptNumeric::MenuMatcherScriptNumeric()
= default;
MatcherResult<SimpleParserValue> MenuMatcherScriptNumeric::CanMatch(ILexer<SimpleParserValue>* lexer, const unsigned tokenOffset)
{
const auto& token = lexer->GetToken(tokenOffset);
if (token.m_type == SimpleParserValueType::FLOATING_POINT || token.m_type == SimpleParserValueType::INTEGER)
return MatcherResult<SimpleParserValue>::Match(1);
if (token.m_type != SimpleParserValueType::STRING)
return MatcherResult<SimpleParserValue>::NoMatch();
const auto& stringValue = token.StringValue();
if (stringValue.empty())
return MatcherResult<SimpleParserValue>::NoMatch();
char* endPtr;
// The return result does not matter here
const auto _ = strtod(&stringValue[0], &endPtr);
if(endPtr != &stringValue[stringValue.size()])
return MatcherResult<SimpleParserValue>::NoMatch();
return MatcherResult<SimpleParserValue>::Match(1);
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "Parsing/Simple/SimpleParserValue.h"
#include "Parsing/Matcher/AbstractMatcher.h"
class MenuMatcherScriptNumeric final : public AbstractMatcher<SimpleParserValue>
{
protected:
MatcherResult<SimpleParserValue> CanMatch(ILexer<SimpleParserValue>* lexer, unsigned tokenOffset) override;
public:
MenuMatcherScriptNumeric();
};

View File

@ -9,6 +9,8 @@
#include "Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.h" #include "Parsing/Menu/Domain/EventHandler/CommonEventHandlerSetLocalVar.h"
#include "Parsing/Menu/Matcher/MenuCommonMatchers.h" #include "Parsing/Menu/Matcher/MenuCommonMatchers.h"
#include "Parsing/Menu/Matcher/MenuMatcherFactory.h" #include "Parsing/Menu/Matcher/MenuMatcherFactory.h"
#include "Parsing/Menu/Matcher/MenuMatcherScriptInt.h"
#include "Parsing/Menu/Matcher/MenuMatcherScriptNumeric.h"
using namespace menu; using namespace menu;
@ -31,16 +33,16 @@ namespace menu
_NODISCARD MatcherFactoryWrapper<SimpleParserValue> ScriptStrictNumeric() const _NODISCARD MatcherFactoryWrapper<SimpleParserValue> ScriptStrictNumeric() const
{ {
return Or({ return And({
Type(SimpleParserValueType::INTEGER).Transform([](const token_list_t& tokens)-> SimpleParserValue MatcherFactoryWrapper<SimpleParserValue>(std::make_unique<MenuMatcherScriptNumeric>()).Transform([](const token_list_t& tokens)-> SimpleParserValue
{ {
const auto& firstToken = tokens[0].get(); const auto& firstToken = tokens[0].get();
return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.IntegerValue())));
}), if (firstToken.m_type == SimpleParserValueType::INTEGER)
Type(SimpleParserValueType::FLOATING_POINT).Transform([](const token_list_t& tokens)-> SimpleParserValue return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.IntegerValue())));
{ if (firstToken.m_type == SimpleParserValueType::FLOATING_POINT)
const auto& firstToken = tokens[0].get(); return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.FloatingPointValue())));
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), Type(SimpleParserValueType::IDENTIFIER),
}).Transform([](const token_list_t& tokens) -> SimpleParserValue }).Transform([](const token_list_t& tokens) -> SimpleParserValue
{ {
return SimpleParserValue::Integer(tokens[0].get().GetPos(), static_cast<int>(ExpectedScriptToken::INT)); return SimpleParserValue::Integer(tokens[0].get().GetPos(), static_cast<int>(ExpectedScriptToken::NUMERIC));
}) })
}); });
} }
_NODISCARD MatcherFactoryWrapper<SimpleParserValue> ScriptStrictInt() const
{
return And({
MatcherFactoryWrapper<SimpleParserValue>(std::make_unique<MenuMatcherScriptInt>()).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<SimpleParserValue> ScriptInt() const _NODISCARD MatcherFactoryWrapper<SimpleParserValue> ScriptInt() const
{ {
return Or({ return Or({
Type(SimpleParserValueType::INTEGER).Transform([](const token_list_t& tokens)-> SimpleParserValue ScriptStrictInt(),
{
const auto& firstToken = tokens[0].get();
return SimpleParserValue::String(firstToken.GetPos(), new std::string(std::to_string(firstToken.IntegerValue())));
}),
Or({ Or({
Type(SimpleParserValueType::CHARACTER), Type(SimpleParserValueType::CHARACTER),
Type(SimpleParserValueType::FLOATING_POINT), Type(SimpleParserValueType::FLOATING_POINT),