2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-09-04 07:47:25 +00:00

Use custom parser values instead of simple parser values for parsing Zone definitions

This commit is contained in:
Jan
2021-03-20 14:07:48 +01:00
parent ef36d6cdc5
commit 5e08469635
27 changed files with 431 additions and 174 deletions

View File

@@ -1,61 +0,0 @@
#include "ZoneDefinitionCommonMatchers.h"
#include <sstream>
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
std::unique_ptr<ZoneDefinitionCommonMatchers::matcher_t> ZoneDefinitionCommonMatchers::AssetName(const supplier_t* labelSupplier)
{
const SimpleMatcherFactory create(labelSupplier);
return create.And({
create.Loop(create.Or({
create.Identifier(),
create.AnyCharBesides({',', '<', '>', '"', '\\', '*', '?', '|', ':'})
})),
create.Or({
create.Type(SimpleParserValueType::NEW_LINE),
create.Type(SimpleParserValueType::END_OF_FILE)
}).NoConsume()
}).Transform([](SimpleMatcherFactory::token_list_t& tokens)
{
std::ostringstream str;
auto previousType = SimpleParserValueType::INVALID;
auto previousCharacterWasSlash = false;
for (const auto& token : tokens)
{
switch (token.get().m_type)
{
case SimpleParserValueType::IDENTIFIER:
if (previousType == SimpleParserValueType::IDENTIFIER)
str << " ";
str << token.get().IdentifierValue();
break;
case SimpleParserValueType::CHARACTER:
if (token.get().CharacterValue() == '/')
{
if (previousType != SimpleParserValueType::CHARACTER || !previousCharacterWasSlash)
{
str << "/";
previousCharacterWasSlash = true;
}
}
else
{
str << token.get().CharacterValue();
previousCharacterWasSlash = false;
}
break;
default:
break;
}
previousType = token.get().m_type;
}
return SimpleParserValue::Identifier(tokens.front().get().GetPos(), new std::string(str.str()));
});
}

View File

@@ -1,19 +0,0 @@
#pragma once
#include <limits>
#include <memory>
#include "Parsing/Simple/SimpleParserValue.h"
#include "Parsing/Matcher/AbstractMatcher.h"
#include "Parsing/Matcher/MatcherLabel.h"
class ZoneDefinitionCommonMatchers
{
public:
typedef AbstractMatcher<SimpleParserValue> matcher_t;
typedef IMatcherForLabelSupplier<SimpleParserValue> supplier_t;
static constexpr int LABEL_ASSET_NAME = std::numeric_limits<int>::max() - 1;
static std::unique_ptr<matcher_t> AssetName(const supplier_t* labelSupplier);
};

View File

@@ -0,0 +1,14 @@
#include "ZoneDefinitionMatcherCharacter.h"
ZoneDefinitionMatcherCharacter::ZoneDefinitionMatcherCharacter(const char c)
: m_char(c)
{
}
MatcherResult<ZoneDefinitionParserValue> ZoneDefinitionMatcherCharacter::CanMatch(ILexer<ZoneDefinitionParserValue>* lexer, const unsigned tokenOffset)
{
const auto& token = lexer->GetToken(tokenOffset);
return token.m_type == ZoneDefinitionParserValueType::CHARACTER && token.CharacterValue() == m_char
? MatcherResult<ZoneDefinitionParserValue>::Match(1)
: MatcherResult<ZoneDefinitionParserValue>::NoMatch();
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include "Parsing/Matcher/AbstractMatcher.h"
#include "Parsing/ZoneDefinition/ZoneDefinitionParserValue.h"
class ZoneDefinitionMatcherCharacter final : public AbstractMatcher<ZoneDefinitionParserValue>
{
char m_char;
protected:
MatcherResult<ZoneDefinitionParserValue> CanMatch(ILexer<ZoneDefinitionParserValue>* lexer, unsigned tokenOffset) override;
public:
explicit ZoneDefinitionMatcherCharacter(char c);
};

View File

@@ -0,0 +1,35 @@
#include "ZoneDefinitionMatcherFactory.h"
#include "ZoneDefinitionMatcherCharacter.h"
#include "ZoneDefinitionMatcherKeyword.h"
#include "ZoneDefinitionMatcherValueType.h"
ZoneDefinitionMatcherFactory::ZoneDefinitionMatcherFactory(const IMatcherForLabelSupplier<ZoneDefinitionParserValue>* labelSupplier)
: AbstractMatcherFactory(labelSupplier)
{
}
MatcherFactoryWrapper<ZoneDefinitionParserValue> ZoneDefinitionMatcherFactory::Type(ZoneDefinitionParserValueType type) const
{
return MatcherFactoryWrapper<ZoneDefinitionParserValue>(std::make_unique<ZoneDefinitionMatcherValueType>(type));
}
MatcherFactoryWrapper<ZoneDefinitionParserValue> ZoneDefinitionMatcherFactory::Keyword(std::string keyword) const
{
return MatcherFactoryWrapper<ZoneDefinitionParserValue>(std::make_unique<ZoneDefinitionMatcherKeyword>(std::move(keyword)));
}
MatcherFactoryWrapper<ZoneDefinitionParserValue> ZoneDefinitionMatcherFactory::Field() const
{
return MatcherFactoryWrapper<ZoneDefinitionParserValue>(std::make_unique<ZoneDefinitionMatcherValueType>(ZoneDefinitionParserValueType::FIELD));
}
MatcherFactoryWrapper<ZoneDefinitionParserValue> ZoneDefinitionMatcherFactory::String() const
{
return MatcherFactoryWrapper<ZoneDefinitionParserValue>(std::make_unique<ZoneDefinitionMatcherValueType>(ZoneDefinitionParserValueType::STRING));
}
MatcherFactoryWrapper<ZoneDefinitionParserValue> ZoneDefinitionMatcherFactory::Char(char c) const
{
return MatcherFactoryWrapper<ZoneDefinitionParserValue>(std::make_unique<ZoneDefinitionMatcherCharacter>(c));
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include <string>
#include "Parsing/ZoneDefinition/ZoneDefinitionParserValue.h"
#include "Parsing/Matcher/AbstractMatcherFactory.h"
class ZoneDefinitionMatcherFactory final : public AbstractMatcherFactory<ZoneDefinitionParserValue>
{
public:
explicit ZoneDefinitionMatcherFactory(const IMatcherForLabelSupplier<ZoneDefinitionParserValue>* labelSupplier);
_NODISCARD MatcherFactoryWrapper<ZoneDefinitionParserValue> Type(ZoneDefinitionParserValueType type) const;
_NODISCARD MatcherFactoryWrapper<ZoneDefinitionParserValue> Keyword(std::string keyword) const;
_NODISCARD MatcherFactoryWrapper<ZoneDefinitionParserValue> Field() const;
_NODISCARD MatcherFactoryWrapper<ZoneDefinitionParserValue> String() const;
_NODISCARD MatcherFactoryWrapper<ZoneDefinitionParserValue> Char(char c) const;
};

View File

@@ -0,0 +1,16 @@
#include "ZoneDefinitionMatcherKeyword.h"
ZoneDefinitionMatcherKeyword::ZoneDefinitionMatcherKeyword(std::string value)
: m_value(std::move(value))
{
const std::hash<std::string> hash;
m_hash = hash(m_value);
}
MatcherResult<ZoneDefinitionParserValue> ZoneDefinitionMatcherKeyword::CanMatch(ILexer<ZoneDefinitionParserValue>* lexer, const unsigned tokenOffset)
{
const auto& token = lexer->GetToken(tokenOffset);
return token.m_type == ZoneDefinitionParserValueType::FIELD && token.FieldHash() == m_hash && token.FieldValue() == m_value
? MatcherResult<ZoneDefinitionParserValue>::Match(1)
: MatcherResult<ZoneDefinitionParserValue>::NoMatch();
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include <string>
#include "Parsing/ZoneDefinition/ZoneDefinitionParserValue.h"
#include "Parsing/Matcher/AbstractMatcher.h"
class ZoneDefinitionMatcherKeyword final : public AbstractMatcher<ZoneDefinitionParserValue>
{
size_t m_hash;
std::string m_value;
protected:
MatcherResult<ZoneDefinitionParserValue> CanMatch(ILexer<ZoneDefinitionParserValue>* lexer, unsigned tokenOffset) override;
public:
explicit ZoneDefinitionMatcherKeyword(std::string value);
};

View File

@@ -0,0 +1,13 @@
#include "ZoneDefinitionMatcherValueType.h"
ZoneDefinitionMatcherValueType::ZoneDefinitionMatcherValueType(const ZoneDefinitionParserValueType type)
: m_type(type)
{
}
MatcherResult<ZoneDefinitionParserValue> ZoneDefinitionMatcherValueType::CanMatch(ILexer<ZoneDefinitionParserValue>* lexer, const unsigned tokenOffset)
{
return lexer->GetToken(tokenOffset).m_type == m_type
? MatcherResult<ZoneDefinitionParserValue>::Match(1)
: MatcherResult<ZoneDefinitionParserValue>::NoMatch();
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include "Parsing/ZoneDefinition/ZoneDefinitionParserValue.h"
#include "Parsing/Matcher/AbstractMatcher.h"
class ZoneDefinitionMatcherValueType final : public AbstractMatcher<ZoneDefinitionParserValue>
{
ZoneDefinitionParserValueType m_type;
protected:
MatcherResult<ZoneDefinitionParserValue> CanMatch(ILexer<ZoneDefinitionParserValue>* lexer, unsigned tokenOffset) override;
public:
explicit ZoneDefinitionMatcherValueType(ZoneDefinitionParserValueType type);
};