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

10.3.8 Java Push Parser Interface

Normally, Bison generates a pull parser for Java. The following Bison declaration says that you want the parser to be a push parser (see %define Summary):

%define api.push-pull push

Most of the discussion about the Java pull Parser Interface, (see Java Parser Interface) applies to the push parser interface as well.

When generating a push parser, the method push_parse is created with the following signature (depending on if locations are enabled).

Method on YYParser: void push_parse (int token, Object yylval)
Method on YYParser: void push_parse (int token, Object yylval, Location yyloc)
Method on YYParser: void push_parse (int token, Object yylval, Position yypos)

The primary difference with respect to a pull parser is that the parser method push_parse is invoked repeatedly to parse each token. This function is available if either the ‘%define api.push-pull push’ or ‘%define api.push-pull both’ declaration is used (see %define Summary). The Location and Position parameters are available only if location tracking is active.

The value returned by the push_parse method is one of the following: 0 (success), 1 (abort), 2 (memory exhaustion), or YYPUSH_MORE. This new value, YYPUSH_MORE, may be returned if more input is required to finish parsing the grammar.

If api.push-pull is defined as both, then the generated parser class will also implement the parse method. This method’s body is a loop that repeatedly invokes the scanner and then passes the values obtained from the scanner to the push_parse method.

There is one additional complication. Technically, the push parser does not need to know about the scanner (i.e. an object implementing the YYParser.Lexer interface), but it does need access to the yyerror method. Currently, the yyerror method is defined in the YYParser.Lexer interface. Hence, an implementation of that interface is still required in order to provide an implementation of yyerror. The current approach (and subject to change) is to require the YYParser constructor to be given an object implementing the YYParser.Lexer interface. This object need only implement the yyerror method; the other methods can be stubbed since they will never be invoked. The simplest way to do this is to add a trivial scanner implementation to your grammar file using whatever implementation of yyerror is desired. The following code sample shows a simple way to accomplish this.

%code lexer
  public Object getLVal () {return null;}
  public int yylex () {return 0;}
  public void yyerror (String s) {System.err.println(s);}

Next: Differences between C/C++ and Java Grammars, Previous: Special Features for Use in Java Actions, Up: Java Parsers   [Contents][Index]