The reference manual describes the cparse public API in cppreference-style one-page-per-symbol format. Each class has a synopsis page that lists its members with one-line summaries; each member has its own page with the declaration, description, parameters, return value, exceptions, notes and a working example.
The generated Doxygen tree is the exhaustive machine-produced reference. This manual is the human-written companion: same granularity, different depth. The Doxygen tree tells you the signature; this manual tells you why to reach for it, when not to, and what to do next.
The library
All names live under namespace fedem::parser and are declared in four headers under <cparse/…>:
#include <cparse/Cursor.hh>
#include <cparse/Parser.hh> // pulls in Cursor.hh transitively
#include <cparse/Generator.hh>
#include <cparse/Indentation.hh>
The library has two independent halves:
Parsing side — Cursor and Parser. Cursor is a read-only stream position with line/column tracking and save/restore. Parser is the abstract driver you subclass to write a grammar. ParseError is the diagnostic struct they use.
Code-generation side — Generator and Indentation. Generator is the abstract base for code emitters (case conversion, header guards, C++ string encoding, namespace-scope stack). Indentation is a small value type for step-based indent tracking.
A grammar-only tool uses the parsing side. A pure code emitter uses the codegen side. A grammar-driven generator (UMTSM, for instance) uses both, but the two halves never touch each other inside cparse itself — the coupling happens in the subclass.
Classes
| Class | Header | One-line summary |
|---|---|---|
fedem::parser::Cursor | <cparse/Cursor.hh> | Read-only stream position with line/column tracking and save/restore. |
fedem::parser::Parser | <cparse/Parser.hh> | Abstract driver for a hand-written recursive-descent grammar. |
fedem::parser::ParseError | <cparse/Parser.hh> | POD-ish diagnostic record: kind, message, filename, line, column. |
fedem::parser::Generator | <cparse/Generator.hh> | Abstract base for code emitters; case conversion, sanitisation, header guards, namespace stack. |
fedem::parser::Indentation | <cparse/Indentation.hh> | Small value type: current indent + step size, with operator<< for streams. |
For new readers
If you are starting from zero, do not read this manual sequentially. Read User Guide › Getting Started first — it walks through building a working comma-separated-integer parser in under fifty lines. Then come back here for the class-by-class detail.
Design decisions worth knowing about
Two design decisions surface repeatedly across the reference. Both are covered in the pages that motivate them, but flagging them here saves surprise later:
Safe versus throwing methods. Cursor::get() and Cursor::peek() throw an std::ios_base::failure at end-of-input. This is how Parser::parse() detects a clean end-of-input. Inside your own consuming loops, use Cursor::safeGet() and Cursor::safePeek() — they return the EOF sentinel '\032' instead of throwing.
Open-scope tracking is not RAII. Parser::enterScope() and Parser::leaveScope() increment and decrement a counter that Parser::parse() reads after end-of-input. If you wrapped enterScope in a scope-guard, the counter would decrement while the EOF exception unwinds, and parse() would see a depth of zero — the exact wrong answer for a truncated file. leaveScope() is called only on the path that actually consumed a closer.

