Abstract driver for a hand-written recursive-descent grammar.
More...
#include <Parser.hh>
|
| | Parser () |
| | Default-construct. No file is open until parse() is called. More...
|
| |
| virtual | ~Parser () |
| | Destructor. More...
|
| |
| bool | parse (std::string filename) |
| | Parse filename: open it, run start(), and classify the ending. More...
|
| |
| bool | openStream (std::string filename) |
| | Open filename and set up the cursor, but do not run start() — for a grammar driven from outside one unit at a time instead of "parse everything, then read the
result" (the canonical example: a CSV-style reader whose public interface is nextRow(), called until it returns nothing). More...
|
| |
| virtual std::string | getGrammarName () const noexcept=0 |
| | The grammar's name, for diagnostics. Implemented by the subclass. More...
|
| |
| std::vector< ParseError > const & | errors () const noexcept |
| | The collected diagnostics, in the order they were recorded. Valid after parse() returns; check when it returns false. More...
|
| |
| bool | hasErrors () const noexcept |
| | Whether any diagnostic has been collected. More...
|
| |
| void | clearErrors () noexcept |
| | Discard all collected diagnostics. Called by parse() on entry. More...
|
| |
Abstract driver for a hand-written recursive-descent grammar.
Subclass Parser, implement start() (the grammar's entry rule) and getGrammarName(), and call parse() with a filename. The base handles the parts every grammar shares:
Copy and move are deleted.
- See also
- https://cparse.fedem.eu/reference/parser — reference manual page.
-
https://cparse.fedem.eu/docs/getting-started — build a first grammar.
-
Cursor
◆ TermRequirementDeclaration
◆ Parser()
| fedem::parser::Parser::Parser |
( |
| ) |
|
|
default |
◆ ~Parser()
| fedem::parser::Parser::~Parser |
( |
| ) |
|
|
virtualdefault |
◆ parse()
| bool fedem::parser::Parser::parse |
( |
std::string |
filename | ) |
|
Parse filename: open it, run start(), and classify the ending.
- Parameters
-
| filename | Path to parse. Resolved with std::filesystem::canonical; a missing file is reported on std::clog and yields false. |
- Returns
true on a clean parse (grammar succeeded and any scopes it opened were closed); false if start() failed, exit() was called, the input ended with scopes still open, or an I/O / internal error occurred. A nested parse() (an include) restores the parent cursor and returns true.
- Note
- On failure, inspect
errors() for the reason(s). Only the outermost parse() resets the open-scope depth.
- See also
- https://cparse.fedem.eu/reference/parser-parse
◆ openStream()
| bool fedem::parser::Parser::openStream |
( |
std::string |
filename | ) |
|
Open filename and set up the cursor, but do not run start() — for a grammar driven from outside one unit at a time instead of "parse everything, then read the
result" (the canonical example: a CSV-style reader whose public interface is nextRow(), called until it returns nothing).
parse() does not fit that shape: it calls start() itself and, the instant start() returns, tears the cursor down — right for a grammar where start() is the whole parse, fatal for a driver that still needs getCursor() valid afterwards (the external caller has not finished reading yet). openStream() does only the setup half parse() does — same std::filesystem::canonical resolution, same missing-file diagnostic on std::clog — and stops there. Drive the grammar afterwards through whatever public methods it exposes for that (e.g. repeated calls into helpers built on getCursor()); the cursor stays valid until the next parse()/openStream() call or destruction.
- Parameters
-
| filename | Path to open. Resolved with std::filesystem::canonical; a missing file is reported on std::clog and yields false. |
- Returns
true if the file was opened and the cursor is ready.
- See also
- https://cparse.fedem.eu/reference/parser-open-stream
-
https://cparse.fedem.eu/walkthrough/csv-lite
◆ getGrammarName()
| virtual std::string fedem::parser::Parser::getGrammarName |
( |
| ) |
const |
|
pure virtualnoexcept |
◆ errors()
| std::vector< ParseError > const & fedem::parser::Parser::errors |
( |
| ) |
const |
|
inlinenoexcept |
◆ hasErrors()
| bool fedem::parser::Parser::hasErrors |
( |
| ) |
const |
|
inlinenoexcept |
◆ clearErrors()
| void fedem::parser::Parser::clearErrors |
( |
| ) |
|
|
inlinenoexcept |
◆ start()
| virtual bool fedem::parser::Parser::start |
( |
| ) |
|
|
protectedpure virtual |
◆ skipWhiteSpaces()
| bool fedem::parser::Parser::skipWhiteSpaces |
( |
| ) |
|
|
protectedvirtual |
◆ skipComments()
| bool fedem::parser::Parser::skipComments |
( |
| ) |
|
|
protectedvirtual |
◆ skipCommentsBlock()
| bool fedem::parser::Parser::skipCommentsBlock |
( |
| ) |
|
|
protected |
◆ extractToken()
| bool fedem::parser::Parser::extractToken |
( |
std::string const & |
token | ) |
|
|
protected |
◆ extractCharacter()
| bool fedem::parser::Parser::extractCharacter |
( |
std::string::value_type const |
token | ) |
|
|
protected |
◆ writeTraceMessage()
| void fedem::parser::Parser::writeTraceMessage |
( |
| ) |
|
|
protected |
◆ getCursor() [1/2]
| Cursor & fedem::parser::Parser::getCursor |
( |
| ) |
|
|
inlineprotected |
◆ getCursor() [2/2]
| Cursor const & fedem::parser::Parser::getCursor |
( |
| ) |
const |
|
inlineprotected |
◆ pushCursor()
| void fedem::parser::Parser::pushCursor |
( |
std::string const & |
sourceName, |
|
|
std::shared_ptr< Cursor::stream_type > |
stream |
|
) |
| |
|
protected |
◆ storeCursor()
| Cursor const & fedem::parser::Parser::storeCursor |
( |
| ) |
|
|
protected |
◆ restoreCursor()
| void fedem::parser::Parser::restoreCursor |
( |
Cursor const & |
crs | ) |
|
|
protected |
◆ exit()
| void fedem::parser::Parser::exit |
( |
int |
status | ) |
|
|
protected |
◆ recordError()
| void fedem::parser::Parser::recordError |
( |
ParseError::Kind |
kind, |
|
|
std::string const & |
message, |
|
|
unsigned long int |
line = 0, |
|
|
unsigned long int |
col = 0 |
|
) |
| |
|
protected |
◆ enterScope()
| void fedem::parser::Parser::enterScope |
( |
| ) |
|
|
protectednoexcept |
Note that the grammar has consumed a scope opener (brace, bracket, begin, …).
A grammar with nesting calls this on an opener and leaveScope() on the matching closer. parse() reads openScopeDepth() after end-of-input: a non-zero depth means the input was truncated mid-construct and parse() records a syntax error instead of treating the EOF as clean.
This is deliberately not an RAII guard: the depth must stay non-zero while the end-of-input exception unwinds, because that is the condition being detected. Grammars that never call these keep a depth of zero and behave exactly as before.
- See also
- https://cparse.fedem.eu/reference/parser-enter-scope
◆ leaveScope()
| void fedem::parser::Parser::leaveScope |
( |
| ) |
|
|
protectednoexcept |
◆ openScopeDepth()
| unsigned int fedem::parser::Parser::openScopeDepth |
( |
| ) |
const |
|
protectednoexcept |
The documentation for this class was generated from the following files: