FE 0.16.1
Fast, Effecient FrontEnds
Loading...
Searching...
No Matches
fe::Parser< Tok, Tag, K, S > Class Template Reference

The blueprint for a recursive descent/ ascent parser using a K lookahead of Tokens. More...

#include <fe/parser.h>

Classes

class  Tracker
struct  Anchor
 One anchor; the left end opened the context, the right one is what it is still waiting for. More...
class  ScopedAnchor
 RAII helper that pushes a Parser::Anchor for its lifetime; use Parser::anchor to build one. More...
struct  Expected
 What Parser::expect was after - a Tag, or free-form markup. More...

Protected Member Functions

Construction
void init ()
Tracker

Track Location in the source file.

Use like this:

auto track = tracker();
auto foo = parse_foo();
auto bar = parse_bar();
auto foobar = new FooBar(track, foo, bar);
Tracker tracker()
Factory method to build a Parser::Tracker.
Definition parser.h:119
Tracker tracker ()
 Factory method to build a Parser::Tracker.
Tracker tracker (Pos begin)
 As above but start tracking at begin.
Tracker tracker (Loc begin)
Shift Token
Tok ahead (size_t i=0) const
Tok lex ()
 Invoke Lexer to retrieve next Token.
Tok accept (Tag tag)
 If Parser::ahead() is a tag, consume and return it, otherwise yield the Nil Tok().
Tok expect (Tag tag, Cite ctxt)
 Parser::lex Parser::ahead() which must be a tag.
template<class... Args>
Tok expect (Tag tag, cite_string< Args... > fmt, Args &&... args)
 As above but builds the context via fe::format_cite.
Tok eat (Tag tag)
 Consume Parser::ahead which must be a tag; asserts otherwise.
Anchor

An anchor is a Tag that an enclosing context is waiting for.

E.g., while parsing a parenthesized expression, ) is anchored: a nested parser must not swallow it but bail out, so the enclosing context can Parser::expect it. A ) that is not anchored, however, is simply bogus and Parser::recover discards it.

ScopedAnchor anchor (Tok l_tok, Tag r_tag)
 Factory method to build a Parser::ScopedAnchor; Parser::expect r_tag yourself at the end of the scope.
const Anchor * find_anchor (Tag r_tag) const
 The innermost Anchor waiting for r_tag - nullptr if no enclosing context is.
bool is_anchored (Tag r_tag) const
 Is r_tag anchored by an enclosing context?
template<std::predicate< Tag > P>
void recover (P pred, Cite ctxt)
 Parser::lex all Tokens whose Tag satisfies pred and that are not Parser::is_anchored; report the whole run as a single S::unanchored_err.
void recover (Tag tag, Cite ctxt)
 As above but only recovers from tag.
Diagnostics

The defaults S may replace with one of its own.

Each yields the Error it reported into, so a Note can be chained.

fe::Error & error ()
const fe::Error & error () const
fe::Error & syntax_err (Expected what, Cite ctxt, Tok got={})
 Parser::expect did not find what while parsing ctxt; got defaults to Parser::ahead.
fe::Error & unanchored_err (Tok tok, Loc loc, size_t n, Cite ctxt)
 Parser::recover discarded a run of n Tokens starting with tok and spanning loc while parsing ctxt.

Static Protected Member Functions

static auto tag2str_ (Tag tag)
 Spells tag out via Tok::tag2str if there is one - a bare enumerator would render as its number.

Protected Attributes

Ring< Tok, K > ahead_
Loc curr_
Vector< Anchor, 8 > anchors_

Detailed Description

template<class Tok, class Tag, size_t K, class S>
requires Token<Tok, Tag> && (K >= 1)
class fe::Parser< Tok, Tag, K, S >

The blueprint for a recursive descent/ ascent parser using a K lookahead of Tokens.

Parser::accept and Parser::expect indicate failure by constructing a Token with its default constructor. Hence, Tok must be an fe::Token - default-constructible, testable as a bool, and tagged Tag::Nil:

class Tok {
public:
enum class Tag {
Nil,
// ...
};
Tok() {} // default constructor yields the "failure" token
// ...
explicit operator bool() const { return tag_ != Tag::Nil; }
// ...
};
// Your Parser:
if (auto tok = accept(Tok::Tag::My_Tag)) {
do_something(tok);
}
Tok accept(Tag tag)
If Parser::ahead() is a tag, consume and return it, otherwise yield the Nil Tok().
Definition parser.h:138

S must provide the Lexer to pull from and the Driver to report to - publicly, so that fe::Lexable and fe::Diagnosable hold outside this class too:

class MyParser : public fe::Parser<Tok, Tok::Tag, K, MyParser> {
public:
Lexer& lexer(); ///< Parser::lex pulls the next Tok%en from here.
fe::Driver& driver(); ///< The default diagnostics below land in its Driver::error.
};
The blueprint for a lexer with a buffer of K tokens to peek into the future (Lexer::ahead).
Definition lexer.h:30
The blueprint for a recursive descent/ ascent parser using a K lookahead of Tokens.
Definition parser.h:73
Use/derive from this class for "global" variables that you need all over the place.
Definition driver.h:22

Parser::syntax_err and Parser::unanchored_err come with a default; declare either in S to word it differently. Each is one name with one signature, so a declaration in S replaces it outright - no using of the base needed.

Definition at line 73 of file parser.h.


Class Documentation

◆ fe::Parser::Anchor

struct fe::Parser::Anchor
template<class Tok, class Tag, size_t K, class S>
struct fe::Parser< Tok, Tag, K, S >::Anchor

One anchor; the left end opened the context, the right one is what it is still waiting for.

Definition at line 167 of file parser.h.

Class Members
Tok l_tok The Token that opened the context.
Tag r_tag The closing Tag that context is waiting for.

Member Function Documentation

◆ accept()

template<class Tok, class Tag, size_t K, class S>
Tok fe::Parser< Tok, Tag, K, S >::accept ( Tag tag)
inlineprotected

If Parser::ahead() is a tag, consume and return it, otherwise yield the Nil Tok().

Definition at line 138 of file parser.h.

References ahead(), and lex().

◆ ahead()

template<class Tok, class Tag, size_t K, class S>
Tok fe::Parser< Tok, Tag, K, S >::ahead ( size_t i = 0) const
inlineprotected

Get lookahead.

Definition at line 127 of file parser.h.

References ahead_.

Referenced by accept(), eat(), expect(), expect(), init(), lex(), recover(), and tracker().

◆ anchor()

template<class Tok, class Tag, size_t K, class S>
ScopedAnchor fe::Parser< Tok, Tag, K, S >::anchor ( Tok l_tok,
Tag r_tag )
inlinenodiscardprotected

Factory method to build a Parser::ScopedAnchor; Parser::expect r_tag yourself at the end of the scope.

l_tok is the Token that opened this context and Parser::syntax_err notes it on a missing r_tag, which is all it takes to point a ) that never came back at its (. Use like this:

if (auto paren_l = accept(Tag::D_paren_l)) {
auto _ = anchor(paren_l, Tag::D_paren_r);
auto expr = parse_expr();
expect(Tag::D_paren_r, "parenthesized expression");
return expr;
}
ScopedAnchor anchor(Tok l_tok, Tag r_tag)
Factory method to build a Parser::ScopedAnchor; Parser::expect r_tag yourself at the end of the scope...
Definition parser.h:208
Tok expect(Tag tag, Cite ctxt)
Parser::lex Parser::ahead() which must be a tag.
Definition parser.h:145

Definition at line 208 of file parser.h.

◆ eat()

template<class Tok, class Tag, size_t K, class S>
Tok fe::Parser< Tok, Tag, K, S >::eat ( Tag tag)
inlineprotected

Consume Parser::ahead which must be a tag; asserts otherwise.

Definition at line 160 of file parser.h.

References ahead(), and lex().

◆ error() [1/2]

template<class Tok, class Tag, size_t K, class S>
fe::Error & fe::Parser< Tok, Tag, K, S >::error ( )
inlineprotected

Definition at line 269 of file parser.h.

Referenced by unanchored_err().

◆ error() [2/2]

template<class Tok, class Tag, size_t K, class S>
const fe::Error & fe::Parser< Tok, Tag, K, S >::error ( ) const
inlineprotected

Definition at line 270 of file parser.h.

◆ expect() [1/2]

template<class Tok, class Tag, size_t K, class S>
Tok fe::Parser< Tok, Tag, K, S >::expect ( Tag tag,
Cite ctxt )
inlineprotected

Parser::lex Parser::ahead() which must be a tag.

Issue error with ctxt otherwise.

Definition at line 145 of file parser.h.

References ahead(), and lex().

◆ expect() [2/2]

template<class Tok, class Tag, size_t K, class S>
template<class... Args>
Tok fe::Parser< Tok, Tag, K, S >::expect ( Tag tag,
cite_string< Args... > fmt,
Args &&... args )
inlineprotected

As above but builds the context via fe::format_cite.

Definition at line 153 of file parser.h.

References ahead(), fe::format_cite(), and lex().

◆ find_anchor()

template<class Tok, class Tag, size_t K, class S>
const Anchor * fe::Parser< Tok, Tag, K, S >::find_anchor ( Tag r_tag) const
inlineprotected

The innermost Anchor waiting for r_tag - nullptr if no enclosing context is.

Scans the innermost anchor first, but any enclosing context counts.

Definition at line 212 of file parser.h.

References anchors_.

Referenced by is_anchored().

◆ init()

template<class Tok, class Tag, size_t K, class S>
void fe::Parser< Tok, Tag, K, S >::init ( )
inlineprotected

Definition at line 81 of file parser.h.

References ahead(), ahead_, and curr_.

◆ is_anchored()

template<class Tok, class Tag, size_t K, class S>
bool fe::Parser< Tok, Tag, K, S >::is_anchored ( Tag r_tag) const
inlineprotected

Is r_tag anchored by an enclosing context?

Definition at line 220 of file parser.h.

References find_anchor().

Referenced by recover().

◆ lex()

template<class Tok, class Tag, size_t K, class S>
Tok fe::Parser< Tok, Tag, K, S >::lex ( )
inlineprotected

Invoke Lexer to retrieve next Token.

Definition at line 130 of file parser.h.

References ahead(), ahead_, curr_, and lex().

Referenced by accept(), eat(), expect(), expect(), lex(), and recover().

◆ recover() [1/2]

template<class Tok, class Tag, size_t K, class S>
template<std::predicate< Tag > P>
void fe::Parser< Tok, Tag, K, S >::recover ( P pred,
Cite ctxt )
inlineprotected

Parser::lex all Tokens whose Tag satisfies pred and that are not Parser::is_anchored; report the whole run as a single S::unanchored_err.

This turns an otherwise fatal Token into a mere error message and keeps the current parser going. One mistake discards one run, so one run is one diagnostic: a message per token buries the real error.

Definition at line 227 of file parser.h.

References ahead(), is_anchored(), and lex().

Referenced by recover().

◆ recover() [2/2]

template<class Tok, class Tag, size_t K, class S>
void fe::Parser< Tok, Tag, K, S >::recover ( Tag tag,
Cite ctxt )
inlineprotected

As above but only recovers from tag.

Definition at line 241 of file parser.h.

References recover().

◆ syntax_err()

template<class Tok, class Tag, size_t K, class S>
fe::Error & fe::Parser< Tok, Tag, K, S >::syntax_err ( Expected what,
Cite ctxt,
Tok got = {} )
inlineprotected

Parser::expect did not find what while parsing ctxt; got defaults to Parser::ahead.

ctxt is markup, so backtick a literal token within it yourself. A what the innermost Anchor is waiting for gets a Note pointing back at the Token that opened it - the ( of a ) that never came.

Definition at line 276 of file parser.h.

◆ tag2str_()

template<class Tok, class Tag, size_t K, class S>
auto fe::Parser< Tok, Tag, K, S >::tag2str_ ( Tag tag)
inlinestaticprotected

Spells tag out via Tok::tag2str if there is one - a bare enumerator would render as its number.

Definition at line 299 of file parser.h.

References fe::format_cite().

Referenced by fe::Parser< Tok, Tag, K, S >::Expected::Expected().

◆ tracker() [1/3]

template<class Tok, class Tag, size_t K, class S>
Tracker fe::Parser< Tok, Tag, K, S >::tracker ( )
inlineprotected

Factory method to build a Parser::Tracker.

Definition at line 119 of file parser.h.

References ahead(), and curr_.

◆ tracker() [2/3]

template<class Tok, class Tag, size_t K, class S>
Tracker fe::Parser< Tok, Tag, K, S >::tracker ( Loc begin)
inlineprotected

Definition at line 121 of file parser.h.

References fe::Loc::begin, and curr_.

◆ tracker() [3/3]

template<class Tok, class Tag, size_t K, class S>
Tracker fe::Parser< Tok, Tag, K, S >::tracker ( Pos begin)
inlineprotected

As above but start tracking at begin.

Definition at line 120 of file parser.h.

References curr_.

◆ unanchored_err()

template<class Tok, class Tag, size_t K, class S>
fe::Error & fe::Parser< Tok, Tag, K, S >::unanchored_err ( Tok tok,
Loc loc,
size_t n,
Cite ctxt )
inlineprotected

Parser::recover discarded a run of n Tokens starting with tok and spanning loc while parsing ctxt.

Definition at line 289 of file parser.h.

References fe::Error::e(), and error().

Member Data Documentation

◆ ahead_

template<class Tok, class Tag, size_t K, class S>
Ring<Tok, K> fe::Parser< Tok, Tag, K, S >::ahead_
protected

Definition at line 308 of file parser.h.

Referenced by ahead(), init(), and lex().

◆ anchors_

template<class Tok, class Tag, size_t K, class S>
Vector<Anchor, 8> fe::Parser< Tok, Tag, K, S >::anchors_
protected

Definition at line 310 of file parser.h.

Referenced by find_anchor().

◆ curr_

template<class Tok, class Tag, size_t K, class S>
Loc fe::Parser< Tok, Tag, K, S >::curr_
protected

Definition at line 309 of file parser.h.

Referenced by init(), lex(), tracker(), tracker(), and tracker().


The documentation for this class was generated from the following file: