summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkim Demaille <akim.demaille@gmail.com>2020-02-08 15:36:18 +0100
committerAkim Demaille <akim.demaille@gmail.com>2020-02-08 16:17:53 +0100
commit80a43893774263ad5db12883eb35af2d882898e6 (patch)
tree65e9773c9bda5ddf06049cb5ce114d07c11de63a
parentef097719eaf5ca80c18c101f21d57741f8178be9 (diff)
downloadbison-80a43893774263ad5db12883eb35af2d882898e6.tar.gz
java: provide Context with a more OO interface
* data/skeletons/lalr1.java (yyexpectedTokens) (yysyntaxErrorArguments): Make them methods of Context. (Context.yysymbolName): New. * tests/local.at: Adjust.
-rw-r--r--TODO8
-rw-r--r--data/skeletons/lalr1.java151
-rw-r--r--examples/java/calc/Calc.y6
-rw-r--r--tests/local.at6
4 files changed, 91 insertions, 80 deletions
diff --git a/TODO b/TODO
index 45263e10..32c7ec38 100644
--- a/TODO
+++ b/TODO
@@ -18,6 +18,14 @@ 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).
+** Java: _
+We must not use _ in Java, it is becoming a keyword in Java 9.
+
+examples/java/calc/Calc.java:998: warning: '_' used as an identifier
+ "$end", "error", "$undefined", _("end of line"), _("number"), "'='",
+ ^
+ (use of '_' as an identifier might not be supported in releases after Java SE 8)
+
** doc
I feel it's ugly to use the GNU style to declare functions in the doc. It
generates tons of white space in the page, and may contribute to bad page
diff --git a/data/skeletons/lalr1.java b/data/skeletons/lalr1.java
index a9725d7b..3b476ff8 100644
--- a/data/skeletons/lalr1.java
+++ b/data/skeletons/lalr1.java
@@ -866,80 +866,83 @@ b4_dollar_popdef[]dnl
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
- current YYCTX, and return the number of tokens stored in YYARG. If
- YYARG is null, return the number of expected tokens (guaranteed to
- be less than YYNTOKENS_). */
- static int
- yyexpectedTokens (Context yyctx,
- int yyarg[], int yyoffset, int yyargn)
- {
- int yycount = yyoffset;
- int yyn = yypact_[yyctx.yystack.stateAt (0)];
- if (!yyPactValueIsDefault (yyn))
- {
- /* Start YYX at -YYN if negative to avoid negative
- indexes in YYCHECK. In other words, skip the first
- -YYN actions for this state because they are default
- actions. */
- int yyxbegin = yyn < 0 ? -yyn : 0;
- /* Stay within bounds of both yycheck and yytname. */
- int yychecklim = yylast_ - yyn + 1;
- int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
- for (int x = yyxbegin; x < yyxend; ++x)
- if (yycheck_[x + yyn] == x && x != yy_error_token_
- && !yyTableValueIsError (yytable_[x + yyn]))
- {
- if (yyarg == null)
- yycount += 1;
- else if (yycount == yyargn)
- return 0; // FIXME: this is incorrect.
- else
- yyarg[yycount++] = x;
- }
- }
- return yycount - yyoffset;
- }
- static int
- yysyntaxErrorArguments (Context yyctx,
- int[] yyarg, int yyargn)
- {
- /* There are many possibilities here to consider:
- - If this state is a consistent state with a default action,
- then the only way this function was invoked is if the
- default action is an error action. In that case, don't
- check for expected tokens because there are none.
- - The only way there can be no lookahead present (in tok) is
- if this state is a consistent state with a default action.
- Thus, detecting the absence of a lookahead is sufficient to
- determine that there is no unexpected or expected token to
- report. In that case, just report a simple "syntax error".
- - Don't assume there isn't a lookahead just because this
- state is a consistent state with a default action. There
- might have been a previous inconsistent state, consistent
- state with a non-default action, or user semantic action
- that manipulated yychar. (However, yychar is currently out
- of scope during semantic actions.)
- - Of course, the expected token list depends on states to
- have correct lookahead information, and it depends on the
- parser not to perform extra reductions after fetching a
- lookahead from the scanner and before detecting a syntax
- error. Thus, state merging (from LALR or IELR) and default
- reductions corrupt the expected token list. However, the
- list is correct for canonical LR with one exception: it
- will still contain any token that will not be accepted due
- to an error action in a later state.
- */
- int yycount = 0;
- if (yyctx.yytoken != yyempty_)
- {
- yyarg[yycount++] = yyctx.yytoken;
- yycount += yyexpectedTokens (yyctx, yyarg, 1, yyargn);
- }
- return yycount;
+ /* Put in YYARG at most YYARGN of the expected tokens given the
+ current YYCTX, and return the number of tokens stored in YYARG. If
+ YYARG is null, return the number of expected tokens (guaranteed to
+ be less than YYNTOKENS). */
+ int yyexpectedTokens (int yyarg[], int yyoffset, int yyargn)
+ {
+ int yycount = yyoffset;
+ int yyn = yypact_[this.yystack.stateAt (0)];
+ if (!yyPactValueIsDefault (yyn))
+ {
+ /* Start YYX at -YYN if negative to avoid negative
+ indexes in YYCHECK. In other words, skip the first
+ -YYN actions for this state because they are default
+ actions. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = yylast_ - yyn + 1;
+ int yyxend = yychecklim < yyntokens ? yychecklim : yyntokens;
+ for (int x = yyxbegin; x < yyxend; ++x)
+ if (yycheck_[x + yyn] == x && x != yy_error_token_
+ && !yyTableValueIsError (yytable_[x + yyn]))
+ {
+ if (yyarg == null)
+ yycount += 1;
+ else if (yycount == yyargn)
+ return 0; // FIXME: this is incorrect.
+ else
+ yyarg[yycount++] = x;
+ }
+ }
+ return yycount - yyoffset;
+ }
+
+ /* The user-facing name of the symbol whose (internal) number is
+ YYSYMBOL. No bounds checking. */
+ static String yysymbolName (int yysymbol)
+ {
+ return ]b4_parser_class[.yysymbolName (yysymbol);
+ }
+
+ int yysyntaxErrorArguments (int[] yyarg, int yyargn)
+ {
+ /* There are many possibilities here to consider:
+ - If this state is a consistent state with a default action,
+ then the only way this function was invoked is if the
+ default action is an error action. In that case, don't
+ check for expected tokens because there are none.
+ - The only way there can be no lookahead present (in tok) is
+ if this state is a consistent state with a default action.
+ Thus, detecting the absence of a lookahead is sufficient to
+ determine that there is no unexpected or expected token to
+ report. In that case, just report a simple "syntax error".
+ - Don't assume there isn't a lookahead just because this
+ state is a consistent state with a default action. There
+ might have been a previous inconsistent state, consistent
+ state with a non-default action, or user semantic action
+ that manipulated yychar. (However, yychar is currently out
+ of scope during semantic actions.)
+ - Of course, the expected token list depends on states to
+ have correct lookahead information, and it depends on the
+ parser not to perform extra reductions after fetching a
+ lookahead from the scanner and before detecting a syntax
+ error. Thus, state merging (from LALR or IELR) and default
+ reductions corrupt the expected token list. However, the
+ list is correct for canonical LR with one exception: it
+ will still contain any token that will not be accepted due
+ to an error action in a later state.
+ */
+ int yycount = 0;
+ if (this.yytoken != yyempty_)
+ {
+ yyarg[yycount++] = this.yytoken;
+ yycount += this.yyexpectedTokens (yyarg, 1, yyargn);
+ }
+ return yycount;
+ }
}
/**
@@ -954,7 +957,7 @@ b4_dollar_popdef[]dnl
{
final int argmax = 5;
int[] yyarg = new int[argmax];
- int yycount = yysyntaxErrorArguments (yyctx, yyarg, argmax);
+ int yycount = yyctx.yysyntaxErrorArguments (yyarg, argmax);
String[] yystr = new String[yycount];
for (int yyi = 0; yyi < yycount; ++yyi)
yystr[yyi] = yysymbolName (yyarg[yyi]);
diff --git a/examples/java/calc/Calc.y b/examples/java/calc/Calc.y
index bc832aba..b1d21ac7 100644
--- a/examples/java/calc/Calc.y
+++ b/examples/java/calc/Calc.y
@@ -110,13 +110,13 @@ class CalcLexer implements Calc.Lexer {
{
final int ARGMAX = 10;
int[] arg = new int[ARGMAX];
- int n = Calc.yysyntaxErrorArguments (ctx, arg, ARGMAX);
+ int n = ctx.yysyntaxErrorArguments (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]));
+ + ctx.yysymbolName (arg[i]));
if (n != 0)
- System.err.print (" before " + Calc.yysymbolName (arg[0]));
+ System.err.print (" before " + ctx.yysymbolName (arg[0]));
System.err.println ("");
}
diff --git a/tests/local.at b/tests/local.at
index 097197d5..d35bbf68 100644
--- a/tests/local.at
+++ b/tests/local.at
@@ -934,14 +934,14 @@ m4_define([AT_YYERROR_DEFINE(java)],
public void yyreportSyntaxError (Calc.Context ctx)
{
int[] arg = new int[ctx.yyntokens];
- int n = Calc.yysyntaxErrorArguments (ctx, arg, ctx.yyntokens);
+ int n = ctx.yysyntaxErrorArguments (arg, ctx.yyntokens);
System.err.print (]AT_LOCATION_IF([[ctx.yylocation + ": "]]
- + )["syntax error on token @<:@" + Calc.yysymbolName(arg[0]) + "@:>@");
+ + )["syntax error on token @<:@" + ctx.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 (" @<:@" + ctx.yysymbolName (arg[i]) + "@:>@");
System.err.print (")");
}
System.err.println ("");