#include "MenuMatcherFactory.h" #include "MenuExpressionMatchers.h" using namespace menu; MenuMatcherFactory::MenuMatcherFactory(const IMatcherForLabelSupplier* labelSupplier) : SimpleMatcherFactory(labelSupplier) { } MatcherFactoryWrapper MenuMatcherFactory::Text() const { return MatcherFactoryWrapper(Or({String(), Identifier()})); } MatcherFactoryWrapper MenuMatcherFactory::Numeric() const { return MatcherFactoryWrapper(Or({FloatingPoint(), Integer()})); } MatcherFactoryWrapper 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 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(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& 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& 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"); }