/
newline.hpp
86 lines (73 loc) · 2.39 KB
/
newline.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Copyright (C) 2020-2024 Jonathan Müller and lexy contributors
// SPDX-License-Identifier: BSL-1.0
#ifndef LEXY_DSL_NEWLINE_HPP_INCLUDED
#define LEXY_DSL_NEWLINE_HPP_INCLUDED
#include <lexy/dsl/base.hpp>
#include <lexy/dsl/literal.hpp>
#include <lexy/dsl/token.hpp>
namespace lexy
{
struct expected_newline
{
static LEXY_CONSTEVAL auto name()
{
return "expected newline";
}
};
} // namespace lexy
namespace lexyd
{
struct _nl
: LEXY_DECAY_DECLTYPE(literal_set(LEXY_LIT("\n"), LEXY_LIT("\r\n")).error<lexy::expected_newline>)
{};
/// Matches a newline character.
constexpr auto newline = _nl{};
} // namespace lexyd
namespace lexyd
{
struct _eol : branch_base
{
template <typename Reader>
struct bp
{
static_assert(lexy::is_char_encoding<typename Reader::encoding>);
constexpr bool try_parse(const void*, Reader reader)
{
return reader.peek() == Reader::encoding::eof()
|| lexy::try_match_token(newline, reader);
}
template <typename Context>
constexpr void cancel(Context&)
{}
template <typename NextParser, typename Context, typename... Args>
LEXY_PARSER_FUNC bool finish(Context& context, Reader& reader, Args&&... args)
{
if (reader.peek() == Reader::encoding::eof())
{
auto pos = reader.position();
context.on(_ev::token{}, lexy::eof_token_kind, pos, pos);
return NextParser::parse(context, reader, LEXY_FWD(args)...);
}
else
{
// Note that we're re-doing the parsing for newline,
// this looks at most at two characters, so it doesn't really matter.
return lexy::parser_for<_nl, NextParser>::parse(context, reader, LEXY_FWD(args)...);
}
}
};
template <typename NextParser>
struct p
{
template <typename Context, typename Reader, typename... Args>
LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
{
static_assert(lexy::is_char_encoding<typename Reader::encoding>);
return bp<Reader>{}.template finish<NextParser>(context, reader, LEXY_FWD(args)...);
}
};
};
/// Matches the end of line (EOF or newline).
constexpr auto eol = _eol{};
} // namespace lexyd
#endif // LEXY_DSL_NEWLINE_HPP_INCLUDED