2
0
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:
Jan
2021-02-13 00:12:26 +01:00
parent fe1f391bcc
commit 0f70f9586c
48 changed files with 1061 additions and 141 deletions

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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);
};

View File

@@ -0,0 +1,7 @@
#pragma once
class HeaderParserState
{
public:
};

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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);
};

View File

@@ -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));
}

View File

@@ -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;
};

View File

@@ -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();
}

View File

@@ -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);
};

View File

@@ -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
{
}

View File

@@ -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();
};