--- /dev/null
+
+#pragma once
+
+#include <string>
+
+#include <exceptions/exception.hpp>
+#include <message/id.hpp>
+
+namespace YAMML
+{
+
+namespace Exceptions
+{
+
+class ParseException : public Exception
+{
+public:
+ ParseException(
+ const std::string& source,
+ std::size_t line,
+ std::size_t column,
+ Message::MessageID id
+ ) : Exception("ParseException: MessageID=" + std::to_string(static_cast<int>(id))),
+ Source(source),
+ Line{line},
+ Column{column},
+ ID{id}
+ {
+ }
+
+ std::string Source;
+ std::size_t Line;
+ std::size_t Column;
+ Message::MessageID ID;
+};
+
+} // namespace Exceptions
+
+} // namespace YAMML
--- /dev/null
+
+#pragma once
+
+#include <pegtl.hh>
+#include <pegtl/contrib/changes.hh>
+
+#include "error_control.hpp"
+
+namespace YAMML
+{
+
+namespace Parser
+{
+
+template<typename TRule>
+class Control : public ErrorControl<TRule>
+{
+};
+
+} // namespace Parser
+
+} // namespace YAMML
--- /dev/null
+
+#pragma once
+
+#include <pegtl.hh>
+
+#include <exceptions/parseexception.hpp>
+#include <message/id.hpp>
+
+namespace YAMML
+{
+
+namespace Parser
+{
+
+template<typename TInput>
+void ThrowParseException(const TInput& in, Message::MessageID id)
+{
+ throw Exceptions::ParseException(in.source(), in.line(), in.column(), id);
+}
+
+template<typename TRule>
+class ErrorControl : public pegtl::normal<TRule>
+{
+public:
+ static const Message::MessageID ID;
+
+ template<typename TInput, typename... TStates>
+ static void raise(const TInput& in, TStates&&...)
+ {
+ ThrowParseException(in, ID);
+ }
+};
+
+} // namespace Parser
+
+} // namespace YAMML