29template<
class Tok,
class Tag,
size_t K,
class S>
30requires(std::is_convertible_v<Tok, bool> || std::is_constructible_v<bool, Tok>) || std::is_default_constructible_v<Tok>
33 S& self() {
return *
static_cast<S*
>(
this); }
34 const S& self()
const {
return *
static_cast<const S*
>(
this); }
39 void init(
const std::filesystem::path* path) {
41 for (
size_t i = 0; i != K; ++i) ahead_[i] = self().lexer().lex();
42 prev_ =
Loc(path, {1, 1});
61 Loc loc()
const {
return {prev_.path, pos_, prev_.finis}; }
63 operator Loc()
const {
return loc(); }
77 Tok
ahead(
size_t i = 0)
const {
return ahead_[i]; }
81 auto result = ahead();
83 ahead_.put(self().lexer().lex());
89 if (tag != ahead().tag())
return {};
95 Tok
expect(Tag tag, std::string_view ctxt) {
96 if (ahead().tag() == tag)
return lex();
97 self().syntax_err(tag, ctxt);
102 Tok
eat([[maybe_unused]] Tag tag) {
103 assert(tag == ahead().tag() &&
"internal parser error");
Tracker(Loc &prev, Pos pos)
The blueprint for a recursive descent/ ascent parser using a K lookahead of Tokens.
Tok lex()
Invoke Lexer to retrieve next Token.
Tok eat(Tag tag)
Consume Parser::ahead which must be a tag; asserts otherwise.
Tok expect(Tag tag, std::string_view ctxt)
Parser::lex Parser::ahead() which must be a tag.
Tok accept(Tag tag)
If Parser::ahead() is a tag, consume and return it, otherwise yield std::nullopt.
Tracker tracker()
Factory method to build a Parser::Tracker.
Tok ahead(size_t i=0) const
void init(const std::filesystem::path *path)
A ring buffer with N elements.
Position in a source file; pass around as value.