mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
Use SimpleExpressionInterpreter in DefinesStreamProxy and expand defines and defined expressions before parsing
This commit is contained in:
parent
7cce0e387e
commit
a36d1c430a
@ -1,15 +0,0 @@
|
|||||||
#pragma options TEST(asdf, bla)
|
|
||||||
#pragma switch TEST_SWITCH
|
|
||||||
|
|
||||||
#ifdef TEST_SWITCH
|
|
||||||
#define SVAL "1"
|
|
||||||
#else
|
|
||||||
#define SVAL "0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#pragma filename "lemao_" + TEST + SVAL + ".txt"
|
|
||||||
|
|
||||||
HAHA TEST
|
|
||||||
#ifdef TEST_SWITCH
|
|
||||||
kekw
|
|
||||||
#endif
|
|
@ -1,16 +0,0 @@
|
|||||||
#include "DefinesDirectiveExpressionSequence.h"
|
|
||||||
|
|
||||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
|
||||||
#include "DefinesExpressionMatchers.h"
|
|
||||||
|
|
||||||
DefinesDirectiveExpressionSequence::DefinesDirectiveExpressionSequence()
|
|
||||||
{
|
|
||||||
const SimpleMatcherFactory create(this);
|
|
||||||
AddLabeledMatchers(DefinesExpressionMatchers().Expression(this), SimpleExpressionMatchers::LABEL_EXPRESSION);
|
|
||||||
AddMatchers(create.Label(SimpleExpressionMatchers::LABEL_EXPRESSION));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DefinesDirectiveExpressionSequence::ProcessMatch(DefinesDirectiveParsingState* state, SequenceResult<SimpleParserValue>& result) const
|
|
||||||
{
|
|
||||||
state->m_expression = DefinesExpressionMatchers(state).ProcessExpression(result);
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "DefinesDirectiveParser.h"
|
|
||||||
#include "DefinesDirectiveParsingState.h"
|
|
||||||
|
|
||||||
class DefinesDirectiveExpressionSequence final : public DefinesDirectiveParser::sequence_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DefinesDirectiveExpressionSequence();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void ProcessMatch(DefinesDirectiveParsingState* state, SequenceResult<SimpleParserValue>& result) const override;
|
|
||||||
};
|
|
@ -1,22 +0,0 @@
|
|||||||
#include "DefinesDirectiveParser.h"
|
|
||||||
|
|
||||||
#include "DefinesDirectiveExpressionSequence.h"
|
|
||||||
|
|
||||||
DefinesDirectiveParser::DefinesDirectiveParser(ILexer<SimpleParserValue>* lexer, const std::map<std::string, DefinesStreamProxy::Define>& defines)
|
|
||||||
: AbstractParser<SimpleParserValue, DefinesDirectiveParsingState>(lexer, std::make_unique<DefinesDirectiveParsingState>(defines))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<AbstractParser<SimpleParserValue, DefinesDirectiveParsingState>::sequence_t*>& DefinesDirectiveParser::GetTestsForState()
|
|
||||||
{
|
|
||||||
static std::vector<sequence_t*> sequences
|
|
||||||
{
|
|
||||||
new DefinesDirectiveExpressionSequence()
|
|
||||||
};
|
|
||||||
return sequences;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<ISimpleExpression> DefinesDirectiveParser::GetParsedExpression() const
|
|
||||||
{
|
|
||||||
return std::move(m_state->m_expression);
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "DefinesDirectiveParsingState.h"
|
|
||||||
#include "Parsing/Impl/AbstractParser.h"
|
|
||||||
#include "Parsing/Simple/SimpleParserValue.h"
|
|
||||||
|
|
||||||
class DefinesDirectiveParser final : public AbstractParser<SimpleParserValue, DefinesDirectiveParsingState>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DefinesDirectiveParser(ILexer<SimpleParserValue>* lexer, const std::map<std::string, DefinesStreamProxy::Define>& defines);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
const std::vector<sequence_t*>& GetTestsForState() override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
_NODISCARD std::unique_ptr<ISimpleExpression> GetParsedExpression() const;
|
|
||||||
};
|
|
@ -1,6 +0,0 @@
|
|||||||
#include "DefinesDirectiveParsingState.h"
|
|
||||||
|
|
||||||
DefinesDirectiveParsingState::DefinesDirectiveParsingState(const std::map<std::string, DefinesStreamProxy::Define>& defines)
|
|
||||||
: m_defines(defines)
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "Parsing/Impl/DefinesStreamProxy.h"
|
|
||||||
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
|
||||||
|
|
||||||
class DefinesDirectiveParsingState
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const std::map<std::string, DefinesStreamProxy::Define>& m_defines;
|
|
||||||
std::unique_ptr<ISimpleExpression> m_expression;
|
|
||||||
|
|
||||||
explicit DefinesDirectiveParsingState(const std::map<std::string, DefinesStreamProxy::Define>& defines);
|
|
||||||
};
|
|
@ -1,37 +0,0 @@
|
|||||||
#include "DefinesExpressionMatchers.h"
|
|
||||||
|
|
||||||
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
|
|
||||||
|
|
||||||
DefinesExpressionMatchers::DefinesExpressionMatchers()
|
|
||||||
: DefinesExpressionMatchers(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
DefinesExpressionMatchers::DefinesExpressionMatchers(const DefinesDirectiveParsingState* state)
|
|
||||||
: SimpleExpressionMatchers(true, false, true, true, false),
|
|
||||||
m_state(state)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<SimpleExpressionMatchers::matcher_t> DefinesExpressionMatchers::ParseOperandExtension(const supplier_t* labelSupplier) const
|
|
||||||
{
|
|
||||||
const SimpleMatcherFactory create(labelSupplier);
|
|
||||||
|
|
||||||
return create.And({
|
|
||||||
create.Keyword("defined"),
|
|
||||||
create.Char('('),
|
|
||||||
create.Identifier().Capture(CAPTURE_DEFINE_NAME),
|
|
||||||
create.Char(')'),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<ISimpleExpression> DefinesExpressionMatchers::ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const
|
|
||||||
{
|
|
||||||
const auto& defineCapture = result.NextCapture(CAPTURE_DEFINE_NAME);
|
|
||||||
|
|
||||||
assert(m_state);
|
|
||||||
if(m_state && m_state->m_defines.find(defineCapture.IdentifierValue()) != m_state->m_defines.end())
|
|
||||||
return std::make_unique<SimpleExpressionValue>(1);
|
|
||||||
|
|
||||||
return std::make_unique<SimpleExpressionValue>(0);
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "DefinesDirectiveParsingState.h"
|
|
||||||
#include "Parsing/Simple/Expression/SimpleExpressionMatchers.h"
|
|
||||||
|
|
||||||
class DefinesExpressionMatchers final : public SimpleExpressionMatchers
|
|
||||||
{
|
|
||||||
static constexpr auto CAPTURE_DEFINE_NAME = CAPTURE_OFFSET_EXPRESSION_EXT + 1;
|
|
||||||
|
|
||||||
const DefinesDirectiveParsingState* m_state;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::unique_ptr<matcher_t> ParseOperandExtension(const supplier_t* labelSupplier) const override;
|
|
||||||
std::unique_ptr<ISimpleExpression> ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
DefinesExpressionMatchers();
|
|
||||||
explicit DefinesExpressionMatchers(const DefinesDirectiveParsingState* state);
|
|
||||||
};
|
|
@ -1,13 +1,14 @@
|
|||||||
#include "DefinesStreamProxy.h"
|
#include "DefinesStreamProxy.h"
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "Utils/ClassUtils.h"
|
#include "Utils/ClassUtils.h"
|
||||||
#include "AbstractParser.h"
|
#include "AbstractParser.h"
|
||||||
#include "ParserSingleInputStream.h"
|
#include "ParserSingleInputStream.h"
|
||||||
#include "Defines/DefinesDirectiveParser.h"
|
|
||||||
#include "Parsing/ParsingException.h"
|
#include "Parsing/ParsingException.h"
|
||||||
|
#include "Parsing/Simple/SimpleExpressionInterpreter.h"
|
||||||
#include "Parsing/Simple/SimpleLexer.h"
|
#include "Parsing/Simple/SimpleLexer.h"
|
||||||
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
#include "Parsing/Simple/Expression/ISimpleExpression.h"
|
||||||
#include "Parsing/Simple/Expression/SimpleExpressionMatchers.h"
|
#include "Parsing/Simple/Expression/SimpleExpressionMatchers.h"
|
||||||
@ -34,7 +35,7 @@ DefinesStreamProxy::Define::Define(std::string name, std::string value)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DefinesStreamProxy::Define::Render(const std::vector<std::string>& parameterValues)
|
std::string DefinesStreamProxy::Define::Render(const std::vector<std::string>& parameterValues) const
|
||||||
{
|
{
|
||||||
if (parameterValues.empty() || m_parameter_positions.empty())
|
if (parameterValues.empty() || m_parameter_positions.empty())
|
||||||
return m_value;
|
return m_value;
|
||||||
@ -279,25 +280,17 @@ bool DefinesStreamProxy::MatchUndefDirective(const ParserLine& line, const unsig
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ISimpleExpression> DefinesStreamProxy::ParseExpression(const std::string& expressionString) const
|
std::unique_ptr<ISimpleExpression> DefinesStreamProxy::ParseExpression(std::string expressionString) const
|
||||||
{
|
{
|
||||||
std::istringstream ss(expressionString);
|
ParserLine pseudoLine(nullptr, 1, std::move(expressionString));
|
||||||
|
ExpandDefinedExpressions(pseudoLine);
|
||||||
|
ExpandDefines(pseudoLine);
|
||||||
|
|
||||||
|
std::istringstream ss(pseudoLine.m_line);
|
||||||
ParserSingleInputStream inputStream(ss, "defines directive expression");
|
ParserSingleInputStream inputStream(ss, "defines directive expression");
|
||||||
|
|
||||||
SimpleLexer::Config lexerConfig;
|
const SimpleExpressionInterpreter expressionInterpreter(&inputStream);
|
||||||
lexerConfig.m_emit_new_line_tokens = false;
|
return expressionInterpreter.Evaluate();
|
||||||
lexerConfig.m_read_integer_numbers = true;
|
|
||||||
lexerConfig.m_read_floating_point_numbers = true;
|
|
||||||
lexerConfig.m_read_strings = true;
|
|
||||||
SimpleExpressionMatchers().ApplyTokensToLexerConfig(lexerConfig);
|
|
||||||
|
|
||||||
SimpleLexer lexer(&inputStream, std::move(lexerConfig));
|
|
||||||
DefinesDirectiveParser parser(&lexer, m_defines);
|
|
||||||
|
|
||||||
if (!parser.Parse())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return parser.GetParsedExpression();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DefinesStreamProxy::MatchIfDirective(const ParserLine& line, const unsigned directiveStartPosition, const unsigned directiveEndPosition)
|
bool DefinesStreamProxy::MatchIfDirective(const ParserLine& line, const unsigned directiveStartPosition, const unsigned directiveEndPosition)
|
||||||
@ -485,7 +478,7 @@ bool DefinesStreamProxy::MatchDirectives(const ParserLine& line)
|
|||||||
|| MatchEndifDirective(line, directiveStartPos, directiveEndPos);
|
|| MatchEndifDirective(line, directiveStartPos, directiveEndPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DefinesStreamProxy::FindDefineForWord(const ParserLine& line, const unsigned wordStart, const unsigned wordEnd, Define*& value)
|
bool DefinesStreamProxy::FindDefineForWord(const ParserLine& line, const unsigned wordStart, const unsigned wordEnd, const Define*& value) const
|
||||||
{
|
{
|
||||||
const std::string word(line.m_line, wordStart, wordEnd - wordStart);
|
const std::string word(line.m_line, wordStart, wordEnd - wordStart);
|
||||||
const auto foundEntry = m_defines.find(word);
|
const auto foundEntry = m_defines.find(word);
|
||||||
@ -560,7 +553,58 @@ void DefinesStreamProxy::ExtractParametersFromDefineUsage(const ParserLine& line
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinesStreamProxy::ExpandDefines(ParserLine& line)
|
bool DefinesStreamProxy::MatchDefinedExpression(const ParserLine& line, unsigned& pos, std::string& definitionName)
|
||||||
|
{
|
||||||
|
unsigned currentPos = pos;
|
||||||
|
|
||||||
|
if (!MatchNextCharacter(line, currentPos, '('))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto nameStartPos = currentPos;
|
||||||
|
if (!ExtractIdentifier(line, currentPos))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto nameEndPos = currentPos;
|
||||||
|
if (!MatchNextCharacter(line, currentPos, ')'))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pos = currentPos;
|
||||||
|
definitionName = line.m_line.substr(nameStartPos, nameEndPos - nameStartPos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefinesStreamProxy::ExpandDefinedExpressions(ParserLine& line) const
|
||||||
|
{
|
||||||
|
auto currentPos = 0u;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const auto definedPos = line.m_line.find(DEFINED_KEYWORD, currentPos);
|
||||||
|
if (definedPos == std::string::npos)
|
||||||
|
break;
|
||||||
|
|
||||||
|
currentPos = definedPos;
|
||||||
|
|
||||||
|
if (definedPos > 0 && !isspace(line.m_line[definedPos - 1]))
|
||||||
|
{
|
||||||
|
currentPos += std::char_traits<char>::length(DEFINED_KEYWORD);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto definitionEndPos = currentPos + std::char_traits<char>::length(DEFINED_KEYWORD);
|
||||||
|
std::string definitionName;
|
||||||
|
if (!MatchDefinedExpression(line, definitionEndPos, definitionName))
|
||||||
|
{
|
||||||
|
currentPos += std::char_traits<char>::length(DEFINED_KEYWORD);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto entry = m_defines.find(definitionName);
|
||||||
|
line.m_line.replace(currentPos, definitionEndPos - currentPos, entry != m_defines.end() ? "1" : "0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefinesStreamProxy::ExpandDefines(ParserLine& line) const
|
||||||
{
|
{
|
||||||
bool usesDefines;
|
bool usesDefines;
|
||||||
auto defineIterations = 0u;
|
auto defineIterations = 0u;
|
||||||
@ -575,7 +619,7 @@ void DefinesStreamProxy::ExpandDefines(ParserLine& line)
|
|||||||
auto wordStart = 0u;
|
auto wordStart = 0u;
|
||||||
auto lastWordEnd = 0u;
|
auto lastWordEnd = 0u;
|
||||||
auto inWord = false;
|
auto inWord = false;
|
||||||
Define* value;
|
const Define* value;
|
||||||
std::ostringstream str;
|
std::ostringstream str;
|
||||||
|
|
||||||
for (auto i = 0u; i < line.m_line.size(); i++)
|
for (auto i = 0u; i < line.m_line.size(); i++)
|
||||||
|
@ -18,6 +18,7 @@ class DefinesStreamProxy final : public AbstractDirectiveStreamProxy
|
|||||||
static constexpr const char* IFNDEF_DIRECTIVE = "ifndef";
|
static constexpr const char* IFNDEF_DIRECTIVE = "ifndef";
|
||||||
static constexpr const char* ELSE_DIRECTIVE = "else";
|
static constexpr const char* ELSE_DIRECTIVE = "else";
|
||||||
static constexpr const char* ENDIF_DIRECTIVE = "endif";
|
static constexpr const char* ENDIF_DIRECTIVE = "endif";
|
||||||
|
static constexpr const char* DEFINED_KEYWORD = "defined";
|
||||||
|
|
||||||
static constexpr auto MAX_DEFINE_ITERATIONS = 128u;
|
static constexpr auto MAX_DEFINE_ITERATIONS = 128u;
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ public:
|
|||||||
Define();
|
Define();
|
||||||
Define(std::string name, std::string value);
|
Define(std::string name, std::string value);
|
||||||
void IdentifyParameters(const std::vector<std::string>& parameterNames);
|
void IdentifyParameters(const std::vector<std::string>& parameterNames);
|
||||||
std::string Render(const std::vector<std::string>& parameterValues);
|
_NODISCARD std::string Render(const std::vector<std::string>& parameterValues) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -77,17 +78,20 @@ private:
|
|||||||
_NODISCARD bool MatchDirectives(const ParserLine& line);
|
_NODISCARD bool MatchDirectives(const ParserLine& line);
|
||||||
|
|
||||||
static void ExtractParametersFromDefineUsage(const ParserLine& line, unsigned parameterStart, unsigned& parameterEnd, std::vector<std::string>& parameterValues);
|
static void ExtractParametersFromDefineUsage(const ParserLine& line, unsigned parameterStart, unsigned& parameterEnd, std::vector<std::string>& parameterValues);
|
||||||
bool FindDefineForWord(const ParserLine& line, unsigned wordStart, unsigned wordEnd, Define*& value);
|
bool FindDefineForWord(const ParserLine& line, unsigned wordStart, unsigned wordEnd, const Define*& value) const;
|
||||||
|
|
||||||
|
static bool MatchDefinedExpression(const ParserLine& line, unsigned& pos, std::string& definitionName);
|
||||||
|
void ExpandDefinedExpressions(ParserLine& line) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DefinesStreamProxy(IParserLineStream* stream, bool skipDirectiveLines = false);
|
explicit DefinesStreamProxy(IParserLineStream* stream, bool skipDirectiveLines = false);
|
||||||
|
|
||||||
void AddDefine(Define define);
|
void AddDefine(Define define);
|
||||||
void Undefine(const std::string& name);
|
void Undefine(const std::string& name);
|
||||||
|
|
||||||
void ExpandDefines(ParserLine& line);
|
void ExpandDefines(ParserLine& line) const;
|
||||||
|
|
||||||
_NODISCARD std::unique_ptr<ISimpleExpression> ParseExpression(const std::string& expressionString) const;
|
_NODISCARD std::unique_ptr<ISimpleExpression> ParseExpression(std::string expressionString) const;
|
||||||
|
|
||||||
ParserLine NextLine() override;
|
ParserLine NextLine() override;
|
||||||
bool IncludeFile(const std::string& filename) override;
|
bool IncludeFile(const std::string& filename) override;
|
||||||
|
@ -92,9 +92,7 @@ bool TemplatingStreamProxy::MatchOptionsDirective(const ParserLine& line, const
|
|||||||
if (!ExtractIdentifier(line, currentPosition))
|
if (!ExtractIdentifier(line, currentPosition))
|
||||||
throw ParsingException(CreatePos(line, currentPosition), "Invalid options directive.");
|
throw ParsingException(CreatePos(line, currentPosition), "Invalid options directive.");
|
||||||
|
|
||||||
std::ostringstream optionValueBuilder;
|
options.emplace_back(line.m_line.substr(optionStartPosition, currentPosition - optionStartPosition));
|
||||||
optionValueBuilder << '"' << line.m_line.substr(optionStartPosition, currentPosition - optionStartPosition) << '"';
|
|
||||||
options.emplace_back(optionValueBuilder.str());
|
|
||||||
|
|
||||||
firstArg = false;
|
firstArg = false;
|
||||||
}
|
}
|
||||||
@ -126,10 +124,7 @@ bool TemplatingStreamProxy::MatchFilenameDirective(const ParserLine& line, const
|
|||||||
if (expressionString.empty())
|
if (expressionString.empty())
|
||||||
throw ParsingException(CreatePos(line, currentPosition), "Cannot pragma filename without an expression.");
|
throw ParsingException(CreatePos(line, currentPosition), "Cannot pragma filename without an expression.");
|
||||||
|
|
||||||
ParserLine expressionStringAsLine(line.m_filename, line.m_line_number, expressionString);
|
const auto expression = m_defines_proxy->ParseExpression(expressionString);
|
||||||
m_defines_proxy->ExpandDefines(expressionStringAsLine);
|
|
||||||
|
|
||||||
const auto expression = m_defines_proxy->ParseExpression(expressionStringAsLine.m_line);
|
|
||||||
if (!expression)
|
if (!expression)
|
||||||
throw ParsingException(CreatePos(line, currentPosition), "Failed to parse pragma filename expression");
|
throw ParsingException(CreatePos(line, currentPosition), "Failed to parse pragma filename expression");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user