2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-06-26 06:11:53 +00:00
Files
OpenAssetTools/src/ZoneCodeGeneratorLib/Parsing/Header/Impl/HeaderLexer.cpp
2023-11-19 21:07:21 +00:00

173 lines
5.1 KiB
C++

#include "HeaderLexer.h"
HeaderLexer::HeaderLexer(IParserLineStream* stream)
: AbstractLexer(stream)
{
PrepareKeywords();
}
void HeaderLexer::PrepareKeywords()
{
m_keywords["__declspec"] = HeaderParserValueType::DECLSPEC;
m_keywords["align"] = HeaderParserValueType::ALIGN;
m_keywords["alignas"] = HeaderParserValueType::ALIGNAS;
m_keywords["char"] = HeaderParserValueType::CHAR;
m_keywords["const"] = HeaderParserValueType::CONST;
m_keywords["enum"] = HeaderParserValueType::ENUM;
m_keywords["int"] = HeaderParserValueType::INT;
m_keywords["long"] = HeaderParserValueType::LONG;
m_keywords["namespace"] = HeaderParserValueType::NAMESPACE;
m_keywords["short"] = HeaderParserValueType::SHORT;
m_keywords["struct"] = HeaderParserValueType::STRUCT;
m_keywords["typedef"] = HeaderParserValueType::TYPEDEF;
m_keywords["union"] = HeaderParserValueType::UNION;
m_keywords["unsigned"] = HeaderParserValueType::UNSIGNED;
}
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;
const auto pos = GetPreviousCharacterPos();
if (isdigit(c))
{
bool isFloatingPointValue;
bool hasSignPrefix;
double doubleValue;
int integerValue;
ReadNumber(isFloatingPointValue, hasSignPrefix, doubleValue, integerValue);
if (isFloatingPointValue)
return HeaderParserValue::FloatingPoint(pos, doubleValue);
return HeaderParserValue::Integer(pos, integerValue);
}
if (isalpha(c) || c == '_')
{
auto identifier = ReadIdentifier();
const auto foundKeyword = m_keywords.find(identifier);
if (foundKeyword != m_keywords.end())
return HeaderParserValue::Keyword(pos, foundKeyword->second);
return HeaderParserValue::Identifier(pos, new std::string(std::move(identifier)));
}
return HeaderParserValue::Character(pos, static_cast<char>(c));
}
}
c = NextChar();
}
return HeaderParserValue::EndOfFile(TokenPos());
}