Previous: , Up: Error Reporting   [Contents][Index]


4.4.2 The Syntax Error Reporting Function yyreport_syntax_error

If you invoke ‘%define parse.error custom’ (see The Bison Declarations Section), then the parser no longer passes syntax error messages to yyerror, rather it delegates that task to the user by calling the yyreport_syntax_error function.

The following functions and types are “static”: they are defined in the implementation file (*.c) and available only from there. They are meant to be used from the grammar’s epilogue.

Function: static int yyreport_syntax_error (const yypcontext_t *ctx)

Report a syntax error to the user. Return 0 on success, YYENOMEM on memory exhaustion. Whether it uses yyerror is up to the user.

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

Type: yypcontext_t

An opaque type that captures the circumstances of the syntax error.

Type: yysymbol_kind_t

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

enum yysymbol_kind_t
{
  YYSYMBOL_YYEMPTY = -2,      /* No symbol.  */
  YYSYMBOL_YYEOF = 0,         /* "end of file"  */
  YYSYMBOL_YYerror = 1,       /* error  */
  YYSYMBOL_YYUNDEF = 2,       /* "invalid token"  */
  YYSYMBOL_PLUS = 3,          /* "+"  */
  YYSYMBOL_MINUS = 4,         /* "-"  */
  [...]
  YYSYMBOL_VAR = 14,          /* "variable"  */
  YYSYMBOL_NEG = 15,          /* NEG  */
  YYSYMBOL_YYACCEPT = 16,     /* $accept  */
  YYSYMBOL_exp = 17,          /* exp  */
  YYSYMBOL_input = 18         /* input  */
};
typedef enum yysymbol_kind_t yysymbol_kind_t;
Function: static yysymbol_kind_t yypcontext_token (const yypcontext_t *ctx)

The “unexpected” token: the symbol kind of the lookahead token that caused the syntax error. Returns YYSYMBOL_YYEMPTY if there is no lookahead.

Function: static YYLTYPE * yypcontext_location (const yypcontext_t *ctx)

The location of the syntax error (that of the unexpected token).

Function: static int yypcontext_expected_tokens (const yypcontext_t *ctx, yysymbol_kind_t argv[], int argc)

Fill argv with the expected tokens, which never includes YYSYMBOL_YYEMPTY, YYSYMBOL_YYerror, or YYSYMBOL_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 YYSYMBOL_YYEMPTY.

When LAC is enabled, may return a negative number on errors, such as YYENOMEM on memory exhaustion.

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

Function: static const char * yysymbol_name (symbol_kind_t symbol)

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

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

static int
yyreport_syntax_error (const yypcontext_t *ctx)
{
  int res = 0;
  YYLOCATION_PRINT (stderr, *yypcontext_location (ctx));
  fprintf (stderr, ": syntax error");
  // Report the tokens expected at this point.
  {
    enum { TOKENMAX = 5 };
    yysymbol_kind_t expected[TOKENMAX];
    int n = yypcontext_expected_tokens (ctx, expected, TOKENMAX);
    if (n < 0)
      // Forward errors to yyparse.
      res = n;
    else
      for (int i = 0; i < n; ++i)
        fprintf (stderr, "%s %s",
                 i == 0 ? ": expected" : " or", yysymbol_name (expected[i]));
  }
  // Report the unexpected token.
  {
    yysymbol_kind_t lookahead = yypcontext_token (ctx);
    if (lookahead != YYSYMBOL_YYEMPTY)
      fprintf (stderr, " before %s", yysymbol_name (lookahead));
  }
  fprintf (stderr, "\n");
  return res;
}

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


Previous: The Error Reporting Function yyerror, Up: Error Reporting   [Contents][Index]