mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-09 12:23:04 +00:00
java: add support for parse.error custom
* data/skeletons/lalr1.java: Add support for custom parse errors. (yyntokens_): Make it public. Under... (yyntokens): this name. (Context): Capture the location too. * examples/c/bistromathic/parse.y, * examples/c/bistromathic/bistromathic.test: Improve error message. * examples/java/calc/Calc.test, examples/java/calc/Calc.y: Use custom error messages. * tests/calc.at, tests/local.at: Check custom error messages.
This commit is contained in:
5
TODO
5
TODO
@@ -12,6 +12,11 @@ The calc.at test should call yyerror with location:
|
|||||||
yyerror (]AT_LOCATION_IF([[@$, ]])["calc: error: " + $1 + " != " + $3);
|
yyerror (]AT_LOCATION_IF([[@$, ]])["calc: error: " + $1 + " != " + $3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
** Java: EOF
|
||||||
|
We should be able to redefine EOF like we do in C.
|
||||||
|
|
||||||
|
** Java: calc.at
|
||||||
|
Stop hard-coding "Calc". Adjust local.at (look for FIXME).
|
||||||
|
|
||||||
** doc
|
** doc
|
||||||
I feel it's ugly to use the GNU style to declare functions in the doc. It
|
I feel it's ugly to use the GNU style to declare functions in the doc. It
|
||||||
|
|||||||
@@ -91,8 +91,10 @@ import java.text.MessageFormat;
|
|||||||
*/
|
*/
|
||||||
]b4_parser_class_declaration[
|
]b4_parser_class_declaration[
|
||||||
{
|
{
|
||||||
]b4_identification[
|
]b4_identification[
|
||||||
]b4_error_verbose_if([[
|
][
|
||||||
|
]m4_bmatch(b4_percent_define_get([[parse.error]]),
|
||||||
|
[detailed\|verbose], [[
|
||||||
/**
|
/**
|
||||||
* True if verbose error messages are enabled.
|
* True if verbose error messages are enabled.
|
||||||
*/
|
*/
|
||||||
@@ -161,9 +163,6 @@ import java.text.MessageFormat;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
]])[
|
|
||||||
|
|
||||||
]b4_locations_if([[
|
|
||||||
private ]b4_location_type[ yylloc (YYStack rhs, int n)
|
private ]b4_location_type[ yylloc (YYStack rhs, int n)
|
||||||
{
|
{
|
||||||
if (0 < n)
|
if (0 < n)
|
||||||
@@ -181,8 +180,8 @@ import java.text.MessageFormat;
|
|||||||
public static final int EOF = 0;
|
public static final int EOF = 0;
|
||||||
|
|
||||||
]b4_token_enums[
|
]b4_token_enums[
|
||||||
|
]b4_locations_if([[
|
||||||
]b4_locations_if([[/**
|
/**
|
||||||
* Method to retrieve the beginning position of the last scanned token.
|
* Method to retrieve the beginning position of the last scanned token.
|
||||||
* @@return the position at which the last scanned token starts.
|
* @@return the position at which the last scanned token starts.
|
||||||
*/
|
*/
|
||||||
@@ -217,7 +216,12 @@ import java.text.MessageFormat;
|
|||||||
* @@param msg The string for the error message.
|
* @@param msg The string for the error message.
|
||||||
*/
|
*/
|
||||||
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);
|
void yyerror (]b4_locations_if([b4_location_type[ loc, ]])[String msg);
|
||||||
}
|
|
||||||
|
]m4_bmatch(b4_percent_define_get([[parse.error]]),
|
||||||
|
[custom], [[
|
||||||
|
void yyreportSyntaxError (][Context yyctx);
|
||||||
|
]])[
|
||||||
|
}
|
||||||
|
|
||||||
]b4_lexer_if([[
|
]b4_lexer_if([[
|
||||||
private class YYLexer implements Lexer {
|
private class YYLexer implements Lexer {
|
||||||
@@ -676,8 +680,9 @@ b4_dollar_popdef[]dnl
|
|||||||
yytoken = yyempty_;
|
yytoken = yyempty_;
|
||||||
Context yyctx = new Context ();
|
Context yyctx = new Context ();
|
||||||
yyctx.yystack = yystack;
|
yyctx.yystack = yystack;
|
||||||
yyctx.yytoken = yytoken;
|
yyctx.yytoken = yytoken;]b4_locations_if([[
|
||||||
yyerror (]b4_locations_if([yylloc, ])[yysyntax_error (yyctx));
|
yyctx.yylocation = yylloc;]])[
|
||||||
|
yyreportSyntaxError (yyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
]b4_locations_if([[
|
]b4_locations_if([[
|
||||||
@@ -858,13 +863,15 @@ b4_dollar_popdef[]dnl
|
|||||||
public static final class Context
|
public static final class Context
|
||||||
{
|
{
|
||||||
public YYStack yystack;
|
public YYStack yystack;
|
||||||
public int yytoken;
|
public int yytoken;]b4_locations_if([[
|
||||||
|
public ]b4_location_type[ yylocation;]])[
|
||||||
|
public static final int yyntokens = ]b4_parser_class[.yyntokens_;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Put in YYARG at most YYARGN of the expected tokens given the
|
/* Put in YYARG at most YYARGN of the expected tokens given the
|
||||||
current YYCTX, and return the number of tokens stored in YYARG. If
|
current YYCTX, and return the number of tokens stored in YYARG. If
|
||||||
YYARG is null, return the number of expected tokens (guaranteed to
|
YYARG is null, return the number of expected tokens (guaranteed to
|
||||||
be less than YYNTOKENS). */
|
be less than YYNTOKENS_). */
|
||||||
static int
|
static int
|
||||||
yyexpectedTokens (Context yyctx,
|
yyexpectedTokens (Context yyctx,
|
||||||
int yyarg[], int yyoffset, int yyargn)
|
int yyarg[], int yyoffset, int yyargn)
|
||||||
@@ -935,13 +942,19 @@ b4_dollar_popdef[]dnl
|
|||||||
return yycount;
|
return yycount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate an error message.
|
/**
|
||||||
private String yysyntax_error (Context yyctx)
|
* Report a syntax error.
|
||||||
{]b4_error_verbose_if([[
|
*/
|
||||||
|
private void yyreportSyntaxError (Context yyctx)
|
||||||
|
{]m4_bmatch(b4_percent_define_get([parse.error]),
|
||||||
|
[custom], [[
|
||||||
|
yylexer.yyreportSyntaxError (yyctx);]],
|
||||||
|
[detailed\|verbose], [[
|
||||||
if (yyErrorVerbose)
|
if (yyErrorVerbose)
|
||||||
{
|
{
|
||||||
int[] yyarg = new int[5];
|
final int argmax = 5;
|
||||||
int yycount = yysyntaxErrorArguments (yyctx, yyarg, 5);
|
int[] yyarg = new int[argmax];
|
||||||
|
int yycount = yysyntaxErrorArguments (yyctx, yyarg, argmax);
|
||||||
String[] yystr = new String[yycount];
|
String[] yystr = new String[yycount];
|
||||||
for (int yyi = 0; yyi < yycount; ++yyi)
|
for (int yyi = 0; yyi < yycount; ++yyi)
|
||||||
yystr[yyi] = yysymbolName (yyarg[yyi]);
|
yystr[yyi] = yysymbolName (yyarg[yyi]);
|
||||||
@@ -956,10 +969,12 @@ b4_dollar_popdef[]dnl
|
|||||||
case 4: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3}"])[; break;
|
case 4: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3}"])[; break;
|
||||||
case 5: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3} or {4}"])[; break;
|
case 5: yyformat = ]b4_trans(["syntax error, unexpected {0}, expecting {1} or {2} or {3} or {4}"])[; break;
|
||||||
}
|
}
|
||||||
return new MessageFormat (yyformat).format (yystr);
|
yyerror (]b4_locations_if([[yyctx.yylocation, ]])[new MessageFormat (yyformat).format (yystr));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
]])[
|
yyerror (]b4_locations_if([[yyctx.yylocation, ]])["syntax error");]],
|
||||||
return "syntax error";
|
[simple], [[
|
||||||
|
yyerror (]b4_locations_if([[yyctx.yylocation, ]])["syntax error");]])[
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ run 0 '0.16
|
|||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
*
|
*
|
||||||
EOF
|
EOF
|
||||||
run 0 "err: 1.1: syntax error expected end of file or - or ( or end of line or double precision number or function or variable before *"
|
run 0 "err: 1.1: syntax error: expected end of file or - or ( or end of line or double precision number or function or variable before *"
|
||||||
|
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
1 + 2 * * 3
|
1 + 2 * * 3
|
||||||
EOF
|
EOF
|
||||||
run 0 "err: 1.9: syntax error expected - or ( or double precision number or function or variable before *"
|
run 0 "err: 1.9: syntax error: expected - or ( or double precision number or function or variable before *"
|
||||||
|
|||||||
@@ -200,8 +200,8 @@ yyreport_syntax_error (const yyparse_context_t *ctx)
|
|||||||
YY_LOCATION_PRINT (stderr, *yyparse_context_location (ctx));
|
YY_LOCATION_PRINT (stderr, *yyparse_context_location (ctx));
|
||||||
fprintf (stderr, ": syntax error");
|
fprintf (stderr, ": syntax error");
|
||||||
for (int i = 1; i < n; ++i)
|
for (int i = 1; i < n; ++i)
|
||||||
fprintf (stderr, " %s %s",
|
fprintf (stderr, "%s %s",
|
||||||
i == 1 ? "expected" : "or", yysymbol_name (arg[i]));
|
i == 1 ? ": expected" : " or", yysymbol_name (arg[i]));
|
||||||
if (n)
|
if (n)
|
||||||
fprintf (stderr, " before %s", yysymbol_name (arg[0]));
|
fprintf (stderr, " before %s", yysymbol_name (arg[0]));
|
||||||
fprintf (stderr, "\n");
|
fprintf (stderr, "\n");
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ run 0 '7
|
|||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
1 + 2 * * 3
|
1 + 2 * * 3
|
||||||
EOF
|
EOF
|
||||||
run 0 "err: 1.9-1.10: syntax error, unexpected '*', expecting number or '-' or '(' or '!'"
|
run 0 "err: 1.9-1.10: syntax error: expected number or '-' or '(' or '!' before '*'"
|
||||||
|
|
||||||
cat >input <<EOF
|
cat >input <<EOF
|
||||||
12 222
|
12 222
|
||||||
EOF
|
EOF
|
||||||
run 0 "err: 1.6-1.9: syntax error, unexpected number"
|
run 0 "err: 1.6-1.9: syntax error: expected end of line or '=' or '-' or '+' or '*' or '/' or '^' before number"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
%define api.parser.class {Calc}
|
%define api.parser.class {Calc}
|
||||||
%define api.parser.public
|
%define api.parser.public
|
||||||
|
|
||||||
%define parse.error detailed
|
%define parse.error custom
|
||||||
%define parse.trace
|
%define parse.trace
|
||||||
|
|
||||||
%locations
|
%locations
|
||||||
@@ -29,10 +29,17 @@
|
|||||||
if (!p.parse ())
|
if (!p.parse ())
|
||||||
System.exit (1);
|
System.exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String _ (String s)
|
||||||
|
{
|
||||||
|
return s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bison Declarations */
|
/* Bison Declarations */
|
||||||
%token <Integer> NUM "number"
|
%token
|
||||||
|
'\n' _("end of line")
|
||||||
|
<Integer> NUM _("number")
|
||||||
%type <Integer> exp
|
%type <Integer> exp
|
||||||
|
|
||||||
%nonassoc '=' /* comparison */
|
%nonassoc '=' /* comparison */
|
||||||
@@ -73,7 +80,6 @@ exp:
|
|||||||
| '-' error { $$ = 0; return YYERROR; }
|
| '-' error { $$ = 0; return YYERROR; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
class CalcLexer implements Calc.Lexer {
|
class CalcLexer implements Calc.Lexer {
|
||||||
|
|
||||||
@@ -100,6 +106,20 @@ class CalcLexer implements Calc.Lexer {
|
|||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void yyreportSyntaxError (Calc.Context ctx)
|
||||||
|
{
|
||||||
|
final int ARGMAX = 10;
|
||||||
|
int[] arg = new int[ARGMAX];
|
||||||
|
int n = Calc.yysyntaxErrorArguments (ctx, arg, ARGMAX);
|
||||||
|
System.err.print (ctx.yylocation + ": syntax error");
|
||||||
|
for (int i = 1; i < n; ++i)
|
||||||
|
System.err.print ((i == 1 ? ": expected " : " or ")
|
||||||
|
+ Calc.yysymbolName (arg[i]));
|
||||||
|
if (n != 0)
|
||||||
|
System.err.print (" before " + Calc.yysymbolName (arg[0]));
|
||||||
|
System.err.println ("");
|
||||||
|
}
|
||||||
|
|
||||||
public void yyerror (Calc.Location l, String s)
|
public void yyerror (Calc.Location l, String s)
|
||||||
{
|
{
|
||||||
if (l == null)
|
if (l == null)
|
||||||
|
|||||||
@@ -1185,8 +1185,11 @@ m4_define([AT_CHECK_CALC_LALR1_JAVA],
|
|||||||
[AT_CHECK_CALC([%language "Java" $1], [$2])])
|
[AT_CHECK_CALC([%language "Java" $1], [$2])])
|
||||||
|
|
||||||
AT_CHECK_CALC_LALR1_JAVA
|
AT_CHECK_CALC_LALR1_JAVA
|
||||||
|
AT_CHECK_CALC_LALR1_JAVA([%define parse.error custom])
|
||||||
AT_CHECK_CALC_LALR1_JAVA([%define parse.error detailed])
|
AT_CHECK_CALC_LALR1_JAVA([%define parse.error detailed])
|
||||||
AT_CHECK_CALC_LALR1_JAVA([%define parse.error verbose])
|
AT_CHECK_CALC_LALR1_JAVA([%define parse.error verbose])
|
||||||
|
AT_CHECK_CALC_LALR1_JAVA([%locations %define parse.error custom])
|
||||||
|
AT_CHECK_CALC_LALR1_JAVA([%locations %define parse.error detailed])
|
||||||
AT_CHECK_CALC_LALR1_JAVA([%locations %define parse.error verbose])
|
AT_CHECK_CALC_LALR1_JAVA([%locations %define parse.error verbose])
|
||||||
AT_CHECK_CALC_LALR1_JAVA([%define parse.trace %define parse.error verbose])
|
AT_CHECK_CALC_LALR1_JAVA([%define parse.trace %define parse.error verbose])
|
||||||
AT_CHECK_CALC_LALR1_JAVA([%define parse.trace %define parse.error verbose %locations %lex-param {InputStream is}])
|
AT_CHECK_CALC_LALR1_JAVA([%define parse.trace %define parse.error verbose %locations %lex-param {InputStream is}])
|
||||||
|
|||||||
@@ -908,6 +908,9 @@ class PositionReader extends BufferedReader {
|
|||||||
}]])
|
}]])
|
||||||
|
|
||||||
|
|
||||||
|
# AT_YYERROR_DEFINE(java)
|
||||||
|
# -----------------------
|
||||||
|
# FIXME: We should not hard-code "Calc".
|
||||||
m4_define([AT_YYERROR_DEFINE(java)],
|
m4_define([AT_YYERROR_DEFINE(java)],
|
||||||
[AT_LOCATION_IF([[public void yyerror (Calc.Location l, String m)
|
[AT_LOCATION_IF([[public void yyerror (Calc.Location l, String m)
|
||||||
{]m4_bmatch(m4_defn([AT_PARSE_PARAMS]), [nerrs],[[
|
{]m4_bmatch(m4_defn([AT_PARSE_PARAMS]), [nerrs],[[
|
||||||
@@ -925,6 +928,24 @@ m4_define([AT_YYERROR_DEFINE(java)],
|
|||||||
++*nerrs;]])[
|
++*nerrs;]])[
|
||||||
System.err.println (m);
|
System.err.println (m);
|
||||||
}
|
}
|
||||||
|
]])[
|
||||||
|
|
||||||
|
]AT_ERROR_CUSTOM_IF([[
|
||||||
|
public void yyreportSyntaxError (Calc.Context ctx)
|
||||||
|
{
|
||||||
|
int[] arg = new int[ctx.yyntokens];
|
||||||
|
int n = Calc.yysyntaxErrorArguments (ctx, arg, ctx.yyntokens);
|
||||||
|
System.err.print (]AT_LOCATION_IF([[ctx.yylocation + ": "]]
|
||||||
|
+ )["syntax error on token @<:@" + Calc.yysymbolName(arg[0]) + "@:>@");
|
||||||
|
if (1 < n)
|
||||||
|
{
|
||||||
|
System.err.print (" (expected:");
|
||||||
|
for (int i = 1; i < n; ++i)
|
||||||
|
System.err.print (" @<:@" + Calc.yysymbolName (arg[i]) + "@:>@");
|
||||||
|
System.err.print (")");
|
||||||
|
}
|
||||||
|
System.err.println ("");
|
||||||
|
}
|
||||||
]])
|
]])
|
||||||
])
|
])
|
||||||
|
|
||||||
@@ -962,6 +983,8 @@ m4_define([AT_MAIN_DEFINE(java)],
|
|||||||
m4_define([AT_LANG_FOR_EACH_STD(java)],
|
m4_define([AT_LANG_FOR_EACH_STD(java)],
|
||||||
[$1])
|
[$1])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## --------------- ##
|
## --------------- ##
|
||||||
## Running Bison. ##
|
## Running Bison. ##
|
||||||
## --------------- ##
|
## --------------- ##
|
||||||
|
|||||||
Reference in New Issue
Block a user