mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-09-07 17:27:26 +00:00
Parse techset files for IW4
This commit is contained in:
93
src/ObjLoading/Techset/Parsing/TechsetFileParser.cpp
Normal file
93
src/ObjLoading/Techset/Parsing/TechsetFileParser.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#include "TechsetFileParser.h"
|
||||
|
||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
||||
|
||||
using namespace techset;
|
||||
|
||||
namespace techset
|
||||
{
|
||||
class SequenceTechniqueTypeName final : public Parser::sequence_t
|
||||
{
|
||||
static constexpr auto CAPTURE_TYPE_NAME = 1;
|
||||
|
||||
public:
|
||||
SequenceTechniqueTypeName()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.String().Capture(CAPTURE_TYPE_NAME),
|
||||
create.Char(':')
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(ParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
const auto& typeNameToken = result.NextCapture(CAPTURE_TYPE_NAME);
|
||||
|
||||
size_t techniqueTypeIndex;
|
||||
if (!state->FindTechniqueTypeIndex(typeNameToken.StringValue(), techniqueTypeIndex))
|
||||
throw ParsingException(typeNameToken.GetPos(), "Unknown technique type name");
|
||||
|
||||
state->m_current_technique_types.push_back(techniqueTypeIndex);
|
||||
}
|
||||
};
|
||||
|
||||
class SequenceTechniqueName final : public Parser::sequence_t
|
||||
{
|
||||
static constexpr auto CAPTURE_NAME = 1;
|
||||
|
||||
public:
|
||||
SequenceTechniqueName()
|
||||
{
|
||||
const SimpleMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Or({
|
||||
create.Identifier(),
|
||||
create.String()
|
||||
}).Capture(CAPTURE_NAME),
|
||||
create.Char(';')
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
void ProcessMatch(ParserState* state, SequenceResult<SimpleParserValue>& result) const override
|
||||
{
|
||||
assert(!state->m_current_technique_types.empty());
|
||||
|
||||
const auto& techniqueNameToken = result.NextCapture(CAPTURE_NAME);
|
||||
const auto& techniqueName = techniqueNameToken.m_type == SimpleParserValueType::STRING
|
||||
? techniqueNameToken.StringValue()
|
||||
: techniqueNameToken.IdentifierValue();
|
||||
|
||||
for (const auto techniqueTypeIndex : state->m_current_technique_types)
|
||||
state->m_definition->SetTechniqueByIndex(techniqueTypeIndex, techniqueName);
|
||||
state->m_current_technique_types.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Parser::Parser(SimpleLexer* lexer, const char** validTechniqueTypeNames, const size_t validTechniqueTypeNameCount)
|
||||
: AbstractParser(lexer, std::make_unique<ParserState>(validTechniqueTypeNames, validTechniqueTypeNameCount))
|
||||
{
|
||||
}
|
||||
|
||||
const std::vector<Parser::sequence_t*>& Parser::GetTestsForState()
|
||||
{
|
||||
static std::vector<sequence_t*> allTests({
|
||||
new SequenceTechniqueTypeName(),
|
||||
new SequenceTechniqueName()
|
||||
});
|
||||
static std::vector<sequence_t*> techniqueTypeNameOnlyTests({
|
||||
new SequenceTechniqueTypeName()
|
||||
});
|
||||
|
||||
return m_state->m_current_technique_types.empty() ? techniqueTypeNameOnlyTests : allTests;
|
||||
}
|
||||
|
||||
std::unique_ptr<TechsetDefinition> Parser::GetTechsetDefinition() const
|
||||
{
|
||||
return std::move(m_state->m_definition);
|
||||
}
|
21
src/ObjLoading/Techset/Parsing/TechsetFileParser.h
Normal file
21
src/ObjLoading/Techset/Parsing/TechsetFileParser.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "TechsetFileParserState.h"
|
||||
#include "Techset/TechsetDefinition.h"
|
||||
#include "Parsing/Simple/SimpleLexer.h"
|
||||
#include "Parsing/Simple/SimpleParserValue.h"
|
||||
#include "Parsing/Impl/AbstractParser.h"
|
||||
|
||||
namespace techset
|
||||
{
|
||||
class Parser final : public AbstractParser<SimpleParserValue, ParserState>
|
||||
{
|
||||
protected:
|
||||
const std::vector<sequence_t*>& GetTestsForState() override;
|
||||
|
||||
public:
|
||||
Parser(SimpleLexer* lexer, const char** validTechniqueTypeNames, size_t validTechniqueTypeNameCount);
|
||||
_NODISCARD std::unique_ptr<TechsetDefinition> GetTechsetDefinition() const;
|
||||
};
|
||||
}
|
25
src/ObjLoading/Techset/Parsing/TechsetFileParserState.cpp
Normal file
25
src/ObjLoading/Techset/Parsing/TechsetFileParserState.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "TechsetFileParserState.h"
|
||||
|
||||
using namespace techset;
|
||||
|
||||
ParserState::ParserState(const char** validTechniqueTypeNames, size_t validTechniqueTypeNameCount)
|
||||
: m_definition(std::make_unique<TechsetDefinition>(validTechniqueTypeNameCount))
|
||||
{
|
||||
for(auto i = 0u; i < validTechniqueTypeNameCount; i++)
|
||||
{
|
||||
m_valid_technique_type_names.emplace(std::make_pair(std::string(validTechniqueTypeNames[i]), i));
|
||||
}
|
||||
}
|
||||
|
||||
bool ParserState::FindTechniqueTypeIndex(const std::string& techniqueTypeName, size_t& techniqueTypeIndex) const
|
||||
{
|
||||
const auto foundTechniqueType = m_valid_technique_type_names.find(techniqueTypeName);
|
||||
|
||||
if(foundTechniqueType != m_valid_technique_type_names.end())
|
||||
{
|
||||
techniqueTypeIndex = foundTechniqueType->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
22
src/ObjLoading/Techset/Parsing/TechsetFileParserState.h
Normal file
22
src/ObjLoading/Techset/Parsing/TechsetFileParserState.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "Techset/TechsetDefinition.h"
|
||||
|
||||
namespace techset
|
||||
{
|
||||
class ParserState
|
||||
{
|
||||
public:
|
||||
std::map<std::string, size_t> m_valid_technique_type_names;
|
||||
std::unique_ptr<TechsetDefinition> m_definition;
|
||||
std::vector<size_t> m_current_technique_types;
|
||||
|
||||
ParserState(const char** validTechniqueTypeNames, size_t validTechniqueTypeNameCount);
|
||||
|
||||
bool FindTechniqueTypeIndex(const std::string& techniqueTypeName, size_t& techniqueTypeIndex) const;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user