Next: , Previous: , Up: C++ Parsers   [Contents][Index]


10.1.6 C++ Parser Context

When ‘%define parse.error custom’ is used (see The Syntax Error Reporting Function yyreport_syntax_error), the user must define the following function.

Method on parser: void report_syntax_error (const context_type&ctx) const

Report a syntax error to the user. Whether it uses yyerror is up to the user.

Use the following types and functions to build the error message.

Type of parser: context

A type that captures the circumstances of the syntax error.

Type of parser: symbol_kind_type

An enum of all the grammar symbols, tokens and nonterminals. Its enumerators are forged from the symbol names:

struct symbol_kind
{
  enum symbol_kind_type
  {
    S_YYEMPTY = -2,      // No symbol.
    S_YYEOF = 0,         // "end of file"
    S_YYERROR = 1,       // error
    S_YYUNDEF = 2,       // "invalid token"
    S_PLUS = 3,          // "+"
    S_MINUS = 4,         // "-"
    [...]
    S_VAR = 14,          // "variable"
    S_NEG = 15,          // NEG
    S_YYACCEPT = 16,     // $accept
    S_exp = 17,          // exp
    S_input = 18         // input
  };
};
typedef symbol_kind::symbol_kind_t symbol_kind_type;
Method on context: const symbol_type& lookahead () const

The “unexpected” token: the lookahead that caused the syntax error.

Method on context: symbol_kind_type token () const

The symbol kind of the lookahead token that caused the syntax error. Returns symbol_kind::S_YYEMPTY if there is no lookahead.

Method on context: const location& location () const

The location of the syntax error (that of the lookahead).

Method on context: int expected_tokens (symbol_kind_type argv[], int argc) const

Fill argv with the expected tokens, which never includes symbol_kind::S_YYEMPTY, symbol_kind::S_YYERROR, or symbol_kind::S_YYUNDEF.

Never put more than argc elements into argv, and on success return the number of tokens stored in argv. If there are more expected tokens than argc, fill argv up to argc and return 0. If there are no expected tokens, also return 0, but set argv[0] to symbol_kind::S_YYEMPTY.

If argv is null, return the size needed to store all the possible values, which is always less than YYNTOKENS.

Method on parser: const char * symbol_name (symbol_kind_t symbol) const

The name of the symbol whose kind is symbol, possibly translated.

Returns a std::string when parse.error is verbose.

A custom syntax error function looks as follows. This implementation is inappropriate for internationalization, see the c/bistromathic example for a better alternative.

void
yy::parser::report_syntax_error (const context& ctx)
{
  int res = 0;
  std::cerr << ctx.location () << ": syntax error";
  // Report the tokens expected at this point.
  {
    enum { TOKENMAX = 5 };
    symbol_kind_type expected[TOKENMAX];
    int n = ctx.expected_tokens (ctx, expected, TOKENMAX);
    for (int i = 0; i < n; ++i)
      std::cerr << i == 0 ? ": expected " : " or "
                << symbol_name (expected[i]);
  }
  // Report the unexpected token.
  {
    symbol_kind_type lookahead = ctx.token ();
    if (lookahead != symbol_kind::S_YYEMPTY)
      std::cerr << " before " << symbol_name (lookahead));
  }
  std::cerr << '\n';
}

You still must provide a yyerror function, used for instance to report memory exhaustion.


Next: C++ Scanner Interface, Previous: C++ Location Values, Up: C++ Parsers   [Contents][Index]