Add Header Lexer for ZCG cpp

This commit is contained in:
Jan
2021-02-12 00:01:41 +01:00
parent 8b8f1d4f2a
commit 87b7921c73
20 changed files with 1386 additions and 59 deletions

View File

@ -3,29 +3,284 @@
#include <cassert>
#include <deque>
#include "Utils/ClassUtils.h"
#include "ILexer.h"
#include "IParserLineStream.h"
#include "ParsingException.h"
template <typename TokenType>
class AbstractLexer : public ILexer
{
protected:
std::deque<TokenType> m_token_cache;
IParserLineStream* const m_stream;
protected:
unsigned m_current_line_offset;
bool m_peeked_next_line;
bool m_start;
ParserLine m_current_line;
ParserLine m_next_line;
explicit AbstractLexer(IParserLineStream* stream)
: m_stream(stream)
: m_stream(stream),
m_current_line_offset(0u),
m_peeked_next_line(false),
m_start(true)
{
}
virtual TokenType GetNextToken() = 0;
int NextChar()
{
if (m_current_line.IsEof())
{
if (m_start)
m_start = false;
else
return EOF;
}
while (m_current_line_offset >= m_current_line.m_line.size())
{
m_current_line_offset = 0;
if (m_peeked_next_line)
{
m_current_line = m_next_line;
m_peeked_next_line = false;
}
else
{
m_current_line = m_stream->NextLine();
}
if (m_current_line.IsEof())
return EOF;
}
return m_current_line.m_line[m_current_line_offset++];
}
int PeekChar()
{
if (m_current_line.IsEof())
return EOF;
if (m_current_line_offset >= m_current_line.m_line.size())
{
m_peeked_next_line = true;
do
{
m_next_line = m_stream->NextLine();
if (m_next_line.IsEof())
return EOF;
}
while (m_next_line.m_line.empty());
return m_next_line.m_line[0];
}
return m_current_line.m_line[m_current_line_offset];
}
_NODISCARD bool IsLineEnd() const
{
return m_current_line_offset >= m_current_line.m_line.size();
}
_NODISCARD bool NextCharInLineIs(const char c)
{
return !IsLineEnd() && PeekChar() == c;
}
_NODISCARD TokenPos GetPreviousCharacterPos() const
{
return TokenPos(m_current_line.m_filename, m_current_line.m_line_number, m_current_line_offset);
}
_NODISCARD TokenPos GetNextCharacterPos()
{
if (m_current_line_offset + 1 >= m_current_line.m_line.size())
{
PeekChar();
return TokenPos(m_next_line.m_filename, m_next_line.m_line_number, 1);
}
return TokenPos(m_current_line.m_filename, m_current_line.m_line_number, m_current_line_offset + 1);
}
/**
* \brief Reads an identifier from the current position
* \return The value of the read identifier
*/
std::string ReadIdentifier()
{
assert(m_current_line_offset >= 1);
assert(isalpha(m_current_line.m_line[m_current_line_offset - 1]) || m_current_line.m_line[m_current_line_offset - 1] == '_');
const auto startPos = m_current_line_offset - 1;
const auto lineSize = m_current_line.m_line.size();
while (m_current_line_offset < lineSize)
{
const auto c = m_current_line.m_line[m_current_line_offset];
if (!isalnum(c) && c != '_')
break;
m_current_line_offset++;
}
return std::string(m_current_line.m_line, startPos, m_current_line_offset - startPos);
}
/**
* \brief Reads an identifier from the current position
* \return The value of the read identifier
*/
std::string ReadString()
{
assert(m_current_line_offset >= 1);
assert(m_current_line.m_line[m_current_line_offset - 1] == '"');
const auto startPos = m_current_line_offset;
const auto lineSize = m_current_line.m_line.size();
while (true)
{
if (m_current_line_offset >= lineSize)
throw ParsingException(TokenPos(m_current_line.m_filename, m_current_line.m_line_number, m_current_line_offset), "Unclosed string");
if (m_current_line.m_line[m_current_line_offset] == '\"')
break;
m_current_line_offset++;
}
return std::string(m_current_line.m_line, startPos, m_current_line_offset++ - startPos);
}
void ReadHexNumber(int& integerValue)
{
const auto* start = &m_current_line.m_line.c_str()[m_current_line_offset - 1];
char* end;
integerValue = std::strtoul(start, &end, 16);
const auto numberLength = static_cast<unsigned>(end - start);
if (numberLength == 0 || isalnum(*end) || *end == '_')
throw ParsingException(GetPreviousCharacterPos(), "Invalid hex number");
m_current_line_offset += numberLength;
}
_NODISCARD bool IsIntegerNumber() const
{
const auto* currentCharacter = &m_current_line.m_line.c_str()[m_current_line_offset - 1];
auto isInteger = true;
auto dot = false;
auto exponent = false;
if (*currentCharacter == '-')
currentCharacter++;
else if (*currentCharacter == '+')
currentCharacter++;
while (*currentCharacter)
{
if (isdigit(*currentCharacter))
{
}
else if (*currentCharacter == '.')
{
if (dot)
throw ParsingException(GetPreviousCharacterPos(), "Invalid number");
dot = true;
isInteger = false;
}
else if (*currentCharacter == 'e' || *currentCharacter == 'E')
{
if (exponent)
throw ParsingException(GetPreviousCharacterPos(), "Invalid number");
if (currentCharacter[1] == '-')
currentCharacter++;
exponent = true;
isInteger = false;
}
else if (isalpha(*currentCharacter))
{
throw ParsingException(GetPreviousCharacterPos(), "Invalid number");
}
else
{
break;
}
currentCharacter++;
}
return isInteger;
}
int ReadInteger()
{
const auto* start = &m_current_line.m_line.c_str()[m_current_line_offset - 1];
char* end;
const auto integerValue = std::strtol(start, &end, 10);
const auto numberLength = static_cast<unsigned>(end - start);
if(numberLength == 0)
throw ParsingException(GetPreviousCharacterPos(), "Invalid number");
m_current_line_offset += numberLength - 1;
return integerValue;
}
double ReadFloatingPoint()
{
const auto* start = &m_current_line.m_line.c_str()[m_current_line_offset - 1];
char* end;
const auto floatingPointValue = std::strtod(start, &end);
const auto numberLength = static_cast<unsigned>(end - start);
if (numberLength == 0)
throw ParsingException(GetPreviousCharacterPos(), "Invalid number");
m_current_line_offset += numberLength - 1;
return floatingPointValue;
}
void ReadNumber(bool& isFloatingPoint, double& floatingPointValue, int& integerValue)
{
assert(m_current_line_offset >= 1);
assert(isdigit(m_current_line.m_line[m_current_line_offset - 1]));
const auto lineLength = m_current_line.m_line.size();
if (lineLength - m_current_line_offset >= 1
&& m_current_line.m_line[m_current_line_offset - 1] == '0'
&& m_current_line.m_line[m_current_line_offset] == 'x')
{
isFloatingPoint = false;
ReadHexNumber(integerValue);
}
else if (IsIntegerNumber())
{
isFloatingPoint = false;
integerValue = ReadInteger();
}
else
{
isFloatingPoint = true;
floatingPointValue = ReadFloatingPoint();
}
}
public:
const TokenType& GetToken(int index)
const TokenType& GetToken(unsigned index)
{
assert(index >= 0);
while (index <= m_token_cache.size())
m_token_cache.emplace_back(std::move(GetNextToken()));
while (index >= m_token_cache.size())
m_token_cache.emplace_back(GetNextToken());
return m_token_cache[index];
}

View File

@ -2,6 +2,7 @@
#include <iostream>
#include "Impl/CommandsLexer.h"
#include "Parsing/ParsingException.h"
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
#include "Parsing/Impl/DefinesStreamProxy.h"
@ -10,43 +11,60 @@
CommandsFileReader::CommandsFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
: m_args(args),
m_filename(std::move(filename))
m_filename(std::move(filename)),
m_stream(nullptr)
{
}
bool CommandsFileReader::ReadCommandsFile(IDataRepository* repository)
bool CommandsFileReader::OpenBaseStream()
{
std::cout << "Reading commands file: " << m_filename << std::endl;
ParserFilesystemStream stream(m_filename);
if (!stream.IsOpen())
auto stream = std::make_unique<ParserFilesystemStream>(m_filename);
if (!stream->IsOpen())
{
std::cout << "Could not open commands file" << std::endl;
return false;
}
IParserLineStream* lineStream = &stream;
m_stream = stream.get();
m_open_streams.emplace_back(std::move(stream));
return true;
}
CommentRemovingStreamProxy commentProxy(lineStream);
lineStream = &commentProxy;
void CommandsFileReader::SetupStreamProxies()
{
auto commentProxy = std::make_unique<CommentRemovingStreamProxy>(m_stream);
auto includeProxy = std::make_unique<IncludingStreamProxy>(commentProxy.get());
auto definesProxy = std::make_unique<DefinesStreamProxy>(includeProxy.get());
definesProxy->AddDefine(ZONE_CODE_GENERATOR_DEFINE_NAME, ZONE_CODE_GENERATOR_DEFINE_VALUE);
IncludingStreamProxy includeProxy(lineStream);
lineStream = &includeProxy;
m_stream = definesProxy.get();
DefinesStreamProxy definesProxy(lineStream);
definesProxy.AddDefine(ZONE_CODE_GENERATOR_DEFINE_NAME, ZONE_CODE_GENERATOR_DEFINE_VALUE);
lineStream = &definesProxy;
m_open_streams.emplace_back(std::move(commentProxy));
m_open_streams.emplace_back(std::move(includeProxy));
m_open_streams.emplace_back(std::move(definesProxy));
}
bool CommandsFileReader::ReadCommandsFile(IDataRepository* repository)
{
std::cout << "Reading commands file: " << m_filename << std::endl;
if (!OpenBaseStream())
return false;
SetupStreamProxies();
auto lexer = std::make_unique<CommandsLexer>(m_stream);
try
{
while (true)
{
auto line = lineStream->NextLine();
auto line = m_stream->NextLine();
if (line.IsEof())
break;
std::cout << "Line " << line.m_filename << ":" << line.m_line_number << ": " << line.m_line << "\n";
std::cout << "Line " << line.m_filename.get() << ":" << line.m_line_number << ": " << line.m_line << "\n";
}
}
catch (const ParsingException& e)

View File

@ -3,6 +3,7 @@
#include <string>
#include "ZoneCodeGeneratorArguments.h"
#include "Parsing/IParserLineStream.h"
#include "Persistence/IDataRepository.h"
class CommandsFileReader
@ -13,6 +14,12 @@ class CommandsFileReader
const ZoneCodeGeneratorArguments* m_args;
std::string m_filename;
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
IParserLineStream* m_stream;
bool OpenBaseStream();
void SetupStreamProxies();
public:
explicit CommandsFileReader(const ZoneCodeGeneratorArguments* args, std::string filename);

View File

@ -2,12 +2,13 @@
#include <string>
#include "Parsing/TokenPos.h"
#include "Utils/ClassUtils.h"
#include "Parsing/TokenPos.h"
class CommandsParserValueType
{
CommandsParserValueType() = default;
public:
enum
{

View File

@ -2,7 +2,7 @@
#include <iostream>
#include "Impl/HeaderLexer.h"
#include "Parsing/ParsingException.h"
#include "Parsing/Impl/CommentRemovingStreamProxy.h"
#include "Parsing/Impl/DefinesStreamProxy.h"
@ -11,43 +11,92 @@
HeaderFileReader::HeaderFileReader(const ZoneCodeGeneratorArguments* args, std::string filename)
: m_args(args),
m_filename(std::move(filename))
m_filename(std::move(filename)),
m_stream(nullptr)
{
}
bool HeaderFileReader::ReadHeaderFile(IDataRepository* repository) const
bool HeaderFileReader::OpenBaseStream()
{
std::cout << "Reading header file: " << m_filename << std::endl;
ParserFilesystemStream stream(m_filename);
if (!stream.IsOpen())
auto stream = std::make_unique<ParserFilesystemStream>(m_filename);
if (!stream->IsOpen())
{
std::cout << "Could not open header file" << std::endl;
return false;
}
IParserLineStream* lineStream = &stream;
m_stream = stream.get();
m_open_streams.emplace_back(std::move(stream));
return true;
}
CommentRemovingStreamProxy commentProxy(lineStream);
lineStream = &commentProxy;
void HeaderFileReader::SetupStreamProxies()
{
auto commentProxy = std::make_unique<CommentRemovingStreamProxy>(m_stream);
auto includeProxy = std::make_unique<IncludingStreamProxy>(commentProxy.get());
auto definesProxy = std::make_unique<DefinesStreamProxy>(includeProxy.get());
definesProxy->AddDefine(ZONE_CODE_GENERATOR_DEFINE_NAME, ZONE_CODE_GENERATOR_DEFINE_VALUE);
IncludingStreamProxy includeProxy(lineStream);
lineStream = &includeProxy;
m_stream = definesProxy.get();
DefinesStreamProxy definesProxy(lineStream);
definesProxy.AddDefine(ZONE_CODE_GENERATOR_DEFINE_NAME, ZONE_CODE_GENERATOR_DEFINE_VALUE);
lineStream = &definesProxy;
m_open_streams.emplace_back(std::move(commentProxy));
m_open_streams.emplace_back(std::move(includeProxy));
m_open_streams.emplace_back(std::move(definesProxy));
}
bool HeaderFileReader::ReadHeaderFile(IDataRepository* repository)
{
std::cout << "Reading header file: " << m_filename << std::endl;
if (!OpenBaseStream())
return false;
SetupStreamProxies();
auto lexer = std::make_unique<HeaderLexer>(m_stream);
try
{
while (true)
/*while (true)
{
auto line = lineStream->NextLine();
auto line = m_stream->NextLine();
if (line.IsEof())
break;
std::cout << "Line " << line.m_filename << ":" << line.m_line_number << ": " << line.m_line << "\n";
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;
default:
std::cout << "Token UNKNOWN\n";
break;
}
lexer->PopTokens(1);
}
}
catch (const ParsingException& e)

View File

@ -3,6 +3,7 @@
#include <string>
#include "ZoneCodeGeneratorArguments.h"
#include "Parsing/IParserLineStream.h"
#include "Persistence/IDataRepository.h"
class HeaderFileReader
@ -13,8 +14,14 @@ class HeaderFileReader
const ZoneCodeGeneratorArguments* m_args;
std::string m_filename;
std::vector<std::unique_ptr<IParserLineStream>> m_open_streams;
IParserLineStream* m_stream;
bool OpenBaseStream();
void SetupStreamProxies();
public:
HeaderFileReader(const ZoneCodeGeneratorArguments* args, std::string filename);
bool ReadHeaderFile(IDataRepository* repository) const;
bool ReadHeaderFile(IDataRepository* repository);
};

View File

@ -0,0 +1,144 @@
#include "HeaderLexer.h"
HeaderLexer::HeaderLexer(IParserLineStream* stream)
: AbstractLexer(stream)
{
}
HeaderParserValue HeaderLexer::GetNextToken()
{
auto c = NextChar();
while (c != EOF)
{
switch (c)
{
case '\"':
{
return HeaderParserValue::String(GetPreviousCharacterPos(), new std::string(ReadString()));
}
case '<':
{
if (!IsLineEnd())
{
const auto pos = GetPreviousCharacterPos();
const auto nextChar = PeekChar();
if (nextChar == '=')
{
NextChar();
return HeaderParserValue::LessEqual(pos);
}
if (nextChar == '<')
{
NextChar();
return HeaderParserValue::ShiftLeft(pos);
}
}
return HeaderParserValue::Character(GetPreviousCharacterPos(), static_cast<char>(c));
}
case '>':
{
if (!IsLineEnd())
{
const auto pos = GetPreviousCharacterPos();
const auto nextChar = PeekChar();
if (nextChar == '=')
{
NextChar();
return HeaderParserValue::GreaterEqual(pos);
}
if (nextChar == '>')
{
NextChar();
return HeaderParserValue::ShiftRight(pos);
}
}
return HeaderParserValue::Character(GetPreviousCharacterPos(), static_cast<char>(c));
}
case '=':
{
if (NextCharInLineIs('='))
{
const auto pos = GetPreviousCharacterPos();
NextChar();
return HeaderParserValue::Equals(pos);
}
return HeaderParserValue::Character(GetPreviousCharacterPos(), static_cast<char>(c));
}
case '&':
{
if (NextCharInLineIs('&'))
{
const auto pos = GetPreviousCharacterPos();
NextChar();
return HeaderParserValue::LogicalAnd(pos);
}
return HeaderParserValue::Character(GetPreviousCharacterPos(), static_cast<char>(c));
}
case '|':
{
if (NextCharInLineIs('|'))
{
const auto pos = GetPreviousCharacterPos();
NextChar();
return HeaderParserValue::LogicalOr(pos);
}
return HeaderParserValue::Character(GetPreviousCharacterPos(), static_cast<char>(c));
}
case '!':
{
if (NextCharInLineIs('='))
{
const auto pos = GetPreviousCharacterPos();
NextChar();
return HeaderParserValue::NotEqual(pos);
}
return HeaderParserValue::Character(GetPreviousCharacterPos(), static_cast<char>(c));
}
default:
{
if (isspace(c))
break;
if(isdigit(c))
{
const auto pos = GetPreviousCharacterPos();
bool isFloatingPointValue;
double doubleValue;
int integerValue;
ReadNumber(isFloatingPointValue, doubleValue, integerValue);
if (isFloatingPointValue)
return HeaderParserValue::FloatingPoint(pos, doubleValue);
return HeaderParserValue::Integer(pos, integerValue);
}
if (isalpha(c) || c == '_')
return HeaderParserValue::Identifier(GetPreviousCharacterPos(), new std::string(ReadIdentifier()));
return HeaderParserValue::Character(GetPreviousCharacterPos(), static_cast<char>(c));
}
}
c = NextChar();
}
return HeaderParserValue::EndOfFile(TokenPos());
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "HeaderParserValue.h"
#include "Parsing/AbstractLexer.h"
class HeaderLexer final : public AbstractLexer<HeaderParserValue>
{
protected:
HeaderParserValue GetNextToken() override;
public:
explicit HeaderLexer(IParserLineStream* stream);
};

View File

@ -0,0 +1,6 @@
#pragma once
class HeaderParser
{
};

View File

@ -0,0 +1,181 @@
#include "HeaderParserValue.h"
#include <cassert>
HeaderParserValue HeaderParserValue::Invalid(const TokenPos pos)
{
HeaderParserValue pv(pos, HeaderParserValueType::INVALID);
return pv;
}
HeaderParserValue HeaderParserValue::EndOfFile(const TokenPos pos)
{
HeaderParserValue pv(pos, HeaderParserValueType::END_OF_FILE);
return pv;
}
HeaderParserValue HeaderParserValue::Character(const TokenPos pos, const char c)
{
HeaderParserValue pv(pos, HeaderParserValueType::CHARACTER);
pv.m_value.char_value = c;
return pv;
}
HeaderParserValue HeaderParserValue::ShiftLeft(const TokenPos pos)
{
HeaderParserValue pv(pos, HeaderParserValueType::SHIFT_LEFT);
return pv;
}
HeaderParserValue HeaderParserValue::ShiftRight(const TokenPos pos)
{
HeaderParserValue pv(pos, HeaderParserValueType::SHIFT_RIGHT);
return pv;
}
HeaderParserValue HeaderParserValue::Equals(const TokenPos pos)
{
HeaderParserValue pv(pos, HeaderParserValueType::EQUALS);
return pv;
}
HeaderParserValue HeaderParserValue::NotEqual(const TokenPos pos)
{
HeaderParserValue pv(pos, HeaderParserValueType::NOT_EQUAL);
return pv;
}
HeaderParserValue HeaderParserValue::GreaterEqual(const TokenPos pos)
{
HeaderParserValue pv(pos, HeaderParserValueType::GREATER_EQUAL);
return pv;
}
HeaderParserValue HeaderParserValue::LessEqual(const TokenPos pos)
{
HeaderParserValue pv(pos, HeaderParserValueType::LESS_EQUAL);
return pv;
}
HeaderParserValue HeaderParserValue::LogicalAnd(const TokenPos pos)
{
HeaderParserValue pv(pos, HeaderParserValueType::LOGICAL_AND);
return pv;
}
HeaderParserValue HeaderParserValue::LogicalOr(const TokenPos pos)
{
HeaderParserValue pv(pos, HeaderParserValueType::LOGICAL_OR);
return pv;
}
HeaderParserValue HeaderParserValue::Integer(const TokenPos pos, const int value)
{
HeaderParserValue pv(pos, HeaderParserValueType::INTEGER);
pv.m_value.int_value = value;
return pv;
}
HeaderParserValue HeaderParserValue::FloatingPoint(const TokenPos pos, const double value)
{
HeaderParserValue pv(pos, HeaderParserValueType::FLOATING_POINT);
pv.m_value.double_value = value;
return pv;
}
HeaderParserValue HeaderParserValue::String(const TokenPos pos, std::string* stringValue)
{
HeaderParserValue pv(pos, HeaderParserValueType::STRING);
pv.m_value.string_value = stringValue;
return pv;
}
HeaderParserValue HeaderParserValue::Identifier(const TokenPos pos, std::string* identifier)
{
HeaderParserValue pv(pos, HeaderParserValueType::IDENTIFIER);
pv.m_value.string_value = identifier;
return pv;
}
HeaderParserValue HeaderParserValue::TypeName(const TokenPos pos, std::string* typeName)
{
HeaderParserValue pv(pos, HeaderParserValueType::TYPE_NAME);
pv.m_value.string_value = typeName;
return pv;
}
HeaderParserValue::HeaderParserValue(const TokenPos pos, const HeaderParserValueType type)
: m_pos(pos),
m_type(type),
m_value()
{
}
HeaderParserValue::~HeaderParserValue()
{
switch (m_type)
{
case HeaderParserValueType::STRING:
case HeaderParserValueType::IDENTIFIER:
case HeaderParserValueType::TYPE_NAME:
delete m_value.string_value;
break;
default:
break;
}
m_value = ValueType();
}
HeaderParserValue::HeaderParserValue(HeaderParserValue&& other) noexcept
: m_type(other.m_type),
m_value(other.m_value)
{
other.m_value = ValueType();
}
HeaderParserValue& HeaderParserValue::operator=(HeaderParserValue&& other) noexcept
{
m_type = other.m_type;
m_value = other.m_value;
other.m_value = ValueType();
return *this;
}
char HeaderParserValue::CharacterValue() const
{
assert(m_type == HeaderParserValueType::CHARACTER);
return m_value.char_value;
}
int HeaderParserValue::IntegerValue() const
{
assert(m_type == HeaderParserValueType::INTEGER);
return m_value.int_value;
}
double HeaderParserValue::FloatingPointValue() const
{
assert(m_type == HeaderParserValueType::FLOATING_POINT);
return m_value.double_value;
}
std::string& HeaderParserValue::StringValue() const
{
assert(m_type == HeaderParserValueType::STRING);
return *m_value.string_value;
}
std::string& HeaderParserValue::IdentifierValue() const
{
assert(m_type == HeaderParserValueType::IDENTIFIER);
return *m_value.string_value;
}
std::string& HeaderParserValue::TypeNameValue() const
{
assert(m_type == HeaderParserValueType::TYPE_NAME);
return *m_value.string_value;
}

View File

@ -0,0 +1,86 @@
#pragma once
#include <string>
#include "Utils/ClassUtils.h"
#include "Parsing/TokenPos.h"
enum class HeaderParserValueType
{
// Meta tokens
INVALID,
END_OF_FILE,
// Single character
CHARACTER,
// Symbol tokens
SHIFT_LEFT,
SHIFT_RIGHT,
EQUALS,
NOT_EQUAL,
GREATER_EQUAL,
LESS_EQUAL,
LOGICAL_AND,
LOGICAL_OR,
// Generic token types
INTEGER,
FLOATING_POINT,
STRING,
IDENTIFIER,
// Parser created
TYPE_NAME,
// End
MAX
};
class HeaderParserValue
{
public:
TokenPos m_pos;
HeaderParserValueType m_type;
union ValueType
{
char char_value;
int int_value;
double double_value;
std::string* string_value;
} m_value;
static HeaderParserValue Invalid(TokenPos pos);
static HeaderParserValue EndOfFile(TokenPos pos);
static HeaderParserValue Character(TokenPos pos, char c);
static HeaderParserValue ShiftLeft(TokenPos pos);
static HeaderParserValue ShiftRight(TokenPos pos);
static HeaderParserValue Equals(TokenPos pos);
static HeaderParserValue NotEqual(TokenPos pos);
static HeaderParserValue GreaterEqual(TokenPos pos);
static HeaderParserValue LessEqual(TokenPos pos);
static HeaderParserValue LogicalAnd(TokenPos pos);
static HeaderParserValue LogicalOr(TokenPos pos);
static HeaderParserValue Integer(TokenPos pos, int value);
static HeaderParserValue FloatingPoint(TokenPos pos, double value);
static HeaderParserValue String(TokenPos pos, std::string* stringValue);
static HeaderParserValue Identifier(TokenPos pos, std::string* identifier);
static HeaderParserValue TypeName(TokenPos pos, std::string* typeName);
private:
HeaderParserValue(TokenPos pos, HeaderParserValueType type);
public:
~HeaderParserValue();
HeaderParserValue(const HeaderParserValue& other) = delete;
HeaderParserValue(HeaderParserValue&& other) noexcept;
HeaderParserValue& operator=(const HeaderParserValue& other) = delete;
HeaderParserValue& operator=(HeaderParserValue&& other) noexcept;
_NODISCARD char CharacterValue() const;
_NODISCARD int IntegerValue() const;
_NODISCARD double FloatingPointValue() const;
_NODISCARD std::string& StringValue() const;
_NODISCARD std::string& IdentifierValue() const;
_NODISCARD std::string& TypeNameValue() const;
};

View File

@ -1,5 +1,13 @@
#include "IParserLineStream.h"
const std::string ParserLine::EMPTY_STRING;
ParserLine::ParserLine()
: m_filename(EMPTY_STRING),
m_line_number(0)
{
}
ParserLine::ParserLine(const std::string& filename, const int lineNumber, std::string line)
: m_filename(filename),
m_line_number(lineNumber),

View File

@ -6,11 +6,14 @@
class ParserLine
{
static const std::string EMPTY_STRING;
public:
const std::string& m_filename;
const int m_line_number;
std::reference_wrapper<const std::string> m_filename;
int m_line_number;
std::string m_line;
ParserLine();
ParserLine(const std::string& filename, int lineNumber, std::string line);
_NODISCARD bool IsEof() const;

View File

@ -5,8 +5,6 @@
namespace fs = std::filesystem;
const std::string ParserFilesystemStream::EMPTY_FILE_NAME;
ParserFilesystemStream::FileInfo::FileInfo(std::string filePath)
: m_file_path(std::move(filePath)),
m_stream(m_file_path),
@ -31,7 +29,7 @@ ParserLine ParserFilesystemStream::NextLine()
auto hasLength = false;
if (m_files.empty())
return ParserLine(EMPTY_FILE_NAME, 0, std::string());
return ParserLine();
while(!m_files.empty())
{
@ -67,7 +65,7 @@ ParserLine ParserFilesystemStream::NextLine()
m_files.pop();
}
return ParserLine(EMPTY_FILE_NAME, 0, std::string());
return ParserLine();
}
bool ParserFilesystemStream::IncludeFile(const std::string& filename)

View File

@ -7,8 +7,6 @@
class ParserFilesystemStream final : public IParserLineStream
{
static const std::string EMPTY_FILE_NAME;
class FileInfo
{
public: