OpenAssetTools/src/ObjLoading/Parsing/Menu/Matcher/MenuMatcherFactory.cpp

137 lines
4.1 KiB
C++

#include "MenuMatcherFactory.h"
#include "MenuExpressionMatchers.h"
using namespace menu;
MenuMatcherFactory::MenuMatcherFactory(const IMatcherForLabelSupplier<SimpleParserValue>* labelSupplier)
: SimpleMatcherFactory(labelSupplier)
{
}
MatcherFactoryWrapper<SimpleParserValue> MenuMatcherFactory::Text() const
{
return MatcherFactoryWrapper(Or({String(), Identifier()}));
}
MatcherFactoryWrapper<SimpleParserValue> MenuMatcherFactory::Numeric() const
{
return MatcherFactoryWrapper(Or({FloatingPoint(), Integer()}));
}
MatcherFactoryWrapper<SimpleParserValue> MenuMatcherFactory::IntExpression() const
{
return MatcherFactoryWrapper(Or({
Integer().Tag(TAG_INT).Capture(CAPTURE_INT),
And({
Char('(').Capture(CAPTURE_FIRST_TOKEN),
Label(MenuExpressionMatchers::LABEL_EXPRESSION),
Char(')'),
}).Tag(TAG_EXPRESSION)
}));
}
MatcherFactoryWrapper<SimpleParserValue> MenuMatcherFactory::NumericExpression() const
{
return MatcherFactoryWrapper(Or({
Numeric().Tag(TAG_NUMERIC).Capture(CAPTURE_NUMERIC),
And({
Char('(').Capture(CAPTURE_FIRST_TOKEN),
Label(MenuExpressionMatchers::LABEL_EXPRESSION),
Char(')'),
}).Tag(TAG_EXPRESSION)
}));
}
int MenuMatcherFactory::TokenNumericIntValue(const SimpleParserValue& value)
{
if (value.m_type == SimpleParserValueType::FLOATING_POINT)
{
return static_cast<int>(value.FloatingPointValue());
}
return value.IntegerValue();
}
double MenuMatcherFactory::TokenNumericFloatingPointValue(const SimpleParserValue& value)
{
if (value.m_type == SimpleParserValueType::INTEGER)
{
return value.IntegerValue();
}
return value.FloatingPointValue();
}
std::string& MenuMatcherFactory::TokenTextValue(const SimpleParserValue& value)
{
if (value.m_type == SimpleParserValueType::IDENTIFIER)
{
return value.IdentifierValue();
}
return value.StringValue();
}
int MenuMatcherFactory::TokenIntExpressionValue(SequenceResult<SimpleParserValue>& result)
{
const auto nextTag = result.PeekTag();
assert(nextTag == TAG_INT || nextTag == TAG_EXPRESSION);
if (nextTag == TAG_INT)
{
result.NextTag();
return result.NextCapture(CAPTURE_INT).IntegerValue();
}
if (nextTag == TAG_EXPRESSION)
{
result.NextTag();
const auto expression = MenuExpressionMatchers().ProcessExpression(result);
if (!expression || !expression->IsStatic())
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Not a valid static expression");
const auto value = expression->Evaluate();
if (value.m_type != SimpleExpressionValue::Type::INT)
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Expression MUST be int type");
return value.m_int_value;
}
throw ParsingException(TokenPos(), "TokenIntExpressionValue must be expression or int");
}
double MenuMatcherFactory::TokenNumericExpressionValue(SequenceResult<SimpleParserValue>& result)
{
const auto nextTag = result.PeekTag();
assert(nextTag == TAG_NUMERIC || nextTag == TAG_EXPRESSION);
if (nextTag == TAG_NUMERIC)
{
result.NextTag();
return TokenNumericFloatingPointValue(result.NextCapture(CAPTURE_NUMERIC));
}
if (nextTag == TAG_EXPRESSION)
{
result.NextTag();
const auto expression = MenuExpressionMatchers().ProcessExpression(result);
if (!expression || !expression->IsStatic())
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Not a valid static expression");
const auto value = expression->Evaluate();
if (value.m_type == SimpleExpressionValue::Type::INT)
return value.m_int_value;
if (value.m_type == SimpleExpressionValue::Type::DOUBLE)
return value.m_double_value;
throw ParsingException(result.NextCapture(CAPTURE_FIRST_TOKEN).GetPos(), "Expression MUST be numeric type");
}
throw ParsingException(TokenPos(), "TokenNumericExpressionValue must be expression or numeric");
}