diff --git a/NEWS b/NEWS index 389448e1..05185c75 100644 --- a/NEWS +++ b/NEWS @@ -216,8 +216,8 @@ GNU Bison NEWS *** Examples - There are now two examples in examples/java: a very simple calculator, and - one that tracks locations to provide accurate error messages. + There are now examples/java: a very simple calculator, and a more complete + one (push-parser, location tracking, and debug traces). The lexcalc example (a simple example in C based on Flex and Bison) now also demonstrates location tracking. diff --git a/TODO b/TODO index e2200fe1..31f890e8 100644 --- a/TODO +++ b/TODO @@ -25,9 +25,6 @@ should be updated to not use YYERRCODE. Returning an undef token is good enough. ** Java -*** Examples -Have an example with a push parser. Use autocompletion in that case. - *** calc.at Stop hard-coding "Calc". Adjust local.at (look for FIXME). diff --git a/data/skeletons/lalr1.java b/data/skeletons/lalr1.java index 8536359b..1baa497d 100644 --- a/data/skeletons/lalr1.java +++ b/data/skeletons/lalr1.java @@ -121,7 +121,7 @@ import java.text.MessageFormat; * Locations represent a part of the input through the beginning * and ending positions. */ - public class ]b4_location_type[ { + public static class ]b4_location_type[ { /** * The first, inclusive, position in the range. */ @@ -182,8 +182,7 @@ import java.text.MessageFormat; ]b4_token_enums[ /** Deprecated, use ]b4_symbol(0, id)[ instead. */ public static final int EOF = ]b4_symbol(0, id)[; - -]b4_locations_if([[ +]b4_pull_if([b4_locations_if([[ /** * Method to retrieve the beginning position of the last scanned token. * @@return the position at which the last scanned token starts. @@ -209,7 +208,7 @@ import java.text.MessageFormat; * @@return the token identifier corresponding to the next token. */ int yylex()]b4_maybe_throws([b4_lex_throws])[; - +]])[ /** * Emit an error]b4_locations_if([ referring to the given location])[in a user-defined way. * @@ -832,7 +831,7 @@ b4_dollar_popdef[]dnl this.push_parse_initialized = true; } -]b4_locations_if([ +]b4_locations_if([[ /** * Push parse given input from an external lexer. * @@ -842,11 +841,10 @@ b4_dollar_popdef[]dnl * * @@return YYACCEPT, YYABORT, YYPUSH_MORE */ - public int push_parse(int yylextoken, b4_yystype yylexval, b4_position_type yylexpos)b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])]) - { - return push_parse(yylextoken, yylexval, new b4_location_type (yylexpos)); + public int push_parse(int yylextoken, ]b4_yystype[ yylexval, ]b4_position_type[ yylexpos)]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[ { + return push_parse(yylextoken, yylexval, new ]b4_location_type[(yylexpos)); } -])[]])[ +]])])[ ]b4_both_if([[ /** @@ -857,21 +855,18 @@ b4_dollar_popdef[]dnl * @@return true if the parsing succeeds. Note that this does not * imply that there were no syntax errors. */ - public boolean parse()]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[ - { - if (yylexer == null) - throw new NullPointerException("Null Lexer"); - int status; - do { - int token = yylexer.yylex(); - ]b4_yystype[ lval = yylexer.getLVal(); -]b4_locations_if([dnl - b4_location_type yyloc = new b4_location_type (yylexer.getStartPos (), - yylexer.getEndPos ());])[]b4_locations_if([[ - status = push_parse(token,lval,yyloc);]], [[ - status = push_parse(token,lval);]])[ - } while (status == YYPUSH_MORE); - return (status == YYACCEPT); + public boolean parse()]b4_maybe_throws([b4_list2([b4_lex_throws], [b4_throws])])[ { + if (yylexer == null) + throw new NullPointerException("Null Lexer"); + int status; + do { + int token = yylexer.yylex(); + ]b4_yystype[ lval = yylexer.getLVal();]b4_locations_if([[ + ]b4_location_type[ yyloc = new ]b4_location_type[(yylexer.getStartPos(), yylexer.getEndPos()); + status = push_parse(token, lval, yyloc);]], [[ + status = push_parse(token, lval);]])[ + } while (status == YYPUSH_MORE); + return status == YYACCEPT; } ]])[ diff --git a/doc/bison.texi b/doc/bison.texi index 7a00069f..aeb176a4 100644 --- a/doc/bison.texi +++ b/doc/bison.texi @@ -13341,9 +13341,9 @@ changed using @code{%define api.location.type @{@var{class-name}@}}. @end deftypemethod @deftypemethod {Lexer} {int} yylex () -Return the next token. Its type is the return value, its semantic -value and location are saved and returned by the their methods in the -interface. +Return the next token. Its type is the return value, its semantic value and +location are saved and returned by the their methods in the interface. Not +needed for push-only parsers. Use @samp{%define lex_throws} to specify any uncaught exceptions. Default is @code{java.io.IOException}. @@ -13353,7 +13353,7 @@ Default is @code{java.io.IOException}. @deftypemethodx {Lexer} {Position} getEndPos () Return respectively the first position of the last token that @code{yylex} returned, and the first position beyond it. These methods are not needed -unless location tracking is active. +unless location tracking and pull parsing are active. They should return new objects for each call, to avoid that all the symbol share the same Position boundaries. @@ -13363,7 +13363,8 @@ The return type can be changed using @code{%define api.position.type @end deftypemethod @deftypemethod {Lexer} {Object} getLVal () -Return the semantic value of the last token that yylex returned. +Return the semantic value of the last token that yylex returned. Not needed +for push-only parsers. The return type can be changed using @samp{%define api.value.type @{@var{class-name}@}}. diff --git a/examples/java/README.md b/examples/java/README.md index 4be92c80..25b7f27c 100644 --- a/examples/java/README.md +++ b/examples/java/README.md @@ -9,7 +9,7 @@ afterwards. The usual calculator, a very simple version. ## calc/Calc.y -The calculator, but with location tracking and debug traces. +The calculator, but with location tracking, debug traces, and a push parser.