#ifndef __PLASP__PDDL__EXPRESSIONS__AT_H #define __PLASP__PDDL__EXPRESSIONS__AT_H #include #include #include namespace plasp { namespace pddl { namespace expressions { //////////////////////////////////////////////////////////////////////////////////////////////////// // // At // //////////////////////////////////////////////////////////////////////////////////////////////////// class At: public ExpressionCRTP { public: static const Expression::Type ExpressionType = Expression::Type::At; template static AtPointer parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression); static const size_t TimePointStart = std::numeric_limits::max(); static const size_t TimePointEnd = std::numeric_limits::max() - 1; public: At(); size_t timePoint() const; const Expression *argument() const; private: void setArgument(const Expression *argument); void setArgument(ExpressionPointer &&argument); size_t m_timePoint; const Expression *m_argument; ExpressionPointer m_argumentStorage; }; //////////////////////////////////////////////////////////////////////////////////////////////////// template AtPointer At::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression) { auto &parser = context.parser; const auto position = parser.position(); if (!parser.probe("(") || !parser.probeIdentifier("at", isIdentifier)) { parser.seek(position); return nullptr; } size_t timePoint; const auto timePointPosition = parser.position(); if (parser.probeIdentifier("start", isIdentifier)) timePoint = TimePointStart; else if (parser.probeIdentifier("end", isIdentifier)) timePoint = TimePointEnd; else if (parser.probeNumber()) { parser.seek(timePointPosition); timePoint = parser.parse(); } else { parser.seek(position); return nullptr; } auto expression = std::make_unique(At()); expression->m_timePoint = timePoint; context.parser.skipWhiteSpace(); // Parse argument expression->setArgument(parseExpression(context, expressionContext)); parser.expect(")"); return expression; } //////////////////////////////////////////////////////////////////////////////////////////////////// } } } #endif