mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-08 05:48:19 -05:00
86 lines
2.4 KiB
C++
86 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include <unordered_map>
|
|
|
|
#include "Utils/ClassUtils.h"
|
|
#include "Parsing/Matcher/AbstractMatcher.h"
|
|
#include "Parsing/Matcher/MatcherResult.h"
|
|
#include "Parsing/ParsingException.h"
|
|
|
|
template <typename TokenType>
|
|
class SequenceResult
|
|
{
|
|
class Capture
|
|
{
|
|
public:
|
|
unsigned m_offset;
|
|
std::vector<std::reference_wrapper<const TokenType>> m_tokens;
|
|
|
|
Capture()
|
|
: m_offset(0)
|
|
{
|
|
}
|
|
};
|
|
|
|
// TokenType must inherit IParserValue
|
|
static_assert(std::is_base_of<IParserValue, TokenType>::value);
|
|
|
|
std::vector<int> m_tags;
|
|
std::unordered_map<int, Capture> m_captures;
|
|
|
|
unsigned m_tag_offset;
|
|
|
|
public:
|
|
SequenceResult(ILexer<TokenType>* lexer, const MatcherResult<TokenType>& result)
|
|
: m_tags(result.m_tags),
|
|
m_tag_offset(0)
|
|
{
|
|
for (const typename MatcherResult<TokenType>::Capture& capture : result.m_captures)
|
|
{
|
|
if (capture.m_token_index.IsFabricated())
|
|
m_captures[capture.GetCaptureId()].m_tokens.push_back(result.m_fabricated_tokens[capture.m_token_index.GetTokenIndex()]);
|
|
else
|
|
m_captures[capture.GetCaptureId()].m_tokens.push_back(lexer->GetToken(capture.m_token_index.GetTokenIndex()));
|
|
}
|
|
}
|
|
|
|
_NODISCARD int PeekTag() const
|
|
{
|
|
if (m_tag_offset < m_tags.size())
|
|
return m_tags[m_tag_offset];
|
|
|
|
return AbstractMatcher<TokenType>::NO_ID;
|
|
}
|
|
|
|
int NextTag()
|
|
{
|
|
if (m_tag_offset < m_tags.size())
|
|
return m_tags[m_tag_offset++];
|
|
|
|
return AbstractMatcher<TokenType>::NO_ID;
|
|
}
|
|
|
|
_NODISCARD bool HasNextCapture(int captureId)
|
|
{
|
|
auto foundEntry = m_captures.find(captureId);
|
|
|
|
if (foundEntry == m_captures.end())
|
|
return false;
|
|
|
|
return foundEntry->second.m_offset < foundEntry->second.m_tokens.size();
|
|
}
|
|
|
|
const TokenType& NextCapture(int captureId)
|
|
{
|
|
auto foundEntry = m_captures.find(captureId);
|
|
|
|
if (foundEntry == m_captures.end())
|
|
throw ParsingException(TokenPos(), "Tried to access next capture even though no captures exists!");
|
|
|
|
if(foundEntry->second.m_offset >= foundEntry->second.m_tokens.size())
|
|
throw ParsingException(TokenPos(), "Tried to access next capture even though none exists!");
|
|
|
|
return foundEntry->second.m_tokens[foundEntry->second.m_offset++];
|
|
}
|
|
};
|