Next: Special Features for Use in D Actions, Previous: D Parser Context Interface, Up: D Parsers [Contents][Index]
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-param
s 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.
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.
Return the next token. The return value is of type Symbol
, which
binds together the kind, the semantic value and the location.
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]