mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-09-05 08:17:25 +00:00
Implement sequence matcher and parser magic
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "Impl/HeaderLexer.h"
|
||||
#include "Impl/HeaderParser.h"
|
||||
#include "Parsing/ParsingException.h"
|
||||
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
|
||||
#include "Parsing/Impl/DefinesStreamProxy.h"
|
||||
@@ -53,100 +54,8 @@ bool HeaderFileReader::ReadHeaderFile(IDataRepository* repository)
|
||||
|
||||
SetupStreamProxies();
|
||||
|
||||
auto lexer = std::make_unique<HeaderLexer>(m_stream);
|
||||
const auto lexer = std::make_unique<HeaderLexer>(m_stream);
|
||||
const auto parser = std::make_unique<HeaderParser>(lexer.get(), repository);
|
||||
|
||||
try
|
||||
{
|
||||
/*while (true)
|
||||
{
|
||||
auto line = m_stream->NextLine();
|
||||
|
||||
if (line.IsEof())
|
||||
break;
|
||||
|
||||
std::cout << "Line " << line.m_filename.get() << ":" << line.m_line_number << ": " << line.m_line << "\n";
|
||||
}*/
|
||||
|
||||
auto eof = false;
|
||||
while (!eof)
|
||||
{
|
||||
const auto& token = lexer->GetToken(0);
|
||||
|
||||
switch (token.m_type)
|
||||
{
|
||||
case HeaderParserValueType::END_OF_FILE:
|
||||
case HeaderParserValueType::INVALID:
|
||||
eof = true;
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::CHARACTER:
|
||||
std::cout << "Token " << token.CharacterValue() << "\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::IDENTIFIER:
|
||||
std::cout << "Token IDENTIFIER \"" << token.IdentifierValue() << "\"\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::STRING:
|
||||
std::cout << "Token STRING \"" << token.StringValue() << "\"\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::INTEGER:
|
||||
std::cout << "Token INTEGER " << token.IntegerValue() << "\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::FLOATING_POINT:
|
||||
std::cout << "Token FLOATINGPOINT " << token.FloatingPointValue() << "\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::DECLSPEC:
|
||||
std::cout << "Token DECLSPEC\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::ALIGN:
|
||||
std::cout << "Token ALIGN\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::ALIGNAS:
|
||||
std::cout << "Token ALIGNAS\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::CONST:
|
||||
std::cout << "Token CONST\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::ENUM:
|
||||
std::cout << "Token ENUM\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::NAMESPACE:
|
||||
std::cout << "Token NAMESPACE\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::STRUCT:
|
||||
std::cout << "Token STRUCT\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::TYPEDEF:
|
||||
std::cout << "Token TYPEDEF\n";
|
||||
break;
|
||||
|
||||
case HeaderParserValueType::UNION:
|
||||
std::cout << "Token UNION\n";
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cout << "Token UNKNOWN\n";
|
||||
break;
|
||||
}
|
||||
|
||||
lexer->PopTokens(1);
|
||||
}
|
||||
}
|
||||
catch (const ParsingException& e)
|
||||
{
|
||||
std::cout << "Error: " << e.FullMessage() << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
return parser->Parse();
|
||||
}
|
||||
|
@@ -0,0 +1,17 @@
|
||||
#include "HeaderParser.h"
|
||||
|
||||
#include "Parsing/Header/Sequence/SequenceNamespace.h"
|
||||
|
||||
HeaderParser::HeaderParser(HeaderLexer* lexer, IDataRepository* targetRepository)
|
||||
: AbstractParser(lexer, std::make_unique<HeaderParserState>()),
|
||||
m_repository(targetRepository)
|
||||
{
|
||||
auto sequenceNamespace = std::make_unique<SequenceNamespace>();
|
||||
m_normal_tests.push_back(sequenceNamespace.get());
|
||||
m_tests.emplace_back(std::move(sequenceNamespace));
|
||||
}
|
||||
|
||||
const std::vector<HeaderParser::sequence_t*>& HeaderParser::GetTestsForState()
|
||||
{
|
||||
return m_normal_tests;
|
||||
}
|
||||
|
@@ -1,6 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
class HeaderParser
|
||||
{
|
||||
#include "HeaderLexer.h"
|
||||
#include "HeaderParserState.h"
|
||||
#include "Parsing/AbstractParser.h"
|
||||
#include "Persistence/IDataRepository.h"
|
||||
|
||||
};
|
||||
class HeaderParser final : public AbstractParser<HeaderParserValue, HeaderParserState>
|
||||
{
|
||||
IDataRepository* m_repository;
|
||||
|
||||
std::vector<std::unique_ptr<sequence_t>> m_tests;
|
||||
std::vector<sequence_t*> m_normal_tests;
|
||||
|
||||
protected:
|
||||
const std::vector<sequence_t*>& GetTestsForState() override;
|
||||
|
||||
public:
|
||||
HeaderParser(HeaderLexer* lexer, IDataRepository* targetRepository);
|
||||
};
|
||||
|
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
class HeaderParserState
|
||||
{
|
||||
public:
|
||||
|
||||
};
|
@@ -149,6 +149,16 @@ HeaderParserValue& HeaderParserValue::operator=(HeaderParserValue&& other) noexc
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HeaderParserValue::IsEof() const
|
||||
{
|
||||
return m_type == HeaderParserValueType::END_OF_FILE;
|
||||
}
|
||||
|
||||
const TokenPos& HeaderParserValue::GetPos() const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
char HeaderParserValue::CharacterValue() const
|
||||
{
|
||||
assert(m_type == HeaderParserValueType::CHARACTER);
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
#include "Parsing/IParserValue.h"
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "Parsing/TokenPos.h"
|
||||
|
||||
@@ -48,7 +50,7 @@ enum class HeaderParserValueType
|
||||
MAX
|
||||
};
|
||||
|
||||
class HeaderParserValue
|
||||
class HeaderParserValue final : public IParserValue
|
||||
{
|
||||
public:
|
||||
TokenPos m_pos;
|
||||
@@ -83,12 +85,15 @@ private:
|
||||
HeaderParserValue(TokenPos pos, HeaderParserValueType type);
|
||||
|
||||
public:
|
||||
~HeaderParserValue();
|
||||
~HeaderParserValue() override;
|
||||
HeaderParserValue(const HeaderParserValue& other) = delete;
|
||||
HeaderParserValue(HeaderParserValue&& other) noexcept;
|
||||
HeaderParserValue& operator=(const HeaderParserValue& other) = delete;
|
||||
HeaderParserValue& operator=(HeaderParserValue&& other) noexcept;
|
||||
|
||||
_NODISCARD bool IsEof() const override;
|
||||
_NODISCARD const TokenPos& GetPos() const override;
|
||||
|
||||
_NODISCARD char CharacterValue() const;
|
||||
_NODISCARD int IntegerValue() const;
|
||||
_NODISCARD double FloatingPointValue() const;
|
||||
|
@@ -0,0 +1,14 @@
|
||||
#include "HeaderMatcherCharacter.h"
|
||||
|
||||
HeaderMatcherCharacter::HeaderMatcherCharacter(const char c)
|
||||
: m_char(c)
|
||||
{
|
||||
}
|
||||
|
||||
MatcherResult<HeaderParserValue> HeaderMatcherCharacter::CanMatch(AbstractLexer<HeaderParserValue>* lexer, const unsigned tokenOffset)
|
||||
{
|
||||
const auto& token = lexer->GetToken(tokenOffset);
|
||||
return token.m_type == HeaderParserValueType::CHARACTER && token.CharacterValue() == m_char
|
||||
? MatcherResult<HeaderParserValue>::Match(1)
|
||||
: MatcherResult<HeaderParserValue>::NoMatch();
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Header/Impl/HeaderParserValue.h"
|
||||
#include "Parsing/Matcher/AbstractMatcher.h"
|
||||
|
||||
class HeaderMatcherCharacter final : public AbstractMatcher<HeaderParserValue>
|
||||
{
|
||||
char m_char;
|
||||
|
||||
protected:
|
||||
MatcherResult<HeaderParserValue> CanMatch(AbstractLexer<HeaderParserValue>* lexer, unsigned tokenOffset) override;
|
||||
|
||||
public:
|
||||
explicit HeaderMatcherCharacter(char c);
|
||||
};
|
@@ -0,0 +1,19 @@
|
||||
#include "HeaderMatcherFactory.h"
|
||||
|
||||
#include "HeaderMatcherCharacter.h"
|
||||
#include "HeaderMatcherValueType.h"
|
||||
|
||||
HeaderMatcherFactory::HeaderMatcherFactory(const IMatcherForLabelSupplier<HeaderParserValue>* labelSupplier)
|
||||
: AbstractMatcherFactory(labelSupplier)
|
||||
{
|
||||
}
|
||||
|
||||
MatcherFactoryWrapper<HeaderParserValue> HeaderMatcherFactory::Type(HeaderParserValueType type) const
|
||||
{
|
||||
return MatcherFactoryWrapper<HeaderParserValue>(std::make_unique<HeaderMatcherValueType>(type));
|
||||
}
|
||||
|
||||
MatcherFactoryWrapper<HeaderParserValue> HeaderMatcherFactory::Char(char c) const
|
||||
{
|
||||
return MatcherFactoryWrapper<HeaderParserValue>(std::make_unique<HeaderMatcherCharacter>(c));
|
||||
}
|
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Header/Impl/HeaderParserValue.h"
|
||||
#include "Parsing/Matcher/AbstractMatcherFactory.h"
|
||||
|
||||
class HeaderMatcherFactory final : public AbstractMatcherFactory<HeaderParserValue>
|
||||
{
|
||||
public:
|
||||
explicit HeaderMatcherFactory(const IMatcherForLabelSupplier<HeaderParserValue>* labelSupplier);
|
||||
|
||||
_NODISCARD MatcherFactoryWrapper<HeaderParserValue> Type(HeaderParserValueType type) const;
|
||||
_NODISCARD MatcherFactoryWrapper<HeaderParserValue> Char(char c) const;
|
||||
};
|
@@ -0,0 +1,13 @@
|
||||
#include "HeaderMatcherValueType.h"
|
||||
|
||||
HeaderMatcherValueType::HeaderMatcherValueType(HeaderParserValueType type)
|
||||
: m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
MatcherResult<HeaderParserValue> HeaderMatcherValueType::CanMatch(AbstractLexer<HeaderParserValue>* lexer, const unsigned tokenOffset)
|
||||
{
|
||||
return lexer->GetToken(tokenOffset).m_type == m_type
|
||||
? MatcherResult<HeaderParserValue>::Match(1)
|
||||
: MatcherResult<HeaderParserValue>::NoMatch();
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Header/Impl/HeaderParserValue.h"
|
||||
#include "Parsing/Matcher/AbstractMatcher.h"
|
||||
|
||||
class HeaderMatcherValueType final : public AbstractMatcher<HeaderParserValue>
|
||||
{
|
||||
HeaderParserValueType m_type;
|
||||
|
||||
protected:
|
||||
MatcherResult<HeaderParserValue> CanMatch(AbstractLexer<HeaderParserValue>* lexer, unsigned tokenOffset) override;
|
||||
|
||||
public:
|
||||
explicit HeaderMatcherValueType(HeaderParserValueType type);
|
||||
};
|
@@ -0,0 +1,18 @@
|
||||
#include "SequenceNamespace.h"
|
||||
|
||||
#include "Parsing/Header/Matcher/HeaderMatcherFactory.h"
|
||||
|
||||
SequenceNamespace::SequenceNamespace()
|
||||
{
|
||||
const HeaderMatcherFactory create(this);
|
||||
|
||||
AddMatchers({
|
||||
create.Type(HeaderParserValueType::NAMESPACE),
|
||||
create.Type(HeaderParserValueType::IDENTIFIER).Capture(CAPTURE_NAME),
|
||||
create.Char('{')
|
||||
});
|
||||
}
|
||||
|
||||
void SequenceNamespace::ProcessMatch(HeaderParserState* state, const SequenceResult<HeaderParserValue>& result) const
|
||||
{
|
||||
}
|
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "Parsing/Sequence/AbstractSequence.h"
|
||||
#include "Parsing/Header/Impl/HeaderParserState.h"
|
||||
#include "Parsing/Header/Impl/HeaderParserValue.h"
|
||||
|
||||
class SequenceNamespace final : public AbstractSequence<HeaderParserValue, HeaderParserState>
|
||||
{
|
||||
static constexpr int CAPTURE_NAME = 0;
|
||||
|
||||
protected:
|
||||
void ProcessMatch(HeaderParserState* state, const SequenceResult<HeaderParserValue>& result) const override;
|
||||
|
||||
public:
|
||||
SequenceNamespace();
|
||||
};
|
Reference in New Issue
Block a user