Next: , Previous: , Up: D Parsers   [Contents][Index]


10.2.6 D Scanner Interface

There are two possible ways to interface a Bison-generated D parser with a scanner: the scanner may be defined by %code lexer, or defined elsewhere. In either case, the scanner has to implement the Lexer inner interface of the parser class. This interface also contains constants for all user-defined token names and the predefined YYEOF token.

In the first case, the body of the scanner class is placed in %code lexer blocks. If you want to pass parameters from the parser constructor to the scanner constructor, specify them with %lex-param; they are passed before %parse-params to the constructor.

In the second case, the scanner has to implement the Lexer interface, which is defined within the parser class (e.g., YYParser.Lexer). The constructor of the parser object will then accept an object implementing the interface; %lex-param is not used in this case.

In both cases, the scanner has to implement the following methods.

Method on Lexer: void yyerror(Location loc, string msg)

This method is defined by the user to emit an error message. The first parameter is omitted if location tracking is not active.

Method on Lexer: Symbol yylex()

Return the next token. The return value is of type Symbol, which binds together the kind, the semantic value and the location.

Method on Lexer: void reportSyntaxError(YYParser.Context ctx)

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 reportSyntaxError function.

Whether it uses yyerror is up to the user.

Here is an example of a reporting function (see D Parser Context Interface).

public void reportSyntaxError(YYParser.Context ctx)
{
  stderr.write(ctx.getLocation(), ": syntax error");
  // Report the expected tokens.
  {
    immutable int TOKENMAX = 5;
    YYParser.SymbolKind[] arg = new YYParser.SymbolKind[TOKENMAX];
    int n = ctx.getExpectedTokens(arg, TOKENMAX);
    if (n < TOKENMAX)
      for (int i = 0; i < n; ++i)
        stderr.write((i == 0 ? ": expected " : " or "), arg[i]);
  }
  // Report the unexpected token which triggered the error.
  {
    YYParser.SymbolKind lookahead = ctx.getToken();
    stderr.writeln(" before ", lookahead);
  }
}

This implementation is inappropriate for internationalization, see the c/bistromathic example for a better alternative.


Next: Special Features for Use in D Actions, Previous: D Parser Context Interface, Up: D Parsers   [Contents][Index]