Defined in header <cparse/Parser.hh>
struct ParseError;
ParseError is a small struct describing one diagnostic produced during a parse. Instances live in an internal std::vector inside Parser; callers read them via Parser::errors(), and grammars write them via Parser::recordError().
The struct is deliberately plain — no methods, no severity ordering, no error-code catalogue. It carries what a diagnostic needs (what kind, what happened, where) and leaves formatting and prioritisation to the caller.
Declaration
struct ParseError
{
enum class Kind
{
Syntax, // malformed token sequence
Type, // type mismatch / undefined identifier
Faulty, // ill-formed expression (e.g. nested comment terminator)
Internal, // parser-internal assertion / unexpected state
Warning, // non-fatal diagnostic (parse continues)
};
Kind kind { Kind::Internal };
std::string message;
std::string filename;
unsigned long int line { 0 };
unsigned long int col { 0 };
};
Member types
| Member type | Definition |
|---|---|
Kind | Enum class of diagnostic categories; see below. |
Kind values
| Value | Meaning |
|---|---|
Kind::Syntax | Malformed token sequence. The grammar cannot make progress at this point. Typical uses: "expected ')' before ';'", "unexpected token in expression". |
Kind::Type | Type mismatch or undefined identifier. Reserved for grammars that carry semantic information — fson uses this for "value assigned to member of incompatible type" and "reference to undeclared identifier". |
Kind::Faulty | An ill-formed construct that tokenises correctly but is semantically broken. The canonical case is a comment terminator inside another comment. |
Kind::Internal | Parser-internal assertion or unexpected state. Used by the driver for "unexpected file parsing result" and by handlers for exceptions that reach parse(). The default value of ParseError::kind. |
Kind::Warning | Non-fatal diagnostic. The parse continues; parse() may still return true. |
The Kind enum values have no numeric ordering that means "severity". Syntax is not "worse than" Type. If your consumer needs a severity ordering, define it in the consumer.
Data members
| Member | Type | Description |
|---|---|---|
kind | Kind | The category. Defaults to Kind::Internal — a safe worst-assumption default for accidentally-default-constructed instances. |
message | std::string | Human-readable diagnostic text. No format prescribed — no leading "error: ", no trailing newline. |
filename | std::string | Source file the error refers to. Filled by recordError() from the active cursor. Empty when the parser had no active cursor. |
line | unsigned long int | One-based line number. 0 means unknown. |
col | unsigned long int | One-based column number. 0 means unknown. |
Notes
Errors appear in Parser::errors() in the order recordError() was called. That is usually — but not always — the order they occurred in the input. A grammar that scans speculatively and rewinds may record diagnostics for paths it did not ultimately take; if it also records diagnostics for the path it did take, those come later even though they refer to earlier positions. If order matters for your UI, sort by filename, line, col on the consumer side.
The struct carries no error code beyond Kind. If your grammar has a rich diagnostic taxonomy, encode it in the message string (a "[E1234] " prefix, say) and parse it out on the consumer side. cparse does not maintain a stable, versioned error-code catalogue.
The struct carries no source snippet. Consumers that want to display "the offending line" open the file and read line n themselves — cparse would either duplicate that work or force a particular presentation.
Example
A typical caller-side rendering:
#include <cparse/Parser.hh>
#include <iostream>
static char const* kindLabel(fedem::parser::ParseError::Kind k)
{
using K = fedem::parser::ParseError::Kind;
switch (k)
{
case K::Syntax: return "syntax";
case K::Type: return "type";
case K::Faulty: return "faulty";
case K::Internal: return "internal";
case K::Warning: return "warning";
}
return "?";
}
void report(fedem::parser::Parser const& p)
{
for (auto const& e : p.errors())
{
std::cerr << e.filename << ':' << e.line << ':' << e.col
<< ": " << kindLabel(e.kind) << ": "
<< e.message << '\n';
}
}
See also
- Parser::errors — read the collector.
- Parser::recordError — append a ParseError.
- Parser::hasErrors — check whether any error has been recorded.
- Parser::clearErrors — empty the collector.

