glr2.cc: rely on symbol kinds rather than token kinds

Instead of tracking the lookahead with yychar, use yytoken.  This is
consistent with lalr1.cc, saves us from calls to YYTRANSLATE (except
when calling yylex), and makes it easier to migrate to using
symbol_type.

* data/skeletons/glr2.cc: Replace all uses of `int yychar` with
`symbol_kind_type yytoken`.
(yygetToken): Don't take/return the lookahead's token-kind and
symbol-kind, just work directly on yystack's `yytoken` member.

* tests/glr-regression.at (AT_PRINT_LOOKAHEAD_DECLARE)
(AT_PRINT_LOOKAHEAD_DEFINE): New.
Adjust to the fact that we have yytoken, not yychar, in glr2.cc.
This commit is contained in:
Akim Demaille
2021-01-10 08:17:11 +01:00
parent 47612d987b
commit 3fa59c32fc
2 changed files with 155 additions and 144 deletions

View File

@@ -648,8 +648,8 @@ static void yypdumpstack (const glr_stack& yystack)
#else /* !]b4_api_PREFIX[DEBUG */ #else /* !]b4_api_PREFIX[DEBUG */
# define YYCDEBUG if (true) {} else std::cerr # define YYCDEBUG if (true) {} else std::cerr
# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) {}
# define YY_REDUCE_PRINT(Args) # define YY_REDUCE_PRINT(Args) {}
#endif /* !]b4_api_PREFIX[DEBUG */ #endif /* !]b4_api_PREFIX[DEBUG */
@@ -705,8 +705,8 @@ state_set_index create_state_set_index(std::ptrdiff_t value)
#define yytable_value_is_error(Yytable_value) \ #define yytable_value_is_error(Yytable_value) \
]b4_table_value_equals([[table]], [[Yytable_value]], [b4_table_ninf], [YYTABLE_NINF])[ ]b4_table_value_equals([[table]], [[Yytable_value]], [b4_table_ninf], [YYTABLE_NINF])[
static inline yysymbol_kind_t static inline void
yygetToken (int& yycharp, ]b4_namespace_ref[::]b4_parser_class[& yyparser, glr_stack& yystack]b4_user_formals[); yygetToken (]b4_namespace_ref[::]b4_parser_class[& yyparser, glr_stack& yystack]b4_user_formals[);
static inline bool static inline bool
yyisShiftAction (int yyaction) yyisShiftAction (int yyaction)
@@ -760,6 +760,7 @@ class glr_state
{ {
public: public:
typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind symbol_kind; typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind symbol_kind;
typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type symbol_kind_type;
typedef ]b4_namespace_ref[::]b4_parser_class[::value_type value_type;]b4_locations_if([[ typedef ]b4_namespace_ref[::]b4_parser_class[::value_type value_type;]b4_locations_if([[
typedef ]b4_namespace_ref[::]b4_parser_class[::location_type location_type;]])[ typedef ]b4_namespace_ref[::]b4_parser_class[::location_type location_type;]])[
@@ -1096,7 +1097,7 @@ private:
/** During nondeterministic operation, yylookaheadNeeds tracks which /** During nondeterministic operation, yylookaheadNeeds tracks which
* stacks have actually needed the current lookahead. During deterministic * stacks have actually needed the current lookahead. During deterministic
* operation, yylookaheadNeeds[0] is not maintained since it would merely * operation, yylookaheadNeeds[0] is not maintained since it would merely
* duplicate yychar != ]b4_symbol(empty, id)[. */ * duplicate yytoken != ]b4_symbol(empty, kind)[. */
std::vector<bool> yylookaheadNeeds; std::vector<bool> yylookaheadNeeds;
/** The last stack we invalidated. */ /** The last stack we invalidated. */
@@ -1107,6 +1108,7 @@ class semantic_option
{ {
public: public:
typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind symbol_kind; typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind symbol_kind;
typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type symbol_kind_type;
typedef ]b4_namespace_ref[::]b4_parser_class[::value_type value_type;]b4_locations_if([[ typedef ]b4_namespace_ref[::]b4_parser_class[::value_type value_type;]b4_locations_if([[
typedef ]b4_namespace_ref[::]b4_parser_class[::location_type location_type;]])[ typedef ]b4_namespace_ref[::]b4_parser_class[::location_type location_type;]])[
@@ -1114,17 +1116,17 @@ public:
: yyrule (0) : yyrule (0)
, yystate (0) , yystate (0)
, yynext (0) , yynext (0)
, yychar (0) , yytoken (]b4_symbol(empty, kind)[)
, yyval ()]b4_locations_if([[ , yyval ()]b4_locations_if([[
, yyloc ()]])[]b4_parse_assert_if([[ , yyloc ()]])[]b4_parse_assert_if([[
, magic_ (MAGIC)]])[ , magic_ (MAGIC)]])[
{} {}
semantic_option (rule_num rule, int rawChar) semantic_option (rule_num rule, symbol_kind_type token)
: yyrule (rule) : yyrule (rule)
, yystate (0) , yystate (0)
, yynext (0) , yynext (0)
, yychar (rawChar) , yytoken (token)
, yyval ()]b4_locations_if([[ , yyval ()]b4_locations_if([[
, yyloc ()]])[]b4_parse_assert_if([[ , yyloc ()]])[]b4_parse_assert_if([[
, magic_ (MAGIC)]])[ , magic_ (MAGIC)]])[
@@ -1134,13 +1136,13 @@ public:
: yyrule (that.yyrule) : yyrule (that.yyrule)
, yystate (that.yystate) , yystate (that.yystate)
, yynext (that.yynext) , yynext (that.yynext)
, yychar (that.yychar) , yytoken (that.yytoken)
, yyval (]b4_variant_if([], [[that.yyval]])[)]b4_locations_if([[ , yyval (]b4_variant_if([], [[that.yyval]])[)]b4_locations_if([[
, yyloc (that.yyloc)]])[]b4_parse_assert_if([[ , yyloc (that.yyloc)]])[]b4_parse_assert_if([[
, magic_ (MAGIC)]])[ , magic_ (MAGIC)]])[
{]b4_parse_assert_if([[ {]b4_parse_assert_if([[
that.check_ ();]])[]b4_variant_if([[ that.check_ ();]])[]b4_variant_if([[
]b4_symbol_variant([YYTRANSLATE (yychar)], ]b4_symbol_variant([yytoken],
[yyval], [copy], [that.yyval])])[ [yyval], [copy], [that.yyval])])[
} }
@@ -1152,8 +1154,8 @@ public:
yyrule = that.yyrule; yyrule = that.yyrule;
yystate = that.yystate; yystate = that.yystate;
yynext = that.yynext; yynext = that.yynext;
yychar = that.yychar;]b4_variant_if([[ yytoken = that.yytoken;]b4_variant_if([[
]b4_symbol_variant([YYTRANSLATE (yychar)], ]b4_symbol_variant([yytoken],
[yyval], [copy], [that.yyval])], [[ [yyval], [copy], [that.yyval])], [[
yyval = that.yyval;]])[]b4_locations_if([[ yyval = that.yyval;]])[]b4_locations_if([[
yyloc = that.yyloc;]])[ yyloc = that.yyloc;]])[
@@ -1338,7 +1340,7 @@ private:
public: public:
/** The lookahead for this reduction. */ /** The lookahead for this reduction. */
int yychar; symbol_kind_type yytoken;
value_type yyval;]b4_locations_if([[ value_type yyval;]b4_locations_if([[
location_type yyloc;]])[ location_type yyloc;]])[
@@ -2023,6 +2025,7 @@ class glr_stack
{ {
public: public:
typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind symbol_kind; typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind symbol_kind;
typedef ]b4_namespace_ref[::]b4_parser_class[::symbol_kind_type symbol_kind_type;
typedef ]b4_namespace_ref[::]b4_parser_class[::value_type value_type;]b4_locations_if([[ typedef ]b4_namespace_ref[::]b4_parser_class[::value_type value_type;]b4_locations_if([[
typedef ]b4_namespace_ref[::]b4_parser_class[::location_type location_type;]])[ typedef ]b4_namespace_ref[::]b4_parser_class[::location_type location_type;]])[
@@ -2030,15 +2033,15 @@ public:
: yyerrState (0) : yyerrState (0)
, yystateStack (yysize) , yystateStack (yysize)
, yyerrcnt (0) , yyerrcnt (0)
, yychar (0) , yytoken (]b4_symbol(empty, kind)[)
, yyparser (yyparser_yyarg)]m4_ifset([b4_parse_param], [,b4_parse_param_cons])[ , yyparser (yyparser_yyarg)]m4_ifset([b4_parse_param], [,b4_parse_param_cons])[
{} {}
~glr_stack () ~glr_stack ()
{ {
if (this->yychar != ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(empty, id)[) if (this->yytoken != ]b4_namespace_ref[::]b4_parser_class[::]b4_symbol(empty, kind)[)
yyparser.yy_destroy_ ("Cleanup: discarding lookahead", yyparser.yy_destroy_ ("Cleanup: discarding lookahead",
YYTRANSLATE (this->yychar), this->yylval]b4_locations_if([, this->yylloc])[); this->yytoken, this->yylval]b4_locations_if([, this->yylloc])[);
popall_ (); popall_ ();
} }
@@ -2047,7 +2050,7 @@ public:
glr_stack_item yyerror_range[3];]])[ glr_stack_item yyerror_range[3];]])[
state_stack yystateStack; state_stack yystateStack;
int yyerrcnt; int yyerrcnt;
int yychar; symbol_kind_type yytoken;
value_type yylval;]b4_locations_if([[ value_type yylval;]b4_locations_if([[
location_type yylloc;]])[ location_type yylloc;]])[
YYJMP_BUF yyexception_buffer; YYJMP_BUF yyexception_buffer;
@@ -2084,13 +2087,13 @@ public:
glr_state* yyrhs, rule_num yyrule) glr_state* yyrhs, rule_num yyrule)
{ {
semantic_option& yynewOption = semantic_option& yynewOption =
yystateStack.yynewSemanticOption(semantic_option(yyrule, ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(empty, id)[)); yystateStack.yynewSemanticOption(semantic_option(yyrule, ]b4_namespace_ref[::]b4_parser_class[::]b4_symbol(empty, kind)[));
yynewOption.setState(yyrhs); yynewOption.setState(yyrhs);
yynewOption.setNext(yystate->firstVal()); yynewOption.setNext(yystate->firstVal());
if (yystateStack.yytops.lookaheadNeeds(yyk)) if (yystateStack.yytops.lookaheadNeeds(yyk))
{ {
yynewOption.yychar = this->yychar;]b4_variant_if([[ yynewOption.yytoken = this->yytoken;]b4_variant_if([[
]b4_symbol_variant([YYTRANSLATE (this->yychar)], ]b4_symbol_variant([this->yytoken],
[yynewOption.yyval], [copy], [this->yylval])], [[ [yynewOption.yyval], [copy], [this->yylval])], [[
yynewOption.yyval = this->yylval;]])[]b4_locations_if([ yynewOption.yyval = this->yylval;]])[]b4_locations_if([
yynewOption.yyloc = this->yylloc;])[ yynewOption.yyloc = this->yylloc;])[
@@ -2115,10 +2118,6 @@ public:
[simple], [simple],
[[ yyparser.error (]b4_locations_if([this->yylloc, ])[YY_("syntax error"));]], [[ yyparser.error (]b4_locations_if([this->yylloc, ])[YY_("syntax error"));]],
[[ { [[ {
yysymbol_kind_t yytoken
= this->yychar == ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(empty, id)[
? ]b4_namespace_ref[::]b4_parser_class[::]b4_symbol(empty, kind)[
: YYTRANSLATE (this->yychar);
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Arguments of yyformat. */ /* Arguments of yyformat. */
yysymbol_kind_t yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM] yysymbol_kind_t yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]
@@ -2132,7 +2131,7 @@ public:
the only way this function was invoked is if the default action the only way this function was invoked is if the default action
is an error action. In that case, don't check for expected is an error action. In that case, don't check for expected
tokens because there are none. tokens because there are none.
- The only way there can be no lookahead present (in yychar) is if - The only way there can be no lookahead present (in yytoken) is if
this state is a consistent state with a default action. Thus, this state is a consistent state with a default action. Thus,
detecting the absence of a lookahead is sufficient to determine detecting the absence of a lookahead is sufficient to determine
that there is no unexpected or expected token to report. In that that there is no unexpected or expected token to report. In that
@@ -2140,7 +2139,7 @@ public:
- Don't assume there isn't a lookahead just because this state is a - 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 consistent state with a default action. There might have been a
previous inconsistent state, consistent state with a non-default previous inconsistent state, consistent state with a non-default
action, or user semantic action that manipulated yychar. action, or user semantic action that manipulated yytoken.
- Of course, the expected token list depends on states to have - Of course, the expected token list depends on states to have
correct lookahead information, and it depends on the parser not correct lookahead information, and it depends on the parser not
to perform extra reductions after fetching a lookahead from the to perform extra reductions after fetching a lookahead from the
@@ -2213,7 +2212,7 @@ public:
} }
/* Recover from a syntax error on this, assuming that YYTOKENP, /* Recover from a syntax error on this, assuming that yytoken,
yylval, and yylloc are the syntactic category, semantic value, and location yylval, and yylloc are the syntactic category, semantic value, and location
of the lookahead. */ of the lookahead. */
void void
@@ -2224,9 +2223,9 @@ public:
reductions. Skip tokens until we can proceed. */ reductions. Skip tokens until we can proceed. */
while (true) while (true)
{ {
if (this->yychar == ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(eof, id)[) if (this->yytoken == ]b4_namespace_ref[::]b4_parser_class[::]b4_symbol(eof, kind)[)
yyFail (]b4_locations_if([yylocp, ])[YY_NULLPTR); yyFail (]b4_locations_if([yylocp, ])[YY_NULLPTR);
if (this->yychar != ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(empty, id)[) if (this->yytoken != ]b4_namespace_ref[::]b4_parser_class[::]b4_symbol(empty, kind)[)
{]b4_locations_if([[ {]b4_locations_if([[
/* We throw away the lookahead, but the error range /* We throw away the lookahead, but the error range
of the shifted error token must take it into account. */ of the shifted error token must take it into account. */
@@ -2234,19 +2233,18 @@ public:
yyerror_range[1].getState().yyloc = yys->yyloc; yyerror_range[1].getState().yyloc = yys->yyloc;
yyerror_range[2].getState().yyloc = this->yylloc; yyerror_range[2].getState().yyloc = this->yylloc;
YYLLOC_DEFAULT ((yys->yyloc), yyerror_range, 2);]])[ YYLLOC_DEFAULT ((yys->yyloc), yyerror_range, 2);]])[
yysymbol_kind_t yytoken = YYTRANSLATE (this->yychar);
yyparser.yy_destroy_ ("Error: discarding", yyparser.yy_destroy_ ("Error: discarding",
yytoken, yylval]b4_locations_if([, yylloc])[);]b4_variant_if([[ this->yytoken, this->yylval]b4_locations_if([, this->yylloc])[);]b4_variant_if([[
// Value type destructor. // Value type destructor.
]b4_symbol_variant([[YYTRANSLATE (this->yychar)]], [[yylval]], [[template destroy]])])[ ]b4_symbol_variant([[this->yytoken]], [[this->yylval]], [[template destroy]])])[
this->yychar = ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(empty, id)[; this->yytoken = ]b4_namespace_ref[::]b4_parser_class[::]b4_symbol(empty, kind)[;
} }
yysymbol_kind_t yytoken = yygetToken (this->yychar, yyparser, *this]b4_user_args[); yygetToken (yyparser, *this]b4_user_args[);
int yyj = yypact[firstTopState()->yylrState]; int yyj = yypact[firstTopState()->yylrState];
if (yypact_value_is_default (yyj)) if (yypact_value_is_default (yyj))
return; return;
yyj += yytoken; yyj += this->yytoken;
if (yyj < 0 || YYLAST < yyj || yycheck[yyj] != yytoken) if (yyj < 0 || YYLAST < yyj || yycheck[yyj] != this->yytoken)
{ {
if (yydefact[firstTopState()->yylrState] != 0) if (yydefact[firstTopState()->yylrState] != 0)
return; return;
@@ -2329,9 +2327,9 @@ public:
else else
{ {
yystateStack.yytops.setLookaheadNeeds(yyk, true); yystateStack.yytops.setLookaheadNeeds(yyk, true);
const yysymbol_kind_t yytoken = yygetToken (this->yychar, yyparser, *this]b4_user_args[); yygetToken (yyparser, *this]b4_user_args[);
const short* yyconflicts; const short* yyconflicts;
const int yyaction = yygetLRActions (yystate, yytoken, yyconflicts); const int yyaction = yygetLRActions (yystate, this->yytoken, yyconflicts);
for (; *yyconflicts != 0; ++yyconflicts) for (; *yyconflicts != 0; ++yyconflicts)
{ {
@@ -2403,10 +2401,10 @@ public:
# define YYERROR return yyerrok, yyerr # define YYERROR return yyerrok, yyerr
# undef YYRECOVERING # undef YYRECOVERING
# define YYRECOVERING() (yyerrState != 0) # define YYRECOVERING() (yyerrState != 0)
# undef yychar # undef yytoken
# define yychar this->yychar # define yytoken this->yytoken
# undef yyclearin # undef yyclearin
# define yyclearin (yychar = ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(empty, id)[) # define yyclearin (yytoken = ]b4_namespace_ref[::]b4_parser_class[::]b4_symbol(empty, kind)[)
# undef YYBACKUP # undef YYBACKUP
# define YYBACKUP(Token, Value) \ # define YYBACKUP(Token, Value) \
return yyparser.error (]b4_locations_if([*yylocp, ])[YY_("syntax error: cannot back up")), \ return yyparser.error (]b4_locations_if([*yylocp, ])[YY_("syntax error: cannot back up")), \
@@ -2460,7 +2458,7 @@ public:
# undef YYACCEPT # undef YYACCEPT
# undef YYERROR # undef YYERROR
# undef YYBACKUP # undef YYBACKUP
# undef yychar # undef yytoken
# undef yyclearin # undef yyclearin
# undef YYRECOVERING # undef YYRECOVERING
} }
@@ -2835,15 +2833,15 @@ private:
/* Set default location. */ /* Set default location. */
yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].getState().yyloc = yyoptState->yyloc;]])[ yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].getState().yyloc = yyoptState->yyloc;]])[
{ {
int yychar_current = this->yychar;]b4_variant_if([[ symbol_kind_type yytoken_current = this->yytoken;]b4_variant_if([[
value_type yylval_current; value_type yylval_current;
]b4_symbol_variant([YYTRANSLATE (this->yychar)], ]b4_symbol_variant([this->yytoken],
[yylval_current], [move], [this->yylval])], [[ [yylval_current], [move], [this->yylval])], [[
value_type yylval_current = this->yylval;]])[]b4_locations_if([ value_type yylval_current = this->yylval;]])[]b4_locations_if([
location_type yylloc_current = this->yylloc;])[ location_type yylloc_current = this->yylloc;])[
this->yychar = yyopt.yychar;]b4_variant_if([[ this->yytoken = yyopt.yytoken;]b4_variant_if([[
]b4_symbol_variant([YYTRANSLATE (this->yychar)], ]b4_symbol_variant([this->yytoken],
[this->yylval], [move], [yyopt.yyval])], [[ [this->yylval], [move], [yyopt.yyval])], [[
this->yylval = yyopt.yyval;]])[]b4_locations_if([ this->yylval = yyopt.yyval;]])[]b4_locations_if([
this->yylloc = yyopt.yyloc;])[ this->yylloc = yyopt.yyloc;])[
@@ -2852,8 +2850,8 @@ private:
create_state_set_index (-1), create_state_set_index (-1),
yyvalp]b4_locations_if([, yylocp])[); yyvalp]b4_locations_if([, yylocp])[);
this->yychar = yychar_current;]b4_variant_if([[ this->yytoken = yytoken_current;]b4_variant_if([[
]b4_symbol_variant([YYTRANSLATE (this->yychar)], ]b4_symbol_variant([this->yytoken],
[this->yylval], [move], [yylval_current])], [[ [this->yylval], [move], [yylval_current])], [[
this->yylval = yylval_current;]])[]b4_locations_if([ this->yylval = yylval_current;]])[]b4_locations_if([
this->yylloc = yylloc_current;])[ this->yylloc = yylloc_current;])[
@@ -2911,20 +2909,20 @@ private:
#undef YYSTACKEXPANDABLE #undef YYSTACKEXPANDABLE
/** If yychar is empty, fetch the next token. */ /** If yytoken is empty, fetch the next token. */
static inline yysymbol_kind_t static inline void
yygetToken (int& yycharp, ]b4_namespace_ref[::]b4_parser_class[& yyparser, glr_stack& yystack]b4_user_formals[) yygetToken (]b4_namespace_ref[::]b4_parser_class[& yyparser, glr_stack& yystack]b4_user_formals[)
{ {
yysymbol_kind_t yytoken;
]b4_parse_param_use()dnl ]b4_parse_param_use()dnl
[ if (yycharp == ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(empty, id)[) [ if (yystack.yytoken == ]b4_namespace_ref[::]b4_parser_class[::]b4_symbol(empty, kind)[)
{ {
YYCDEBUG << "Reading a token\n"; YYCDEBUG << "Reading a token\n";
int yychar;
#if YY_EXCEPTIONS #if YY_EXCEPTIONS
try try
{ {
#endif // YY_EXCEPTIONS #endif // YY_EXCEPTIONS
yycharp = ]b4_lex[; yychar = ]b4_lex[;
#if YY_EXCEPTIONS #if YY_EXCEPTIONS
} }
catch (const ]b4_namespace_ref[::]b4_parser_class[::syntax_error& yyexc) catch (const ]b4_namespace_ref[::]b4_parser_class[::syntax_error& yyexc)
@@ -2934,22 +2932,18 @@ yygetToken (int& yycharp, ]b4_namespace_ref[::]b4_parser_class[& yyparser, glr_s
yyparser.error (]b4_locations_if([yystack.yylloc, ])[yyexc.what ()); yyparser.error (]b4_locations_if([yystack.yylloc, ])[yyexc.what ());
// Map errors caught in the scanner to the error token, so that error // Map errors caught in the scanner to the error token, so that error
// handling is started. // handling is started.
yycharp = ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(error, id)[; yychar = ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(error, id)[;
} }
#endif // YY_EXCEPTIONS #endif // YY_EXCEPTIONS
yystack.yytoken
= (yychar <= ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(eof, id)[)
? ]b4_namespace_ref[::]b4_parser_class[::]b4_symbol(eof, kind)[
: YYTRANSLATE (yychar);
} }
if (yycharp <= ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(eof, id)[) if (yystack.yytoken == ]b4_namespace_ref[::]b4_parser_class[::]b4_symbol(eof, kind)[)
{ YYCDEBUG << "Now at end of input.\n";
yycharp = ]b4_namespace_ref[::]b4_parser_class[::token::]b4_symbol(eof, id)[;
yytoken = ]b4_namespace_ref[::]b4_parser_class[::]b4_symbol(eof, kind)[;
YYCDEBUG << "Now at end of input.\n";
}
else else
{ YY_SYMBOL_PRINT ("Next token is", yystack.yytoken, yystack.yylval, yystack.yylloc);
yytoken = YYTRANSLATE (yycharp);
YY_SYMBOL_PRINT ("Next token is", yytoken, yystack.yylval, yystack.yylloc);
}
return yytoken;
} }
@@ -3103,7 +3097,7 @@ m4_pushdef([b4_parse_param], m4_defn([b4_parse_param_orig]))dnl
YYCDEBUG << "Starting parse\n"; YYCDEBUG << "Starting parse\n";
yystack.yychar = token::]b4_symbol(empty, id)[;]b4_variant_if([], [[ yystack.yytoken = ]b4_symbol(empty, kind)[;]b4_variant_if([], [[
yystack.yylval = yyval_default;]])[]b4_locations_if([ yystack.yylval = yyval_default;]])[]b4_locations_if([
yystack.yylloc = yyloc_default;])[ yystack.yylloc = yyloc_default;])[
]m4_ifdef([b4_initial_action], [ ]m4_ifdef([b4_initial_action], [
@@ -3146,21 +3140,21 @@ b4_dollar_popdef])[]dnl
} }
else else
{ {
const yysymbol_kind_t yytoken = yygetToken (yystack.yychar, yyparser, yystack]b4_user_args[); yygetToken (yyparser, yystack]b4_user_args[);
const short* yyconflicts; const short* yyconflicts;
const int yyaction = yygetLRActions (yystate, yytoken, yyconflicts); const int yyaction = yygetLRActions (yystate, yystack.yytoken, yyconflicts);
if (*yyconflicts != 0) if (*yyconflicts != 0)
break; break;
if (yyisShiftAction (yyaction)) if (yyisShiftAction (yyaction))
{ {
YY_SYMBOL_PRINT ("Shifting", yytoken, yystack.yylval, yystack.yylloc); YY_SYMBOL_PRINT ("Shifting", yystack.yytoken, yystack.yylval, yystack.yylloc);
yystack.yychar = token::]b4_symbol(empty, id)[;
yyposn += 1; yyposn += 1;
// FIXME: we should move yylval. // FIXME: we should move yylval.
yystack.yyglrShift (create_state_set_index(0), yyaction, yyposn, yystack.yylval]b4_locations_if([, yystack.yylloc])[);]b4_variant_if([[ yystack.yyglrShift (create_state_set_index(0), yyaction, yyposn, yystack.yylval]b4_locations_if([, yystack.yylloc])[);]b4_variant_if([[
// FIXME: User destructors. // FIXME: User destructors.
// Value type destructor. // Value type destructor.
]b4_symbol_variant([[yytoken]], [[yystack.yylval]], [[template destroy]])])[ ]b4_symbol_variant([[yystack.yytoken]], [[yystack.yylval]], [[template destroy]])])[
yystack.yytoken = ]b4_symbol(empty, kind)[;
if (0 < yystack.yyerrState) if (0 < yystack.yyerrState)
yystack.yyerrState -= 1; yystack.yyerrState -= 1;
} }
@@ -3169,7 +3163,7 @@ b4_dollar_popdef])[]dnl
yystack.yyerror_range[1].getState().yyloc = yystack.yylloc;]])[ yystack.yyerror_range[1].getState().yyloc = yystack.yylloc;]])[
/* Don't issue an error message again for exceptions /* Don't issue an error message again for exceptions
thrown from the scanner. */ thrown from the scanner. */
if (yystack.yychar != token::]b4_symbol(error, id)[) if (yystack.yytoken != ]b4_symbol(error, kind)[)
yystack.yyreportSyntaxError (); yystack.yyreportSyntaxError ();
goto yyuser_error; goto yyuser_error;
} }
@@ -3181,7 +3175,7 @@ b4_dollar_popdef])[]dnl
while (true) while (true)
{ {
for (state_set_index yys = create_state_set_index(0); yys.uget() < yystack.yystateStack.numTops(); ++yys) for (state_set_index yys = create_state_set_index(0); yys.uget() < yystack.yystateStack.numTops(); ++yys)
yystack.yystateStack.yytops.setLookaheadNeeds(yys, yystack.yychar != token::]b4_symbol(empty, id)[); yystack.yystateStack.yytops.setLookaheadNeeds(yys, yystack.yytoken != ]b4_symbol(empty, kind)[);
/* yyprocessOneStack returns one of three things: /* yyprocessOneStack returns one of three things:
@@ -3219,11 +3213,11 @@ b4_dollar_popdef])[]dnl
/* If any yyglrShift call fails, it will fail after shifting. Thus, /* If any yyglrShift call fails, it will fail after shifting. Thus,
a copy of yylval will already be on stack 0 in the event of a a copy of yylval will already be on stack 0 in the event of a
failure in the following loop. Thus, yychar is set to ]b4_symbol(empty, id)[ failure in the following loop. Thus, yytoken is set to ]b4_symbol(empty, kind)[
before the loop to make sure the user destructor for yylval isn't before the loop to make sure the user destructor for yylval isn't
called twice. */ called twice. */
yysymbol_kind_t yytoken_to_shift = YYTRANSLATE (yystack.yychar); yysymbol_kind_t yytoken_to_shift = yystack.yytoken;
yystack.yychar = token::]b4_symbol(empty, id)[; yystack.yytoken = ]b4_symbol(empty, kind)[;
yyposn += 1; yyposn += 1;
for (state_set_index yys = create_state_set_index(0); yys.uget() < yystack.yystateStack.numTops(); ++yys) for (state_set_index yys = create_state_set_index(0); yys.uget() < yystack.yystateStack.numTops(); ++yys)
{ {

View File

@@ -38,6 +38,63 @@ yyparse ()
]])]) ]])])
# AT_PRINT_LOOKAHEAD_DECLARE
# --------------------------
m4_define([AT_PRINT_LOOKAHEAD_DECLARE],
[AT_GLR2_CC_IF(
[[ static void
print_lookahead (int yytoken, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
char const *reduction);
#define PRINT_LOOKAHEAD(Msg) \
print_lookahead (yytoken, &yylval, &yylloc, Msg)
]],
[[ static void
print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
char const *reduction);
#define PRINT_LOOKAHEAD(Msg) \
print_lookahead (yychar, &yylval, &yylloc, Msg)
]])])
# AT_PRINT_LOOKAHEAD_DEFINE
# -------------------------
m4_define([AT_PRINT_LOOKAHEAD_DEFINE],
[AT_GLR2_CC_IF(
[[static void
print_lookahead (int yytoken, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
char const *reduction)
]],
[[static void
print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
char const *reduction)
]])[
{
]AT_GLR2_CC_IF([[
int yychr
= yytoken == YYTRANSLATE (]AT_TOKEN([YYEMPTY])[) ? -2
: yytoken == YYTRANSLATE (]AT_TOKEN([YYEOF])[) ? 0
: yytoken == YYTRANSLATE ('a') ? 'a'
: yytoken == YYTRANSLATE ('b') ? 'b'
: '?';
]])[
printf ("%s:\n yychar=", reduction);
if (yychr == ]AT_TOKEN([YYEMPTY])[)
printf ("YYEMPTY");
else if (yychr == ]AT_TOKEN([YYEOF])[)
printf ("YYEOF");
else
{
printf ("'%c', yylval='", yychr);
if (yylvalp->value > ' ')
printf ("%c", yylvalp->value);
printf ("', yylloc=(%d,%d),(%d,%d)",
yyllocp->]AT_FIRST_LINE[, yyllocp->]AT_FIRST_COLUMN[,
yyllocp->]AT_LAST_LINE[, yyllocp->]AT_LAST_COLUMN[);
}
printf ("\n");
}
]])
## ---------------------------- ## ## ---------------------------- ##
## Badly Collapsed GLR States. ## ## Badly Collapsed GLR States. ##
## ---------------------------- ## ## ---------------------------- ##
@@ -1266,12 +1323,8 @@ AT_DATA_GRAMMAR([glr-regr13.y],
#include <assert.h> #include <assert.h>
]AT_YYERROR_DECLARE[ ]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[ ]AT_YYLEX_DECLARE[
static void ]AT_PRINT_LOOKAHEAD_DECLARE[
print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp, #define USE(value)
char const *reduction);
#define PRINT_LOOKAHEAD(Msg) \
print_lookahead (yychar, &yylval, &yylloc, Msg)
#define USE(value)
} }
%define parse.assert %define parse.assert
@@ -1330,7 +1383,7 @@ nondefstate:
change_lookahead: change_lookahead:
%empty %empty
{ {
yychar = 'a'; ]AT_GLR2_CC_IF([[yytoken = YYTRANSLATE ('a')]], [[yychar = 'a']])[;
} }
; ;
@@ -1338,30 +1391,10 @@ change_lookahead:
]AT_YYERROR_DEFINE[ ]AT_YYERROR_DEFINE[
]AT_YYPARSE_DEFINE[ ]AT_YYPARSE_DEFINE[
]AT_PRINT_LOOKAHEAD_DEFINE[
]AT_YYLEX_DEFINE(["ab"], ]AT_YYLEX_DEFINE(["ab"],
[]AT_VAL[.value = YY_CAST (char, res + 'A' - 'a')])[ []AT_VAL[.value = YY_CAST (char, res + 'A' - 'a')])[
static void
print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
char const *reduction)
{
printf ("%s:\n yychar=", reduction);
if (yychr == ]AT_TOKEN([YYEMPTY])[)
printf ("YYEMPTY");
else if (yychr == ]AT_TOKEN([YYEOF])[)
printf ("YYEOF");
else
{
printf ("'%c', yylval='", yychr);
if (yylvalp->value > ' ')
printf ("%c", yylvalp->value);
printf ("', yylloc=(%d,%d),(%d,%d)",
yyllocp->]AT_FIRST_LINE[, yyllocp->]AT_FIRST_COLUMN[,
yyllocp->]AT_LAST_LINE[, yyllocp->]AT_LAST_COLUMN[);
}
printf ("\n");
}
int int
main (void) main (void)
{ {
@@ -1448,11 +1481,7 @@ AT_DATA_GRAMMAR([glr-regr14.y],
#include <assert.h> #include <assert.h>
]AT_YYERROR_DECLARE[ ]AT_YYERROR_DECLARE[
]AT_YYLEX_DECLARE[ ]AT_YYLEX_DECLARE[
static void ]AT_PRINT_LOOKAHEAD_DECLARE[
print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
char const *reduction);
#define PRINT_LOOKAHEAD(Msg) \
print_lookahead (yychar, &yylval, &yylloc, Msg)
static char merge (]AT_YYSTYPE[, ]AT_YYSTYPE[); static char merge (]AT_YYSTYPE[, ]AT_YYSTYPE[);
#define USE(value) #define USE(value)
} }
@@ -1534,8 +1563,10 @@ alt1:
'd' no_look 'd' no_look
{ {
USE ($][1); USE ($][1);
if (yychar != 'd' && yychar != ]AT_GLR2_CC_IF([yy::parser::token::])[YYEOF) if (]AT_GLR2_CC_IF(
fprintf (stderr, "Incorrect lookahead during stack explosion.\n"); [[yytoken != YYTRANSLATE('d') && yytoken != symbol_kind::S_YYEOF]],
[[yychar != 'd' && yychar != ]AT_GLR2_CC_IF([yy::parser::token::])[YYEOF]])[)
PRINT_LOOKAHEAD ("Incorrect lookahead during stack explosion.");
} }
; ;
@@ -1543,25 +1574,31 @@ alt2:
'd' no_look 'd' no_look
{ {
USE ($][1); USE ($][1);
if (yychar != 'd' && yychar != ]AT_GLR2_CC_IF([yy::parser::token::])[YYEOF) if (]AT_GLR2_CC_IF(
fprintf (stderr, "Incorrect lookahead during stack explosion.\n"); [[yytoken != YYTRANSLATE('d') && yytoken != symbol_kind::S_YYEOF]],
[[yychar != 'd' && yychar != ]AT_GLR2_CC_IF([yy::parser::token::])[YYEOF]])[)
PRINT_LOOKAHEAD ("Incorrect lookahead during stack explosion.");
} }
; ;
alt3: alt3:
'd' no_look { 'd' no_look
USE ($][1); {
if (yychar != 'd' && yychar != ]AT_GLR2_CC_IF([yy::parser::token::])[YYEOF) USE ($][1);
fprintf (stderr, "Incorrect lookahead during stack explosion.\n"); if (]AT_GLR2_CC_IF(
} [[yytoken != YYTRANSLATE('d') && yytoken != symbol_kind::S_YYEOF]],
[[yychar != 'd' && yychar != ]AT_GLR2_CC_IF([yy::parser::token::])[YYEOF]])[)
PRINT_LOOKAHEAD ("Incorrect lookahead during stack explosion.");
}
; ;
no_look: no_look:
%empty %empty
{ {
if (yychar != ]AT_GLR2_CC_IF([yy::parser::token::])[YYEMPTY) if (]AT_GLR2_CC_IF(
fprintf (stderr, [[yytoken != symbol_kind::S_YYEMPTY]],
"Found lookahead where shouldn't during stack explosion.\n"); [[yychar != ]AT_GLR2_CC_IF([yy::parser::token::])[YYEMPTY]])[)
PRINT_LOOKAHEAD ("Found lookahead where shouldn't during stack explosion.");
} }
; ;
@@ -1569,6 +1606,8 @@ no_look:
]AT_YYERROR_DEFINE[ ]AT_YYERROR_DEFINE[
]AT_YYPARSE_DEFINE[ ]AT_YYPARSE_DEFINE[
]AT_PRINT_LOOKAHEAD_DEFINE[
]AT_YYLEX_PROTOTYPE[ ]AT_YYLEX_PROTOTYPE[
{ {
]AT_USE_LEX_ARGS[ ]AT_USE_LEX_ARGS[
@@ -1587,28 +1626,6 @@ merge (]AT_YYSTYPE[ s1, ]AT_YYSTYPE[ s2)
return YY_CAST (char, s1.value + s2.value); return YY_CAST (char, s1.value + s2.value);
} }
/* FIXME: Factor duplicate. Possibly use yy_symbol_print. */
static void
print_lookahead (int yychr, ]AT_YYSTYPE[ *yylvalp, ]AT_YYLTYPE[ *yyllocp,
char const *reduction)
{
printf ("%s:\n yychar=", reduction);
if (yychr == ]AT_TOKEN([YYEMPTY])[)
printf ("YYEMPTY");
else if (yychr == ]AT_TOKEN([YYEOF])[)
printf ("YYEOF");
else
{
printf ("'%c', yylval='", yychr);
if (yylvalp->value > ' ')
printf ("%c", yylvalp->value);
printf ("', yylloc=(%d,%d),(%d,%d)",
yyllocp->]AT_FIRST_LINE[, yyllocp->]AT_FIRST_COLUMN[,
yyllocp->]AT_LAST_LINE[, yyllocp->]AT_LAST_COLUMN[);
}
printf ("\n");
}
int int
main (void) main (void)
{ {