mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-17 08:13:02 +00:00
* data/c.m4 (b4_identification, b4_user_args, b4_parse_param):
New. * data/yacc.m4 (b4_pure_args, b4_Pure_args): New. (b4_parse_param): Remove. Use b4_identification. Propagate b4_pure_args where needed to pass them to yyerror. * data/glr.m4 (b4_parse_param): Remove. (b4_user_formals, b4_pure_args, b4_pure_formals, b4_lpure_args) (b4_lpure_formals): New. Use b4_identification. (YY_USER_FORMALS, YY_USER_ARGS): Remove, replaced by b4_user_formals and b4_user_args. (yyexpandGLRStack, yyFail, yyaddDeferredAction, yyglrShiftDefer) (yyreportAmbiguity): When using a pure parser, also need the location, and the parse-params. Adjust callers. (yyuserAction, yyglrShift, yyreportParseError, yyrecoverParseError): When using a pure parser, also need the parse-params. Adjust callers. * tests/calc.at: Test pure (%pure-parser) and absolutely pure (%pure-parser + %parse-param) LALR and GLR parsers. (AT_CHECK_PUSHDEFS, AT_CHECK_POPDEFS): New, define AT_PARAM_IF, AT_LOCATION_IF, AT_PURE_IF, AT_GLR_IF, AAT_PURE_AND_LOC_IF, AT_GLR_OR_PARAM_IF, AT_YYERROR_ARG_LOC_IF, AT_YYERROR_SEES_LOC_IF. (_AT_DATA_CALC_Y): Equip for purity of yyerror. (_AT_CHECK_CALC_ERROR): Use AT_YYERROR_SEES_LOC_IF. * tests/cxx-type.at (_AT_TEST_GLR_CALC): Equip for yyerror purity. * doc/bison.texinfo: Untabify the whole file. (Parser Function): Document %parse-param, deprecate YYPARSE_PARAM. (Pure Calling): Document %lex-param, deprecate YYLEX_PARAM. (Error Reporting): Adjust to these new directives. Document %error-verbose, deprecate YYERROR_VERBOSE.
This commit is contained in:
35
ChangeLog
35
ChangeLog
@@ -1,3 +1,38 @@
|
|||||||
|
2002-11-03 Akim Demaille <akim@epita.fr>
|
||||||
|
|
||||||
|
* data/c.m4 (b4_identification, b4_user_args, b4_parse_param):
|
||||||
|
New.
|
||||||
|
* data/yacc.m4 (b4_pure_args, b4_Pure_args): New.
|
||||||
|
(b4_parse_param): Remove.
|
||||||
|
Use b4_identification.
|
||||||
|
Propagate b4_pure_args where needed to pass them to yyerror.
|
||||||
|
* data/glr.m4 (b4_parse_param): Remove.
|
||||||
|
(b4_user_formals, b4_pure_args, b4_pure_formals, b4_lpure_args)
|
||||||
|
(b4_lpure_formals): New.
|
||||||
|
Use b4_identification.
|
||||||
|
(YY_USER_FORMALS, YY_USER_ARGS): Remove, replaced by
|
||||||
|
b4_user_formals and b4_user_args.
|
||||||
|
(yyexpandGLRStack, yyFail, yyaddDeferredAction, yyglrShiftDefer)
|
||||||
|
(yyreportAmbiguity): When using a pure parser, also need
|
||||||
|
the location, and the parse-params.
|
||||||
|
Adjust callers.
|
||||||
|
(yyuserAction, yyglrShift, yyreportParseError, yyrecoverParseError):
|
||||||
|
When using a pure parser, also need the parse-params.
|
||||||
|
Adjust callers.
|
||||||
|
* tests/calc.at: Test pure (%pure-parser) and absolutely pure
|
||||||
|
(%pure-parser + %parse-param) LALR and GLR parsers.
|
||||||
|
(AT_CHECK_PUSHDEFS, AT_CHECK_POPDEFS): New, define AT_PARAM_IF,
|
||||||
|
AT_LOCATION_IF, AT_PURE_IF, AT_GLR_IF, AAT_PURE_AND_LOC_IF,
|
||||||
|
AT_GLR_OR_PARAM_IF, AT_YYERROR_ARG_LOC_IF, AT_YYERROR_SEES_LOC_IF.
|
||||||
|
(_AT_DATA_CALC_Y): Equip for purity of yyerror.
|
||||||
|
(_AT_CHECK_CALC_ERROR): Use AT_YYERROR_SEES_LOC_IF.
|
||||||
|
* tests/cxx-type.at (_AT_TEST_GLR_CALC): Equip for yyerror purity.
|
||||||
|
* doc/bison.texinfo: Untabify the whole file.
|
||||||
|
(Parser Function): Document %parse-param, deprecate YYPARSE_PARAM.
|
||||||
|
(Pure Calling): Document %lex-param, deprecate YYLEX_PARAM.
|
||||||
|
(Error Reporting): Adjust to these new directives.
|
||||||
|
Document %error-verbose, deprecate YYERROR_VERBOSE.
|
||||||
|
|
||||||
2002-11-03 Akim Demaille <akim@epita.fr>
|
2002-11-03 Akim Demaille <akim@epita.fr>
|
||||||
|
|
||||||
* tests/calc.at: Change all the AT_CHECK_CALC_LALR and
|
* tests/calc.at: Change all the AT_CHECK_CALC_LALR and
|
||||||
|
|||||||
8
NEWS
8
NEWS
@@ -8,6 +8,14 @@ Changes in version 1.75a, 2002-10-24:
|
|||||||
ago, but nobody noticed until we recently asked someone to try
|
ago, but nobody noticed until we recently asked someone to try
|
||||||
building Bison with a K&R C compiler.
|
building Bison with a K&R C compiler.
|
||||||
|
|
||||||
|
* %error-verbose
|
||||||
|
This new directive is preferred over YYERROR_VERBOSE.
|
||||||
|
|
||||||
|
* %lex-param, %parse-param
|
||||||
|
These new directives are preferred over PARSE_PARAM and LEX_PARAM.
|
||||||
|
In addition, they provide a means for yyerror to remain pure, and
|
||||||
|
to access to the current location.
|
||||||
|
|
||||||
Changes in version 1.75, 2002-10-14:
|
Changes in version 1.75, 2002-10-14:
|
||||||
|
|
||||||
* Bison should now work on 64-bit hosts.
|
* Bison should now work on 64-bit hosts.
|
||||||
|
|||||||
45
data/c.m4
45
data/c.m4
@@ -19,9 +19,9 @@ m4_divert(-1) -*- Autoconf -*-
|
|||||||
# 02111-1307 USA
|
# 02111-1307 USA
|
||||||
|
|
||||||
|
|
||||||
## ----------- ##
|
## ---------------- ##
|
||||||
## Copyright. ##
|
## Identification. ##
|
||||||
## ----------- ##
|
## ---------------- ##
|
||||||
|
|
||||||
# b4_copyright(TITLE, YEARS)
|
# b4_copyright(TITLE, YEARS)
|
||||||
# --------------------------
|
# --------------------------
|
||||||
@@ -47,6 +47,45 @@ m4_define([b4_copyright],
|
|||||||
Boston, MA 02111-1307, USA. */])
|
Boston, MA 02111-1307, USA. */])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_identification
|
||||||
|
# -----------------
|
||||||
|
m4_define([b4_identification],
|
||||||
|
[/* Identify Bison output. */
|
||||||
|
[#]define YYBISON 1
|
||||||
|
|
||||||
|
/* Skeleton name. */
|
||||||
|
[#]define YYSKELETON_NAME "b4_skeleton"
|
||||||
|
|
||||||
|
/* Pure parsers. */
|
||||||
|
[#]define YYPURE b4_pure
|
||||||
|
|
||||||
|
/* Using locations. */
|
||||||
|
[#]define YYLSP_NEEDED b4_locations_flag
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ------------------------ ##
|
||||||
|
## Pure/impure interfaces. ##
|
||||||
|
## ------------------------ ##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_user_args
|
||||||
|
# ------------
|
||||||
|
m4_define([b4_user_args],
|
||||||
|
[m4_ifset([b4_parse_param], [, b4_c_args(b4_parse_param)])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_parse_param
|
||||||
|
# --------------
|
||||||
|
# If defined, b4_parse_param arrives double quoted, but below we prefer
|
||||||
|
# it to be single quoted.
|
||||||
|
m4_define_default([b4_parse_param])
|
||||||
|
m4_define([b4_parse_param],
|
||||||
|
b4_parse_param))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## ------------ ##
|
## ------------ ##
|
||||||
## Data Types. ##
|
## Data Types. ##
|
||||||
## ------------ ##
|
## ------------ ##
|
||||||
|
|||||||
216
data/glr.c
216
data/glr.c
@@ -31,6 +31,15 @@ m4_define_default([b4_stack_depth_init], [200])
|
|||||||
# Location type.
|
# Location type.
|
||||||
m4_define_default([b4_location_type], [yyltype])
|
m4_define_default([b4_location_type], [yyltype])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## ------------------------ ##
|
||||||
|
## Pure/impure interfaces. ##
|
||||||
|
## ------------------------ ##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_lex_param
|
||||||
|
# ------------
|
||||||
# Accumule in b4_lex_param all the yylex arguments.
|
# Accumule in b4_lex_param all the yylex arguments.
|
||||||
# Yes, this is quite ugly...
|
# Yes, this is quite ugly...
|
||||||
m4_define([b4_lex_param],
|
m4_define([b4_lex_param],
|
||||||
@@ -38,12 +47,39 @@ m4_dquote(b4_pure_if([[[[YYSTYPE *]], [[yylvalp]]][]dnl
|
|||||||
b4_location_if([, [[YYLTYPE *], [yyllocp]]])])dnl
|
b4_location_if([, [[YYLTYPE *], [yyllocp]]])])dnl
|
||||||
m4_ifdef([b4_lex_param], [, ]b4_lex_param)))
|
m4_ifdef([b4_lex_param], [, ]b4_lex_param)))
|
||||||
|
|
||||||
# Yes, this is quite ugly...
|
|
||||||
m4_define_default([b4_parse_param])
|
|
||||||
m4_ifdef([b4_parse_param],
|
|
||||||
[m4_define([b4_parse_param],
|
|
||||||
b4_parse_param)])
|
|
||||||
|
|
||||||
|
# b4_user_formals
|
||||||
|
# ---------------
|
||||||
|
m4_define([b4_user_formals],
|
||||||
|
[m4_ifset([b4_parse_param], [, b4_c_ansi_formals(b4_parse_param)])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_pure_args
|
||||||
|
# ------------
|
||||||
|
# Arguments passed to yyerror: user args plus yylloc.
|
||||||
|
m4_define([b4_pure_args],
|
||||||
|
[b4_pure_if([b4_location_if([, yylocp])])[]b4_user_args])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_pure_formals
|
||||||
|
# ---------------
|
||||||
|
# Arguments passed to yyerror: user formals plus yyllocp.
|
||||||
|
m4_define([b4_pure_formals],
|
||||||
|
[b4_pure_if([b4_location_if([, YYLTYPE *yylocp])])[]b4_user_formals])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_lpure_args
|
||||||
|
# -------------
|
||||||
|
# Same as above, but on the lookahead, hence yyllocp instead of yylocp.
|
||||||
|
m4_define([b4_lpure_args],
|
||||||
|
[b4_pure_if([b4_location_if([, yyllocp])])[]b4_user_args])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_lpure_formals
|
||||||
|
# ----------------
|
||||||
|
# Same as above, but on the lookahead, hence yyllocp instead of yylocp.
|
||||||
|
m4_define([b4_lpure_formals],
|
||||||
|
[b4_pure_if([b4_location_if([YYLTYPE *yyllocp])])[]b4_user_formals])
|
||||||
|
|
||||||
|
|
||||||
## ----------------- ##
|
## ----------------- ##
|
||||||
@@ -119,24 +155,15 @@ b4_copyright([Skeleton parser for GLR parsing with Bison], [2002])
|
|||||||
[
|
[
|
||||||
/* This is the parser code for GLR (Generalized LR) parser. */
|
/* This is the parser code for GLR (Generalized LR) parser. */
|
||||||
|
|
||||||
/* FIXME: minimize these */
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <setjmp.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
/* Identify Bison output. */
|
]b4_identification
|
||||||
#define YYBISON 1
|
m4_if(b4_prefix[], [yy], [],
|
||||||
|
|
||||||
/* Pure parsers. */
|
|
||||||
#define YYPURE ]b4_pure[
|
|
||||||
|
|
||||||
/* Using locations. */
|
|
||||||
#define YYLSP_NEEDED ]b4_locations_flag[
|
|
||||||
|
|
||||||
]m4_if(b4_prefix[], [yy], [],
|
|
||||||
[/* If NAME_PREFIX is specified substitute the variables and functions
|
[/* If NAME_PREFIX is specified substitute the variables and functions
|
||||||
names. */
|
names. */
|
||||||
#define yyparse b4_prefix[]parse
|
#define yyparse b4_prefix[]parse
|
||||||
@@ -378,16 +405,9 @@ static const ]b4_int_type_for([b4_check])[ yycheck[] =
|
|||||||
|
|
||||||
|
|
||||||
/* Prevent warning if -Wmissing-prototypes. */
|
/* Prevent warning if -Wmissing-prototypes. */
|
||||||
]b4_c_ansi_function_decl([yyparse], [int], b4_parse_param)
|
]b4_c_ansi_function_decl([yyparse], [int], b4_parse_param)[
|
||||||
|
|
||||||
m4_ifset([b4_parse_param],
|
/* Error token number */
|
||||||
[#define YY_USER_FORMALS , b4_c_ansi_formals(b4_parse_param)
|
|
||||||
#define YY_USER_ARGS , b4_c_args(b4_parse_param)],
|
|
||||||
[#define YY_USER_FORMALS
|
|
||||||
#define YY_USER_ARGS])
|
|
||||||
|
|
||||||
|
|
||||||
[/* Error token number */
|
|
||||||
#define YYTERROR 1
|
#define YYTERROR 1
|
||||||
|
|
||||||
/* YYLLOC_DEFAULT -- Compute the default location (before the actions
|
/* YYLLOC_DEFAULT -- Compute the default location (before the actions
|
||||||
@@ -548,11 +568,11 @@ struct yyGLRStack {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void yyinitGLRStack (yyGLRStack* yystack, size_t yysize);
|
static void yyinitGLRStack (yyGLRStack* yystack, size_t yysize);
|
||||||
static void yyexpandGLRStack (yyGLRStack* yystack);
|
static void yyexpandGLRStack (yyGLRStack* yystack]b4_pure_formals[);
|
||||||
static void yyfreeGLRStack (yyGLRStack* yystack);
|
static void yyfreeGLRStack (yyGLRStack* yystack);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
yyFail (yyGLRStack* yystack, const char* yyformat, ...)
|
yyFail (yyGLRStack* yystack]b4_pure_formals[, const char* yyformat, ...)
|
||||||
{
|
{
|
||||||
if (yyformat != NULL)
|
if (yyformat != NULL)
|
||||||
{
|
{
|
||||||
@@ -561,7 +581,7 @@ yyFail (yyGLRStack* yystack, const char* yyformat, ...)
|
|||||||
va_start (yyap, yyformat);
|
va_start (yyap, yyformat);
|
||||||
yystack->yyerrflag = 1;
|
yystack->yyerrflag = 1;
|
||||||
vsprintf (yymsg, yyformat, yyap);
|
vsprintf (yymsg, yyformat, yyap);
|
||||||
yyerror (yymsg);
|
yyerror (yymsg]b4_pure_args[);
|
||||||
}
|
}
|
||||||
longjmp (yystack->yyexception_buffer, 1);
|
longjmp (yystack->yyexception_buffer, 1);
|
||||||
}
|
}
|
||||||
@@ -584,7 +604,7 @@ yytokenName (yySymbol yytoken)
|
|||||||
static YYRESULTTAG
|
static YYRESULTTAG
|
||||||
yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
|
yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
|
||||||
YYSTYPE* yyvalp, YYLTYPE* yylocp, yyGLRStack* yystack
|
YYSTYPE* yyvalp, YYLTYPE* yylocp, yyGLRStack* yystack
|
||||||
YY_USER_FORMALS)
|
]b4_user_formals[)
|
||||||
{
|
{
|
||||||
/* Avoid `unused' warnings in there are no $n. */
|
/* Avoid `unused' warnings in there are no $n. */
|
||||||
(void) yystack;
|
(void) yystack;
|
||||||
@@ -616,7 +636,7 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
|
|||||||
# undef YYBACKUP
|
# undef YYBACKUP
|
||||||
# define YYBACKUP(Token, Value) \
|
# define YYBACKUP(Token, Value) \
|
||||||
do { \
|
do { \
|
||||||
yyerror ("syntax error: cannot back up"); \
|
yyerror ("syntax error: cannot back up"]b4_pure_args[); \
|
||||||
YYERROR; \
|
YYERROR; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@@ -644,7 +664,7 @@ static YYSTYPE
|
|||||||
yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1)
|
yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1)
|
||||||
{
|
{
|
||||||
YYSTYPE yyval = *yy0;
|
YYSTYPE yyval = *yy0;
|
||||||
/* `Use' the arguments. */
|
/* `Use' the arguments. */
|
||||||
(void) yy0;
|
(void) yy0;
|
||||||
(void) yy1;
|
(void) yy1;
|
||||||
|
|
||||||
@@ -655,7 +675,7 @@ yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1)
|
|||||||
return yyval;
|
return yyval;
|
||||||
}
|
}
|
||||||
[
|
[
|
||||||
/* Bison grammar-table manipulation */
|
/* Bison grammar-table manipulation. */
|
||||||
|
|
||||||
/** Number of symbols composing the right hand side of rule #RULE. */
|
/** Number of symbols composing the right hand side of rule #RULE. */
|
||||||
static inline int
|
static inline int
|
||||||
@@ -751,7 +771,7 @@ yyhasResolvedValue (yyGLRState* yystate)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
yyaddDeferredAction (yyGLRStack* yystack, yyGLRState* yystate,
|
yyaddDeferredAction (yyGLRStack* yystack, yyGLRState* yystate,
|
||||||
yyGLRState* rhs, yyRuleNum yyrule)
|
yyGLRState* rhs, yyRuleNum yyrule]b4_pure_formals[)
|
||||||
{
|
{
|
||||||
yySemanticOption* yynewItem;
|
yySemanticOption* yynewItem;
|
||||||
yynewItem = &yystack->yynextFree->yyoption;
|
yynewItem = &yystack->yynextFree->yyoption;
|
||||||
@@ -763,7 +783,7 @@ yyaddDeferredAction (yyGLRStack* yystack, yyGLRState* yystate,
|
|||||||
yynewItem->yynext = yystate->yysemantics.yyfirstVal;
|
yynewItem->yynext = yystate->yysemantics.yyfirstVal;
|
||||||
yystate->yysemantics.yyfirstVal = yynewItem;
|
yystate->yysemantics.yyfirstVal = yynewItem;
|
||||||
if (yystack->yyspaceLeft < YYHEADROOM)
|
if (yystack->yyspaceLeft < YYHEADROOM)
|
||||||
yyexpandGLRStack (yystack);
|
yyexpandGLRStack (yystack]b4_pure_args[);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GLRStacks */
|
/* GLRStacks */
|
||||||
@@ -808,7 +828,7 @@ yyinitGLRStack (yyGLRStack* yystack, size_t yysize)
|
|||||||
allocation, so that we can avoid having external pointers exist
|
allocation, so that we can avoid having external pointers exist
|
||||||
across an allocation. */
|
across an allocation. */
|
||||||
static void
|
static void
|
||||||
yyexpandGLRStack (yyGLRStack* yystack)
|
yyexpandGLRStack (yyGLRStack* yystack]b4_pure_formals[)
|
||||||
{
|
{
|
||||||
#if YYSTACKEXPANDABLE
|
#if YYSTACKEXPANDABLE
|
||||||
yyGLRStack yynewStack;
|
yyGLRStack yynewStack;
|
||||||
@@ -817,7 +837,8 @@ yyexpandGLRStack (yyGLRStack* yystack)
|
|||||||
size_t yyn;
|
size_t yyn;
|
||||||
yysize = yystack->yynextFree - yystack->yyitems;
|
yysize = yystack->yynextFree - yystack->yyitems;
|
||||||
if (YYMAXDEPTH <= yysize)
|
if (YYMAXDEPTH <= yysize)
|
||||||
yyFail (yystack, "parsing stack overflow (%d items)", yysize);
|
yyFail (yystack][]b4_pure_args[,
|
||||||
|
"parsing stack overflow (%d items)", yysize);
|
||||||
yynewSize = 2*yysize;
|
yynewSize = 2*yysize;
|
||||||
if (YYMAXDEPTH < yynewSize)
|
if (YYMAXDEPTH < yynewSize)
|
||||||
yynewSize = YYMAXDEPTH;
|
yynewSize = YYMAXDEPTH;
|
||||||
@@ -864,8 +885,8 @@ yyexpandGLRStack (yyGLRStack* yystack)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
yyFail (yystack, "parsing stack overflow (%d items)", yysize);
|
yyFail (yystack][]b4_lpure_args[,
|
||||||
|
"parsing stack overflow (%d items)", yysize);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -937,7 +958,7 @@ yyremoveDeletes (yyGLRStack* yystack)
|
|||||||
* LRSTATE, at input position POSN, with (resolved) semantic value SVAL. */
|
* LRSTATE, at input position POSN, with (resolved) semantic value SVAL. */
|
||||||
static inline void
|
static inline void
|
||||||
yyglrShift (yyGLRStack* yystack, int yyk, yyStateNum yylrState, size_t yyposn,
|
yyglrShift (yyGLRStack* yystack, int yyk, yyStateNum yylrState, size_t yyposn,
|
||||||
YYSTYPE yysval, YYLTYPE* yylocp)
|
YYSTYPE yysval, YYLTYPE* yylocp]b4_user_formals[)
|
||||||
{
|
{
|
||||||
yyGLRStackItem* yynewItem;
|
yyGLRStackItem* yynewItem;
|
||||||
|
|
||||||
@@ -953,7 +974,7 @@ yyglrShift (yyGLRStack* yystack, int yyk, yyStateNum yylrState, size_t yyposn,
|
|||||||
yynewItem->yystate.yysemantics.yysval = yysval;
|
yynewItem->yystate.yysemantics.yysval = yysval;
|
||||||
yynewItem->yystate.yyloc = *yylocp;
|
yynewItem->yystate.yyloc = *yylocp;
|
||||||
if (yystack->yyspaceLeft < YYHEADROOM)
|
if (yystack->yyspaceLeft < YYHEADROOM)
|
||||||
yyexpandGLRStack (yystack);
|
yyexpandGLRStack (yystack]b4_pure_args[);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Shift to a new state on stack #K of STACK, to a new state
|
/** Shift to a new state on stack #K of STACK, to a new state
|
||||||
@@ -961,7 +982,7 @@ yyglrShift (yyGLRStack* yystack, int yyk, yyStateNum yylrState, size_t yyposn,
|
|||||||
* the (unresolved) semantic value of RHS under the action for RULE. */
|
* the (unresolved) semantic value of RHS under the action for RULE. */
|
||||||
static inline void
|
static inline void
|
||||||
yyglrShiftDefer (yyGLRStack* yystack, int yyk, yyStateNum yylrState,
|
yyglrShiftDefer (yyGLRStack* yystack, int yyk, yyStateNum yylrState,
|
||||||
size_t yyposn, yyGLRState* rhs, yyRuleNum yyrule)
|
size_t yyposn, yyGLRState* rhs, yyRuleNum yyrule]b4_pure_formals[)
|
||||||
{
|
{
|
||||||
yyGLRStackItem* yynewItem;
|
yyGLRStackItem* yynewItem;
|
||||||
|
|
||||||
@@ -975,7 +996,7 @@ yyglrShiftDefer (yyGLRStack* yystack, int yyk, yyStateNum yylrState,
|
|||||||
yystack->yytops.yystates[yyk] = &yynewItem->yystate;
|
yystack->yytops.yystates[yyk] = &yynewItem->yystate;
|
||||||
yystack->yynextFree += 1;
|
yystack->yynextFree += 1;
|
||||||
yystack->yyspaceLeft -= 1;
|
yystack->yyspaceLeft -= 1;
|
||||||
yyaddDeferredAction (yystack, &yynewItem->yystate, rhs, yyrule);
|
yyaddDeferredAction (yystack, &yynewItem->yystate, rhs, yyrule]b4_pure_args[);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Pop the symbols consumed by reduction #RULE from the top of stack
|
/** Pop the symbols consumed by reduction #RULE from the top of stack
|
||||||
@@ -986,7 +1007,7 @@ yyglrShiftDefer (yyGLRStack* yystack, int yyk, yyStateNum yylrState,
|
|||||||
* for userAction. */
|
* for userAction. */
|
||||||
static inline int
|
static inline int
|
||||||
yydoAction (yyGLRStack* yystack, int yyk, yyRuleNum yyrule,
|
yydoAction (yyGLRStack* yystack, int yyk, yyRuleNum yyrule,
|
||||||
YYSTYPE* yyvalp, YYLTYPE* yylocp YY_USER_FORMALS)
|
YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
|
||||||
{
|
{
|
||||||
int yynrhs = yyrhsLength (yyrule);
|
int yynrhs = yyrhsLength (yyrule);
|
||||||
|
|
||||||
@@ -1009,7 +1030,7 @@ yydoAction (yyGLRStack* yystack, int yyk, yyRuleNum yyrule,
|
|||||||
*yylocp = rhs[1-yynrhs].yystate.yyloc;
|
*yylocp = rhs[1-yynrhs].yystate.yyloc;
|
||||||
}
|
}
|
||||||
return yyuserAction (yyrule, yynrhs, rhs,
|
return yyuserAction (yyrule, yynrhs, rhs,
|
||||||
yyvalp, yylocp, yystack YY_USER_ARGS);
|
yyvalp, yylocp, yystack]b4_user_args[);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1037,7 +1058,7 @@ yydoAction (yyGLRStack* yystack, int yyk, yyRuleNum yyrule,
|
|||||||
*yylocp = yyrhsVals[0].yystate.yyloc;
|
*yylocp = yyrhsVals[0].yystate.yyloc;
|
||||||
}
|
}
|
||||||
return yyuserAction (yyrule, yynrhs, yyrhsVals + (yynrhs-1),
|
return yyuserAction (yyrule, yynrhs, yyrhsVals + (yynrhs-1),
|
||||||
yyvalp, yylocp, yystack YY_USER_ARGS);
|
yyvalp, yylocp, yystack]b4_user_args[);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1080,7 +1101,7 @@ yy_reduce_print (size_t yyk, yyRuleNum yyrule)
|
|||||||
*/
|
*/
|
||||||
static inline YYRESULTTAG
|
static inline YYRESULTTAG
|
||||||
yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
|
yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
|
||||||
bool yyforceEval YY_USER_FORMALS)
|
bool yyforceEval]b4_pure_formals[)
|
||||||
{
|
{
|
||||||
size_t yyposn = yystack->yytops.yystates[yyk]->yyposn;
|
size_t yyposn = yystack->yytops.yystates[yyk]->yyposn;
|
||||||
|
|
||||||
@@ -1090,11 +1111,11 @@ yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
|
|||||||
YYLTYPE yyloc;
|
YYLTYPE yyloc;
|
||||||
|
|
||||||
YY_REDUCE_PRINT (yyk, yyrule);
|
YY_REDUCE_PRINT (yyk, yyrule);
|
||||||
YYCHK (yydoAction (yystack, yyk, yyrule, &yysval, &yyloc YY_USER_ARGS));
|
YYCHK (yydoAction (yystack, yyk, yyrule, &yysval, &yyloc]b4_user_args[));
|
||||||
yyglrShift (yystack, yyk,
|
yyglrShift (yystack, yyk,
|
||||||
yyLRgotoState (yystack->yytops.yystates[yyk]->yylrState,
|
yyLRgotoState (yystack->yytops.yystates[yyk]->yylrState,
|
||||||
yylhsNonterm (yyrule)),
|
yylhsNonterm (yyrule)),
|
||||||
yyposn, yysval, &yyloc);
|
yyposn, yysval, &yyloc]b4_user_args[);
|
||||||
YYDPRINTF ((stderr, "Stack %d entering state %d\n",
|
YYDPRINTF ((stderr, "Stack %d entering state %d\n",
|
||||||
yyk, yystack->yytops.yystates[yyk]->yylrState));
|
yyk, yystack->yytops.yystates[yyk]->yylrState));
|
||||||
}
|
}
|
||||||
@@ -1126,7 +1147,7 @@ yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
|
|||||||
{
|
{
|
||||||
if (yyp->yylrState == yynewLRState && yyp->yypred == yys)
|
if (yyp->yylrState == yynewLRState && yyp->yypred == yys)
|
||||||
{
|
{
|
||||||
yyaddDeferredAction (yystack, yyp, yys0, yyrule);
|
yyaddDeferredAction (yystack, yyp, yys0, yyrule]b4_pure_args[);
|
||||||
yymarkStackDeleted (yystack, yyk);
|
yymarkStackDeleted (yystack, yyk);
|
||||||
YYDPRINTF ((stderr, "Merging stack %d into stack %d.\n",
|
YYDPRINTF ((stderr, "Merging stack %d into stack %d.\n",
|
||||||
yyk, yyi));
|
yyk, yyi));
|
||||||
@@ -1136,7 +1157,7 @@ yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
yystack->yytops.yystates[yyk] = yys;
|
yystack->yytops.yystates[yyk] = yys;
|
||||||
yyglrShiftDefer (yystack, yyk, yynewLRState, yyposn, yys0, yyrule);
|
yyglrShiftDefer (yystack, yyk, yynewLRState, yyposn, yys0, yyrule]b4_pure_args[);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1236,23 +1257,23 @@ yypreference (yySemanticOption* y0, yySemanticOption* y1)
|
|||||||
|
|
||||||
static YYRESULTTAG yyresolveValue (yySemanticOption* yyoptionList,
|
static YYRESULTTAG yyresolveValue (yySemanticOption* yyoptionList,
|
||||||
yyGLRStack* yystack, YYSTYPE* yyvalp,
|
yyGLRStack* yystack, YYSTYPE* yyvalp,
|
||||||
YYLTYPE* yylocp YY_USER_FORMALS);
|
YYLTYPE* yylocp]b4_user_formals[);
|
||||||
|
|
||||||
static YYRESULTTAG
|
static YYRESULTTAG
|
||||||
yyresolveStates (yyGLRState* yys, int yyn, yyGLRStack* yystack YY_USER_FORMALS)
|
yyresolveStates (yyGLRState* yys, int yyn, yyGLRStack* yystack]b4_user_formals[)
|
||||||
{
|
{
|
||||||
YYRESULTTAG yyflag;
|
YYRESULTTAG yyflag;
|
||||||
if (0 < yyn)
|
if (0 < yyn)
|
||||||
{
|
{
|
||||||
assert (yys->yypred != NULL);
|
assert (yys->yypred != NULL);
|
||||||
yyflag = yyresolveStates (yys->yypred, yyn-1, yystack YY_USER_ARGS);
|
yyflag = yyresolveStates (yys->yypred, yyn-1, yystack]b4_user_args[);
|
||||||
if (yyflag != yyok)
|
if (yyflag != yyok)
|
||||||
return yyflag;
|
return yyflag;
|
||||||
if (! yys->yyresolved)
|
if (! yys->yyresolved)
|
||||||
{
|
{
|
||||||
yyflag = yyresolveValue (yys->yysemantics.yyfirstVal, yystack,
|
yyflag = yyresolveValue (yys->yysemantics.yyfirstVal, yystack,
|
||||||
&yys->yysemantics.yysval, &yys->yyloc
|
&yys->yysemantics.yysval, &yys->yyloc
|
||||||
YY_USER_ARGS);
|
]b4_user_args[);
|
||||||
if (yyflag != yyok)
|
if (yyflag != yyok)
|
||||||
return yyflag;
|
return yyflag;
|
||||||
yys->yyresolved = yytrue;
|
yys->yyresolved = yytrue;
|
||||||
@@ -1263,14 +1284,14 @@ yyresolveStates (yyGLRState* yys, int yyn, yyGLRStack* yystack YY_USER_FORMALS)
|
|||||||
|
|
||||||
static YYRESULTTAG
|
static YYRESULTTAG
|
||||||
yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack,
|
yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack,
|
||||||
YYSTYPE* yyvalp, YYLTYPE* yylocp YY_USER_FORMALS)
|
YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
|
||||||
{
|
{
|
||||||
yyGLRStackItem yyrhsVals[YYMAXRHS];
|
yyGLRStackItem yyrhsVals[YYMAXRHS];
|
||||||
int yynrhs, yyi;
|
int yynrhs, yyi;
|
||||||
yyGLRState* yys;
|
yyGLRState* yys;
|
||||||
|
|
||||||
yynrhs = yyrhsLength (yyopt->yyrule);
|
yynrhs = yyrhsLength (yyopt->yyrule);
|
||||||
YYCHK (yyresolveStates (yyopt->yystate, yynrhs, yystack YY_USER_ARGS));
|
YYCHK (yyresolveStates (yyopt->yystate, yynrhs, yystack]b4_user_args[));
|
||||||
for (yyi = yynrhs-1, yys = yyopt->yystate; 0 <= yyi;
|
for (yyi = yynrhs-1, yys = yyopt->yystate; 0 <= yyi;
|
||||||
yyi -= 1, yys = yys->yypred)
|
yyi -= 1, yys = yys->yypred)
|
||||||
{
|
{
|
||||||
@@ -1280,7 +1301,7 @@ yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack,
|
|||||||
yyrhsVals[yyi].yystate.yyloc = yys->yyloc;
|
yyrhsVals[yyi].yystate.yyloc = yys->yyloc;
|
||||||
}
|
}
|
||||||
return yyuserAction (yyopt->yyrule, yynrhs, yyrhsVals + (yynrhs-1),
|
return yyuserAction (yyopt->yyrule, yynrhs, yyrhsVals + (yynrhs-1),
|
||||||
yyvalp, yylocp, yystack YY_USER_ARGS);
|
yyvalp, yylocp, yystack]b4_user_args[);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if YYDEBUG
|
#if YYDEBUG
|
||||||
@@ -1331,7 +1352,7 @@ yyreportTree (yySemanticOption* yyx, int yyindent)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1,
|
yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1,
|
||||||
yyGLRStack* yystack)
|
yyGLRStack* yystack]b4_pure_formals[)
|
||||||
{
|
{
|
||||||
/* `Unused' warnings. */
|
/* `Unused' warnings. */
|
||||||
(void) yyx0;
|
(void) yyx0;
|
||||||
@@ -1345,7 +1366,7 @@ yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1,
|
|||||||
yyreportTree (yyx1, 2);
|
yyreportTree (yyx1, 2);
|
||||||
YYFPRINTF (stderr, "\n");
|
YYFPRINTF (stderr, "\n");
|
||||||
#endif
|
#endif
|
||||||
yyFail (yystack, "ambiguity detected");
|
yyFail (yystack][]b4_pure_args[, "ambiguity detected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1353,7 +1374,7 @@ yyreportAmbiguity (yySemanticOption* yyx0, yySemanticOption* yyx1,
|
|||||||
* actions, and return the result. */
|
* actions, and return the result. */
|
||||||
static YYRESULTTAG
|
static YYRESULTTAG
|
||||||
yyresolveValue (yySemanticOption* yyoptionList, yyGLRStack* yystack,
|
yyresolveValue (yySemanticOption* yyoptionList, yyGLRStack* yystack,
|
||||||
YYSTYPE* yyvalp, YYLTYPE* yylocp YY_USER_FORMALS)
|
YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
|
||||||
{
|
{
|
||||||
yySemanticOption* yybest;
|
yySemanticOption* yybest;
|
||||||
yySemanticOption* yyp;
|
yySemanticOption* yyp;
|
||||||
@@ -1369,7 +1390,7 @@ yyresolveValue (yySemanticOption* yyoptionList, yyGLRStack* yystack,
|
|||||||
switch (yypreference (yybest, yyp))
|
switch (yypreference (yybest, yyp))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
yyreportAmbiguity (yybest, yyp, yystack);
|
yyreportAmbiguity (yybest, yyp, yystack]b4_pure_args[);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
yymerge = 1;
|
yymerge = 1;
|
||||||
@@ -1386,25 +1407,25 @@ yyresolveValue (yySemanticOption* yyoptionList, yyGLRStack* yystack,
|
|||||||
if (yymerge)
|
if (yymerge)
|
||||||
{
|
{
|
||||||
int yyprec = yydprec[yybest->yyrule];
|
int yyprec = yydprec[yybest->yyrule];
|
||||||
YYCHK (yyresolveAction (yybest, yystack, yyvalp, yylocp YY_USER_ARGS));
|
YYCHK (yyresolveAction (yybest, yystack, yyvalp, yylocp]b4_user_args[));
|
||||||
for (yyp = yybest->yynext; yyp != NULL; yyp = yyp->yynext)
|
for (yyp = yybest->yynext; yyp != NULL; yyp = yyp->yynext)
|
||||||
{
|
{
|
||||||
if (yyprec == yydprec[yyp->yyrule])
|
if (yyprec == yydprec[yyp->yyrule])
|
||||||
{
|
{
|
||||||
YYSTYPE yyval1;
|
YYSTYPE yyval1;
|
||||||
YYLTYPE yydummy;
|
YYLTYPE yydummy;
|
||||||
YYCHK (yyresolveAction (yyp, yystack, &yyval1, &yydummy YY_USER_ARGS));
|
YYCHK (yyresolveAction (yyp, yystack, &yyval1, &yydummy]b4_user_args[));
|
||||||
*yyvalp = yyuserMerge (yymerger[yyp->yyrule], yyvalp, &yyval1);
|
*yyvalp = yyuserMerge (yymerger[yyp->yyrule], yyvalp, &yyval1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return yyok;
|
return yyok;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return yyresolveAction (yybest, yystack, yyvalp, yylocp YY_USER_ARGS);
|
return yyresolveAction (yybest, yystack, yyvalp, yylocp]b4_user_args[);
|
||||||
}
|
}
|
||||||
|
|
||||||
static YYRESULTTAG
|
static YYRESULTTAG
|
||||||
yyresolveStack (yyGLRStack* yystack YY_USER_FORMALS)
|
yyresolveStack (yyGLRStack* yystack]b4_user_formals[)
|
||||||
{
|
{
|
||||||
if (yystack->yysplitPoint != NULL)
|
if (yystack->yysplitPoint != NULL)
|
||||||
{
|
{
|
||||||
@@ -1416,7 +1437,7 @@ yyresolveStack (yyGLRStack* yystack YY_USER_FORMALS)
|
|||||||
yys = yys->yypred, yyn += 1)
|
yys = yys->yypred, yyn += 1)
|
||||||
;
|
;
|
||||||
YYCHK (yyresolveStates (yystack->yytops.yystates[0], yyn, yystack
|
YYCHK (yyresolveStates (yystack->yytops.yystates[0], yyn, yystack
|
||||||
YY_USER_ARGS));
|
]b4_user_args[));
|
||||||
}
|
}
|
||||||
return yyok;
|
return yyok;
|
||||||
}
|
}
|
||||||
@@ -1454,7 +1475,7 @@ yycompressStack (yyGLRStack* yystack)
|
|||||||
static YYRESULTTAG
|
static YYRESULTTAG
|
||||||
yyprocessOneStack (yyGLRStack* yystack, int yyk,
|
yyprocessOneStack (yyGLRStack* yystack, int yyk,
|
||||||
size_t yyposn, YYSTYPE* yylvalp, YYLTYPE* yyllocp
|
size_t yyposn, YYSTYPE* yylvalp, YYLTYPE* yyllocp
|
||||||
YY_USER_FORMALS)
|
]b4_user_formals[)
|
||||||
{
|
{
|
||||||
int yyaction;
|
int yyaction;
|
||||||
const short* yyconflicts;
|
const short* yyconflicts;
|
||||||
@@ -1475,7 +1496,7 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk,
|
|||||||
yymarkStackDeleted (yystack, yyk);
|
yymarkStackDeleted (yystack, yyk);
|
||||||
return yyok;
|
return yyok;
|
||||||
}
|
}
|
||||||
YYCHK (yyglrReduce (yystack, yyk, yyrule, yyfalse YY_USER_ARGS));
|
YYCHK (yyglrReduce (yystack, yyk, yyrule, yyfalse]b4_lpure_args[));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1495,9 +1516,9 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk,
|
|||||||
YYDPRINTF ((stderr, "Splitting off stack %d from %d.\n",
|
YYDPRINTF ((stderr, "Splitting off stack %d from %d.\n",
|
||||||
yynewStack, yyk));
|
yynewStack, yyk));
|
||||||
YYCHK (yyglrReduce (yystack, yynewStack,
|
YYCHK (yyglrReduce (yystack, yynewStack,
|
||||||
*yyconflicts, yyfalse YY_USER_ARGS));
|
*yyconflicts, yyfalse]b4_lpure_args[));
|
||||||
YYCHK (yyprocessOneStack (yystack, yynewStack, yyposn,
|
YYCHK (yyprocessOneStack (yystack, yynewStack, yyposn,
|
||||||
yylvalp, yyllocp YY_USER_ARGS));
|
yylvalp, yyllocp]b4_user_args[));
|
||||||
yyconflicts += 1;
|
yyconflicts += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1505,7 +1526,8 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk,
|
|||||||
{
|
{
|
||||||
YYDPRINTF ((stderr, "Shifting token %s on stack %d, ",
|
YYDPRINTF ((stderr, "Shifting token %s on stack %d, ",
|
||||||
yytokenName (*yytokenp), yyk));
|
yytokenName (*yytokenp), yyk));
|
||||||
yyglrShift (yystack, yyk, yyaction, yyposn+1, *yylvalp, yyllocp);
|
yyglrShift (yystack, yyk, yyaction, yyposn+1,
|
||||||
|
*yylvalp, yyllocp]b4_user_args[);
|
||||||
YYDPRINTF ((stderr, "which is now in state #%d\n",
|
YYDPRINTF ((stderr, "which is now in state #%d\n",
|
||||||
yystack->yytops.yystates[yyk]->yylrState));
|
yystack->yytops.yystates[yyk]->yylrState));
|
||||||
break;
|
break;
|
||||||
@@ -1517,14 +1539,15 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
YYCHK (yyglrReduce (yystack, yyk, -yyaction, yyfalse YY_USER_ARGS));
|
YYCHK (yyglrReduce (yystack, yyk, -yyaction, yyfalse]b4_lpure_args[));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return yyok;
|
return yyok;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
yyreportParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
yyreportParseError (yyGLRStack* yystack,
|
||||||
|
YYSTYPE* yylvalp, YYLTYPE* yyllocp]b4_user_formals[)
|
||||||
{
|
{
|
||||||
/* `Unused' warnings. */
|
/* `Unused' warnings. */
|
||||||
(void) yylvalp;
|
(void) yylvalp;
|
||||||
@@ -1568,12 +1591,12 @@ yyreportParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
yyprefix = " or ";
|
yyprefix = " or ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
yyerror (yymsg);
|
yyerror (yymsg]b4_lpure_args[);
|
||||||
free (yymsg);
|
free (yymsg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
yyerror ("parse error");
|
yyerror ("parse error"]b4_lpure_args[);
|
||||||
yynerrs += 1;
|
yynerrs += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1582,7 +1605,8 @@ yyreportParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
YYLVALP, and YYLLOCP point to the syntactic category, semantic
|
YYLVALP, and YYLLOCP point to the syntactic category, semantic
|
||||||
value, and location of the lookahead. */
|
value, and location of the lookahead. */
|
||||||
static void
|
static void
|
||||||
yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
yyrecoverParseError (yyGLRStack* yystack,
|
||||||
|
YYSTYPE* yylvalp, YYLTYPE* yyllocp]b4_user_formals[)
|
||||||
{
|
{
|
||||||
yySymbol* const yytokenp = yystack->yytokenp;
|
yySymbol* const yytokenp = yystack->yytokenp;
|
||||||
size_t yyk;
|
size_t yyk;
|
||||||
@@ -1596,7 +1620,7 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
while (yytrue)
|
while (yytrue)
|
||||||
{
|
{
|
||||||
if (*yytokenp == YYEOF)
|
if (*yytokenp == YYEOF)
|
||||||
yyFail (yystack, NULL);
|
yyFail (yystack][]b4_lpure_args[, NULL);
|
||||||
if (*yytokenp != YYEMPTY)
|
if (*yytokenp != YYEMPTY)
|
||||||
YYDPRINTF ((stderr, "Discarding token %s\n",
|
YYDPRINTF ((stderr, "Discarding token %s\n",
|
||||||
yytokenName (*yytokenp)));
|
yytokenName (*yytokenp)));
|
||||||
@@ -1607,7 +1631,7 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
yyj = yypact[yystack->yytops.yystates[0]->yylrState];
|
yyj = yypact[yystack->yytops.yystates[0]->yylrState];
|
||||||
if (yyj == YYPACT_NINF)
|
if (yyj == YYPACT_NINF)
|
||||||
/* Something's not right; we shouldn't be here. */
|
/* Something's not right; we shouldn't be here. */
|
||||||
yyFail (yystack, NULL);
|
yyFail (yystack][]b4_lpure_args[, NULL);
|
||||||
yyj += *yytokenp;
|
yyj += *yytokenp;
|
||||||
if (yyj < 0 || YYLAST < yyj || yycheck[yyj] != *yytokenp)
|
if (yyj < 0 || YYLAST < yyj || yycheck[yyj] != *yytokenp)
|
||||||
{
|
{
|
||||||
@@ -1623,7 +1647,7 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
if (yystack->yytops.yystates[yyk] != NULL)
|
if (yystack->yytops.yystates[yyk] != NULL)
|
||||||
break;
|
break;
|
||||||
if (yyk >= yystack->yytops.yysize)
|
if (yyk >= yystack->yytops.yysize)
|
||||||
yyFail (yystack, NULL);
|
yyFail (yystack][]b4_lpure_args[, NULL);
|
||||||
for (yyk += 1; yyk < yystack->yytops.yysize; yyk += 1)
|
for (yyk += 1; yyk < yystack->yytops.yysize; yyk += 1)
|
||||||
yymarkStackDeleted (yystack, yyk);
|
yymarkStackDeleted (yystack, yyk);
|
||||||
yyremoveDeletes (yystack);
|
yyremoveDeletes (yystack);
|
||||||
@@ -1637,7 +1661,8 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
yycheck[yyj] == YYTERROR && yyisShiftAction (yytable[yyj]))
|
yycheck[yyj] == YYTERROR && yyisShiftAction (yytable[yyj]))
|
||||||
{
|
{
|
||||||
yyglrShift (yystack, 0, yytable[yyj],
|
yyglrShift (yystack, 0, yytable[yyj],
|
||||||
yystack->yytops.yystates[0]->yyposn, *yylvalp, yyllocp);
|
yystack->yytops.yystates[0]->yyposn,
|
||||||
|
*yylvalp, yyllocp]b4_user_args[);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
yystack->yytops.yystates[0] = yystack->yytops.yystates[0]->yypred;
|
yystack->yytops.yystates[0] = yystack->yytops.yystates[0]->yypred;
|
||||||
@@ -1645,7 +1670,7 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
yystack->yyspaceLeft += 1;
|
yystack->yyspaceLeft += 1;
|
||||||
}
|
}
|
||||||
if (yystack->yytops.yystates[0] == NULL)
|
if (yystack->yytops.yystates[0] == NULL)
|
||||||
yyFail (yystack, NULL);
|
yyFail (yystack][]b4_lpure_args[, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define YYCHK1(YYE) \
|
#define YYCHK1(YYE) \
|
||||||
@@ -1693,7 +1718,7 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
if (setjmp (yystack.yyexception_buffer) != 0)
|
if (setjmp (yystack.yyexception_buffer) != 0)
|
||||||
goto yyDone;
|
goto yyDone;
|
||||||
|
|
||||||
yyglrShift (&yystack, 0, 0, 0, yyval_default, &yyloc_default);
|
yyglrShift (&yystack, 0, 0, 0, yyval_default, &yyloc_default]b4_user_args[);
|
||||||
yytoken = YYEMPTY;
|
yytoken = YYEMPTY;
|
||||||
yyposn = 0;
|
yyposn = 0;
|
||||||
|
|
||||||
@@ -1718,10 +1743,10 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
yyrule = yydefaultAction (yystate);
|
yyrule = yydefaultAction (yystate);
|
||||||
if (yyrule == 0)
|
if (yyrule == 0)
|
||||||
{
|
{
|
||||||
yyreportParseError (&yystack, yylvalp, yyllocp);
|
yyreportParseError (&yystack, yylvalp, yyllocp]b4_user_args[);
|
||||||
goto yyuser_error;
|
goto yyuser_error;
|
||||||
}
|
}
|
||||||
YYCHK1 (yyglrReduce (&yystack, 0, yyrule, yytrue YY_USER_ARGS));
|
YYCHK1 (yyglrReduce (&yystack, 0, yyrule, yytrue]b4_lpure_args[));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1743,7 +1768,8 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
if (yytoken != YYEOF)
|
if (yytoken != YYEOF)
|
||||||
yytoken = YYEMPTY;
|
yytoken = YYEMPTY;
|
||||||
yyposn += 1;
|
yyposn += 1;
|
||||||
yyglrShift (&yystack, 0, yyaction, yyposn, yylval, yyllocp);
|
yyglrShift (&yystack, 0, yyaction, yyposn,
|
||||||
|
yylval, yyllocp]b4_user_args[);
|
||||||
if (0 < yystack.yyerrState)
|
if (0 < yystack.yyerrState)
|
||||||
yystack.yyerrState -= 1;
|
yystack.yyerrState -= 1;
|
||||||
YYDPRINTF ((stderr, "Entering state %d\n",
|
YYDPRINTF ((stderr, "Entering state %d\n",
|
||||||
@@ -1751,11 +1777,11 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
}
|
}
|
||||||
else if (yyisErrorAction (yyaction))
|
else if (yyisErrorAction (yyaction))
|
||||||
{
|
{
|
||||||
yyreportParseError (&yystack, yylvalp, yyllocp);
|
yyreportParseError (&yystack, yylvalp, yyllocp]b4_user_args[);
|
||||||
goto yyuser_error;
|
goto yyuser_error;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
YYCHK1 (yyglrReduce (&yystack, 0, -yyaction, yytrue YY_USER_ARGS));
|
YYCHK1 (yyglrReduce (&yystack, 0, -yyaction, yytrue]b4_lpure_args[));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1765,7 +1791,7 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
int yyn = yystack.yytops.yysize;
|
int yyn = yystack.yytops.yysize;
|
||||||
for (yys = 0; yys < yyn; yys += 1)
|
for (yys = 0; yys < yyn; yys += 1)
|
||||||
YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn,
|
YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn,
|
||||||
yylvalp, yyllocp YY_USER_ARGS));
|
yylvalp, yyllocp]b4_user_args[));
|
||||||
yytoken = YYEMPTY;
|
yytoken = YYEMPTY;
|
||||||
yyposn += 1;
|
yyposn += 1;
|
||||||
yyremoveDeletes (&yystack);
|
yyremoveDeletes (&yystack);
|
||||||
@@ -1773,15 +1799,15 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
{
|
{
|
||||||
yyundeleteLastStack (&yystack);
|
yyundeleteLastStack (&yystack);
|
||||||
if (yystack.yytops.yysize == 0)
|
if (yystack.yytops.yysize == 0)
|
||||||
yyFail (&yystack, "parse error");
|
yyFail (&yystack][]b4_lpure_args[, "parse error");
|
||||||
YYCHK1 (yyresolveStack (&yystack YY_USER_ARGS));
|
YYCHK1 (yyresolveStack (&yystack]b4_user_args[));
|
||||||
YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
|
YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
|
||||||
yyreportParseError (&yystack, yylvalp, yyllocp);
|
yyreportParseError (&yystack, yylvalp, yyllocp]b4_user_args[);
|
||||||
goto yyuser_error;
|
goto yyuser_error;
|
||||||
}
|
}
|
||||||
else if (yystack.yytops.yysize == 1)
|
else if (yystack.yytops.yysize == 1)
|
||||||
{
|
{
|
||||||
YYCHK1 (yyresolveStack (&yystack YY_USER_ARGS));
|
YYCHK1 (yyresolveStack (&yystack]b4_user_args[));
|
||||||
YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
|
YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
|
||||||
yycompressStack (&yystack);
|
yycompressStack (&yystack);
|
||||||
break;
|
break;
|
||||||
@@ -1789,7 +1815,7 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
yyuser_error:
|
yyuser_error:
|
||||||
yyrecoverParseError (&yystack, yylvalp, yyllocp);
|
yyrecoverParseError (&yystack, yylvalp, yyllocp]b4_user_args[);
|
||||||
yyposn = yystack.yytops.yystates[0]->yyposn;
|
yyposn = yystack.yytops.yystates[0]->yyposn;
|
||||||
}
|
}
|
||||||
yyDone:
|
yyDone:
|
||||||
|
|||||||
54
data/yacc.c
54
data/yacc.c
@@ -33,19 +33,37 @@ m4_define_default([b4_stack_depth_init], [200])
|
|||||||
# Location type.
|
# Location type.
|
||||||
m4_define_default([b4_location_type], [yyltype])
|
m4_define_default([b4_location_type], [yyltype])
|
||||||
|
|
||||||
|
|
||||||
|
## ------------------------ ##
|
||||||
|
## Pure/impure interfaces. ##
|
||||||
|
## ------------------------ ##
|
||||||
|
|
||||||
|
|
||||||
|
# b4_Pure_if(IF-TRUE, IF-FALSE)
|
||||||
|
# -----------------------------
|
||||||
|
# Expand IF-TRUE, if %pure-parser and %parse-param, IF-FALSE otherwise.
|
||||||
|
m4_define([b4_Pure_if],
|
||||||
|
[b4_pure_if([m4_ifset([b4_parse_param],
|
||||||
|
[$1], [$2])],
|
||||||
|
[$2])])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_pure_args
|
||||||
|
# ------------
|
||||||
|
# Arguments passed to yyerror: user args plus yylloc.
|
||||||
|
m4_define([b4_pure_args],
|
||||||
|
[b4_Pure_if([b4_location_if([, &yylloc])])[]b4_user_args])
|
||||||
|
|
||||||
|
|
||||||
|
# b4_lex_param
|
||||||
|
# ------------
|
||||||
# Accumule in b4_lex_param all the yylex arguments.
|
# Accumule in b4_lex_param all the yylex arguments.
|
||||||
# Yes, this is quite ugly...
|
# b4_lex_param arrives quoted twice, but we want to keep only one level.
|
||||||
m4_define([b4_lex_param],
|
m4_define([b4_lex_param],
|
||||||
m4_dquote(b4_pure_if([[[[YYSTYPE *]], [[&yylval]]][]dnl
|
m4_dquote(b4_pure_if([[[[YYSTYPE *]], [[&yylval]]][]dnl
|
||||||
b4_location_if([, [[YYLTYPE *], [&yylloc]]])])dnl
|
b4_location_if([, [[YYLTYPE *], [&yylloc]]])])dnl
|
||||||
m4_ifdef([b4_lex_param], [, ]b4_lex_param)))
|
m4_ifdef([b4_lex_param], [, ]b4_lex_param)))
|
||||||
|
|
||||||
# Yes, this is quite ugly...
|
|
||||||
m4_define_default([b4_parse_param])
|
|
||||||
m4_ifdef([b4_parse_param],
|
|
||||||
[m4_define([b4_parse_param],
|
|
||||||
b4_parse_param)])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## ------------ ##
|
## ------------ ##
|
||||||
@@ -56,7 +74,7 @@ m4_ifdef([b4_parse_param],
|
|||||||
# ---------------------
|
# ---------------------
|
||||||
# Return the smallest int type able to handle numbers ranging from
|
# Return the smallest int type able to handle numbers ranging from
|
||||||
# MIN to MAX (included). We overwrite the version from c.m4 which relies
|
# MIN to MAX (included). We overwrite the version from c.m4 which relies
|
||||||
# on `signed char' which is not portable to old K&R compilers.
|
# on "signed char" which is not portable to old K&R compilers.
|
||||||
m4_define([b4_int_type],
|
m4_define([b4_int_type],
|
||||||
[m4_if(b4_ints_in($@, [0], [255]), [1], [unsigned char],
|
[m4_if(b4_ints_in($@, [0], [255]), [1], [unsigned char],
|
||||||
b4_ints_in($@, [-128], [127]), [1], [yysigned_char],
|
b4_ints_in($@, [-128], [127]), [1], [yysigned_char],
|
||||||
@@ -178,15 +196,7 @@ b4_copyright([Skeleton parser for Yacc-like parsing with Bison],
|
|||||||
define necessary library symbols; they are noted "INFRINGES ON
|
define necessary library symbols; they are noted "INFRINGES ON
|
||||||
USER NAME SPACE" below. */
|
USER NAME SPACE" below. */
|
||||||
|
|
||||||
/* Identify Bison output. */
|
b4_identification
|
||||||
#define YYBISON 1
|
|
||||||
|
|
||||||
/* Pure parsers. */
|
|
||||||
#define YYPURE b4_pure
|
|
||||||
|
|
||||||
/* Using locations. */
|
|
||||||
#define YYLSP_NEEDED b4_locations_flag
|
|
||||||
|
|
||||||
m4_if(b4_prefix[], [yy], [],
|
m4_if(b4_prefix[], [yy], [],
|
||||||
[/* If NAME_PREFIX is specified substitute the variables and functions
|
[/* If NAME_PREFIX is specified substitute the variables and functions
|
||||||
names. */
|
names. */
|
||||||
@@ -519,7 +529,7 @@ do \
|
|||||||
} \
|
} \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
yyerror ("syntax error: cannot back up"); \
|
yyerror ("syntax error: cannot back up"b4_pure_args); \
|
||||||
YYERROR; \
|
YYERROR; \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
@@ -1125,15 +1135,15 @@ yyerrlab:
|
|||||||
yycount++;
|
yycount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
yyerror (yymsg);
|
yyerror (yymsg]b4_pure_args[);
|
||||||
YYSTACK_FREE (yymsg);
|
YYSTACK_FREE (yymsg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
yyerror ("parse error; also virtual memory exhausted");
|
yyerror ("parse error; also virtual memory exhausted"]b4_pure_args[);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* YYERROR_VERBOSE */
|
#endif /* YYERROR_VERBOSE */
|
||||||
yyerror ("parse error");
|
yyerror ("parse error"]b4_pure_args[);
|
||||||
}
|
}
|
||||||
goto yyerrlab1;
|
goto yyerrlab1;
|
||||||
|
|
||||||
@@ -1248,7 +1258,7 @@ yyabortlab:
|
|||||||
| yyoverflowlab -- parser overflow comes here. |
|
| yyoverflowlab -- parser overflow comes here. |
|
||||||
`----------------------------------------------*/
|
`----------------------------------------------*/
|
||||||
yyoverflowlab:
|
yyoverflowlab:
|
||||||
yyerror ("parser stack overflow");
|
yyerror ("parser stack overflow"]b4_pure_args[);
|
||||||
yyresult = 2;
|
yyresult = 2;
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -682,7 +682,7 @@ involved, or by performing both actions, and then calling a designated
|
|||||||
user-defined function on the resulting values to produce an arbitrary
|
user-defined function on the resulting values to produce an arbitrary
|
||||||
merged result.
|
merged result.
|
||||||
|
|
||||||
Let's consider an example, vastly simplified from C++.
|
Let's consider an example, vastly simplified from a C++ grammar.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
%@{
|
%@{
|
||||||
@@ -706,20 +706,20 @@ stmt : expr ';' %dprec 1
|
|||||||
| decl %dprec 2
|
| decl %dprec 2
|
||||||
;
|
;
|
||||||
|
|
||||||
expr : ID @{ printf ("%s ", $$); @}
|
expr : ID @{ printf ("%s ", $$); @}
|
||||||
| TYPENAME '(' expr ')'
|
| TYPENAME '(' expr ')'
|
||||||
@{ printf ("%s <cast> ", $1); @}
|
@{ printf ("%s <cast> ", $1); @}
|
||||||
| expr '+' expr @{ printf ("+ "); @}
|
| expr '+' expr @{ printf ("+ "); @}
|
||||||
| expr '=' expr @{ printf ("= "); @}
|
| expr '=' expr @{ printf ("= "); @}
|
||||||
;
|
;
|
||||||
|
|
||||||
decl : TYPENAME declarator ';'
|
decl : TYPENAME declarator ';'
|
||||||
@{ printf ("%s <declare> ", $1); @}
|
@{ printf ("%s <declare> ", $1); @}
|
||||||
| TYPENAME declarator '=' expr ';'
|
| TYPENAME declarator '=' expr ';'
|
||||||
@{ printf ("%s <init-declare> ", $1); @}
|
@{ printf ("%s <init-declare> ", $1); @}
|
||||||
;
|
;
|
||||||
|
|
||||||
declarator : ID @{ printf ("\"%s\" ", $1); @}
|
declarator : ID @{ printf ("\"%s\" ", $1); @}
|
||||||
| '(' declarator ')'
|
| '(' declarator ')'
|
||||||
;
|
;
|
||||||
@end example
|
@end example
|
||||||
@@ -3559,10 +3559,11 @@ accurate parse error messages.
|
|||||||
Rename the external symbols used in the parser so that they start with
|
Rename the external symbols used in the parser so that they start with
|
||||||
@var{prefix} instead of @samp{yy}. The precise list of symbols renamed
|
@var{prefix} instead of @samp{yy}. The precise list of symbols renamed
|
||||||
is @code{yyparse}, @code{yylex}, @code{yyerror}, @code{yynerrs},
|
is @code{yyparse}, @code{yylex}, @code{yyerror}, @code{yynerrs},
|
||||||
@code{yylval}, @code{yychar}, @code{yydebug}, and possible
|
@code{yylval}, @code{yylloc}, @code{yychar}, @code{yydebug}, and
|
||||||
@code{yylloc}. For example, if you use @samp{%name-prefix="c_"}, the
|
possible @code{yylloc}. For example, if you use
|
||||||
names become @code{c_parse}, @code{c_lex}, and so on. @xref{Multiple
|
@samp{%name-prefix="c_"}, the names become @code{c_parse}, @code{c_lex},
|
||||||
Parsers, ,Multiple Parsers in the Same Program}.
|
and so on. @xref{Multiple Parsers, ,Multiple Parsers in the Same
|
||||||
|
Program}.
|
||||||
|
|
||||||
@item %no-parser
|
@item %no-parser
|
||||||
Do not include any C code in the parser file; generate tables only. The
|
Do not include any C code in the parser file; generate tables only. The
|
||||||
@@ -3659,9 +3660,9 @@ instead of @samp{yy}. You can use this to give each parser distinct
|
|||||||
names that do not conflict.
|
names that do not conflict.
|
||||||
|
|
||||||
The precise list of symbols renamed is @code{yyparse}, @code{yylex},
|
The precise list of symbols renamed is @code{yyparse}, @code{yylex},
|
||||||
@code{yyerror}, @code{yynerrs}, @code{yylval}, @code{yychar} and
|
@code{yyerror}, @code{yynerrs}, @code{yylval}, @code{yylloc},
|
||||||
@code{yydebug}. For example, if you use @samp{-p c}, the names become
|
@code{yychar} and @code{yydebug}. For example, if you use @samp{-p c},
|
||||||
@code{cparse}, @code{clex}, and so on.
|
the names become @code{cparse}, @code{clex}, and so on.
|
||||||
|
|
||||||
@strong{All the other variables and macros associated with Bison are not
|
@strong{All the other variables and macros associated with Bison are not
|
||||||
renamed.} These others are not global; there is no conflict if the same
|
renamed.} These others are not global; there is no conflict if the same
|
||||||
@@ -3706,23 +3707,65 @@ encounters end-of-input or an unrecoverable syntax error. You can also
|
|||||||
write an action which directs @code{yyparse} to return immediately
|
write an action which directs @code{yyparse} to return immediately
|
||||||
without reading further.
|
without reading further.
|
||||||
|
|
||||||
|
|
||||||
|
@deftypefun int yyparse (void)
|
||||||
The value returned by @code{yyparse} is 0 if parsing was successful (return
|
The value returned by @code{yyparse} is 0 if parsing was successful (return
|
||||||
is due to end-of-input).
|
is due to end-of-input).
|
||||||
|
|
||||||
The value is 1 if parsing failed (return is due to a syntax error).
|
The value is 1 if parsing failed (return is due to a syntax error).
|
||||||
|
@end deftypefun
|
||||||
|
|
||||||
In an action, you can cause immediate return from @code{yyparse} by using
|
In an action, you can cause immediate return from @code{yyparse} by using
|
||||||
these macros:
|
these macros:
|
||||||
|
|
||||||
@table @code
|
@defmac YYACCEPT
|
||||||
@item YYACCEPT
|
|
||||||
@findex YYACCEPT
|
@findex YYACCEPT
|
||||||
Return immediately with value 0 (to report success).
|
Return immediately with value 0 (to report success).
|
||||||
|
@end defmac
|
||||||
|
|
||||||
@item YYABORT
|
@defmac YYABORT
|
||||||
@findex YYABORT
|
@findex YYABORT
|
||||||
Return immediately with value 1 (to report failure).
|
Return immediately with value 1 (to report failure).
|
||||||
@end table
|
@end defmac
|
||||||
|
|
||||||
|
If you use a reentrant parser, you can optionally pass additional
|
||||||
|
parameter information to it in a reentrant way. To do so, use the
|
||||||
|
declaration @code{%parse-param}:
|
||||||
|
|
||||||
|
@deffn {Directive} %parse-param @var{argument-declaration} @var{argument-name}
|
||||||
|
@findex %parse-param
|
||||||
|
Declare that @code{argument-name} is an additional @code{yyparse}
|
||||||
|
argument. This argument is also passed to @code{yyerror}. The
|
||||||
|
@var{argument-declaration} is used when declaring functions or
|
||||||
|
prototypes.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
Here's an example. Write this in the parser:
|
||||||
|
|
||||||
|
@example
|
||||||
|
%parse-param "int *nastiness" "nastiness"
|
||||||
|
%parse-param "int *randomness" "randomness"
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
Then call the parser like this:
|
||||||
|
|
||||||
|
@example
|
||||||
|
@{
|
||||||
|
int nastiness, randomness;
|
||||||
|
@dots{} /* @r{Store proper data in @code{nastiness} and @code{randomness}.} */
|
||||||
|
value = yyparse (&nastiness, &randomness);
|
||||||
|
@dots{}
|
||||||
|
@}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
In the grammar actions, use expressions like this to refer to the data:
|
||||||
|
|
||||||
|
@example
|
||||||
|
exp: @dots{} @{ @dots{}; *randomness += 1; @dots{} @}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
|
||||||
@node Lexical
|
@node Lexical
|
||||||
@section The Lexical Analyzer Function @code{yylex}
|
@section The Lexical Analyzer Function @code{yylex}
|
||||||
@@ -3927,86 +3970,48 @@ textual positions, then the type @code{YYLTYPE} will not be defined. In
|
|||||||
this case, omit the second argument; @code{yylex} will be called with
|
this case, omit the second argument; @code{yylex} will be called with
|
||||||
only one argument.
|
only one argument.
|
||||||
|
|
||||||
@vindex YYPARSE_PARAM
|
|
||||||
If you use a reentrant parser, you can optionally pass additional
|
|
||||||
parameter information to it in a reentrant way. To do so, define the
|
|
||||||
macro @code{YYPARSE_PARAM} as a variable name. This modifies the
|
|
||||||
@code{yyparse} function to accept one argument, of type @code{void *},
|
|
||||||
with that name.
|
|
||||||
|
|
||||||
When you call @code{yyparse}, pass the address of an object, casting the
|
If you wish to pass the additional parameter data to @code{yylex}, use
|
||||||
address to @code{void *}. The grammar actions can refer to the contents
|
@code{%lex-param} just like @code{%parse-param} (@pxref{Parser
|
||||||
of the object by casting the pointer value back to its proper type and
|
Function}).
|
||||||
then dereferencing it. Here's an example. Write this in the parser:
|
|
||||||
|
@deffn {Directive} lex-param @var{argument-declaration} @var{argument-name}
|
||||||
|
@findex %lex-param
|
||||||
|
Declare that @code{argument-name} is an additional @code{yylex}
|
||||||
|
argument.
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
For instance:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
%@{
|
%parse-param "int *nastiness" "nastiness"
|
||||||
struct parser_control
|
%lex-param "int *nastiness" "nastiness"
|
||||||
@{
|
%parse-param "int *randomness" "randomness"
|
||||||
int nastiness;
|
|
||||||
int randomness;
|
|
||||||
@};
|
|
||||||
|
|
||||||
#define YYPARSE_PARAM parm
|
|
||||||
%@}
|
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
Then call the parser like this:
|
results in the following signature:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
struct parser_control
|
int yylex (int *nastiness);
|
||||||
@{
|
int yyparse (int *nastiness, int *randomness);
|
||||||
int nastiness;
|
@end example
|
||||||
int randomness;
|
|
||||||
@};
|
|
||||||
|
|
||||||
@dots{}
|
If @code{%pure-parser} is added:
|
||||||
|
|
||||||
@{
|
@example
|
||||||
struct parser_control foo;
|
int yylex (YYSTYPE *lvalp, int *nastiness);
|
||||||
@dots{} /* @r{Store proper data in @code{foo}.} */
|
int yyparse (int *nastiness, int *randomness);
|
||||||
value = yyparse ((void *) &foo);
|
|
||||||
@dots{}
|
|
||||||
@}
|
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
In the grammar actions, use expressions like this to refer to the data:
|
and finally, if both @code{%pure-parser} and @code{%locations} are used:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
((struct parser_control *) parm)->randomness
|
int yylex (YYSTYPE *lvalp, YYLTYPE *llocp, int *nastiness);
|
||||||
|
int yyparse (int *nastiness, int *randomness);
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@vindex YYLEX_PARAM
|
|
||||||
If you wish to pass the additional parameter data to @code{yylex},
|
|
||||||
define the macro @code{YYLEX_PARAM} just like @code{YYPARSE_PARAM}, as
|
|
||||||
shown here:
|
|
||||||
|
|
||||||
@example
|
|
||||||
%@{
|
|
||||||
struct parser_control
|
|
||||||
@{
|
|
||||||
int nastiness;
|
|
||||||
int randomness;
|
|
||||||
@};
|
|
||||||
|
|
||||||
#define YYPARSE_PARAM parm
|
|
||||||
#define YYLEX_PARAM parm
|
|
||||||
%@}
|
|
||||||
@end example
|
|
||||||
|
|
||||||
You should then define @code{yylex} to accept one additional
|
|
||||||
argument---the value of @code{parm}. (This makes either two or three
|
|
||||||
arguments in total, depending on whether an argument of type
|
|
||||||
@code{YYLTYPE} is passed.) You can declare the argument as a pointer to
|
|
||||||
the proper object type, or you can declare it as @code{void *} and
|
|
||||||
access the contents as shown above.
|
|
||||||
|
|
||||||
You can use @samp{%pure-parser} to request a reentrant parser without
|
|
||||||
also using @code{YYPARSE_PARAM}. Then you should call @code{yyparse}
|
|
||||||
with no arguments, as usual.
|
|
||||||
|
|
||||||
@node Error Reporting
|
@node Error Reporting
|
||||||
@section The Error Reporting Function @code{yyerror}
|
@section The Error Reporting Function @code{yyerror}
|
||||||
@cindex error reporting function
|
@cindex error reporting function
|
||||||
@@ -4026,13 +4031,11 @@ called by @code{yyparse} whenever a syntax error is found, and it
|
|||||||
receives one argument. For a parse error, the string is normally
|
receives one argument. For a parse error, the string is normally
|
||||||
@w{@code{"parse error"}}.
|
@w{@code{"parse error"}}.
|
||||||
|
|
||||||
@findex YYERROR_VERBOSE
|
@findex %error-verbose
|
||||||
If you define the macro @code{YYERROR_VERBOSE} in the Bison declarations
|
If you invoke the directive @code{%error-verbose} in the Bison
|
||||||
section (@pxref{Bison Declarations, ,The Bison Declarations Section}),
|
declarations section (@pxref{Bison Declarations, ,The Bison Declarations
|
||||||
then Bison provides a more verbose and specific error message string
|
Section}), then Bison provides a more verbose and specific error message
|
||||||
instead of just plain @w{@code{"parse error"}}. It doesn't matter what
|
string instead of just plain @w{@code{"parse error"}}.
|
||||||
definition you use for @code{YYERROR_VERBOSE}, just whether you define
|
|
||||||
it.
|
|
||||||
|
|
||||||
The parser can detect one other kind of error: stack overflow. This
|
The parser can detect one other kind of error: stack overflow. This
|
||||||
happens when the input contains constructions that are very deeply
|
happens when the input contains constructions that are very deeply
|
||||||
@@ -4061,6 +4064,50 @@ error recovery if you have written suitable error recovery grammar rules
|
|||||||
(@pxref{Error Recovery}). If recovery is impossible, @code{yyparse} will
|
(@pxref{Error Recovery}). If recovery is impossible, @code{yyparse} will
|
||||||
immediately return 1.
|
immediately return 1.
|
||||||
|
|
||||||
|
Oviously, in location tracking pure parsers, @code{yyerror} should have
|
||||||
|
an access to the current location. This is indeed the case for the GLR
|
||||||
|
parsers, but not for the Yacc parser, for historical reasons. I.e., if
|
||||||
|
@samp{%locations %pure-parser} is passed then the prototypes for
|
||||||
|
@code{yyerror} are:
|
||||||
|
|
||||||
|
@example
|
||||||
|
void yyerror (const char *msg); /* Yacc parsers. */
|
||||||
|
void yyerror (const char *msg, YYLTYPE *locp); /* GLR parsers. */
|
||||||
|
@end example
|
||||||
|
|
||||||
|
If @samp{%parse-param "int *nastiness" "nastiness"} is used, then:
|
||||||
|
|
||||||
|
@example
|
||||||
|
void yyerror (int *randomness); /* Yacc parsers. */
|
||||||
|
void yyerror (int *randomness); /* GLR parsers. */
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Finally, GLR and Yacc parsers share the same @code{yyerror} calling
|
||||||
|
convention for absolutely pure parsers, i.e., when the calling
|
||||||
|
convention of @code{yylex} @emph{and} the calling convention of
|
||||||
|
@code{%pure-parser} are pure. I.e.:
|
||||||
|
|
||||||
|
@example
|
||||||
|
/* Location tracking. */
|
||||||
|
%locations
|
||||||
|
/* Pure yylex. */
|
||||||
|
%pure-parser
|
||||||
|
%lex-param "int *nastiness" "nastiness"
|
||||||
|
/* Pure yyparse. */
|
||||||
|
%parse-param "int *nastiness" "nastiness"
|
||||||
|
%parse-param "int *randomness" "randomness"
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
results in the following signatures for all the parser kinds:
|
||||||
|
|
||||||
|
@example
|
||||||
|
int yylex (YYSTYPE *lvalp, YYLTYPE *llocp, int *nastiness);
|
||||||
|
int yyparse (int *nastiness, int *randomness);
|
||||||
|
void yyerror (const char *msg, YYLTYPE *locp,
|
||||||
|
int *nastiness, int *randomness);
|
||||||
|
@end example
|
||||||
|
|
||||||
@vindex yynerrs
|
@vindex yynerrs
|
||||||
The variable @code{yynerrs} contains the number of syntax errors
|
The variable @code{yynerrs} contains the number of syntax errors
|
||||||
encountered so far. Normally this variable is global; but if you
|
encountered so far. Normally this variable is global; but if you
|
||||||
@@ -5450,9 +5497,9 @@ state 0
|
|||||||
|
|
||||||
$accept -> . exp $ (rule 0)
|
$accept -> . exp $ (rule 0)
|
||||||
|
|
||||||
NUM shift, and go to state 1
|
NUM shift, and go to state 1
|
||||||
|
|
||||||
exp go to state 2
|
exp go to state 2
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
This reads as follows: ``state 0 corresponds to being at the very
|
This reads as follows: ``state 0 corresponds to being at the very
|
||||||
@@ -5499,7 +5546,7 @@ state 1
|
|||||||
|
|
||||||
exp -> NUM . (rule 5)
|
exp -> NUM . (rule 5)
|
||||||
|
|
||||||
$default reduce using rule 5 (exp)
|
$default reduce using rule 5 (exp)
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
@@ -5517,11 +5564,11 @@ state 2
|
|||||||
exp -> exp . '*' exp (rule 3)
|
exp -> exp . '*' exp (rule 3)
|
||||||
exp -> exp . '/' exp (rule 4)
|
exp -> exp . '/' exp (rule 4)
|
||||||
|
|
||||||
$ shift, and go to state 3
|
$ shift, and go to state 3
|
||||||
'+' shift, and go to state 4
|
'+' shift, and go to state 4
|
||||||
'-' shift, and go to state 5
|
'-' shift, and go to state 5
|
||||||
'*' shift, and go to state 6
|
'*' shift, and go to state 6
|
||||||
'/' shift, and go to state 7
|
'/' shift, and go to state 7
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
@@ -5540,7 +5587,7 @@ state 3
|
|||||||
|
|
||||||
$accept -> exp $ . (rule 0)
|
$accept -> exp $ . (rule 0)
|
||||||
|
|
||||||
$default accept
|
$default accept
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
@@ -5555,33 +5602,33 @@ state 4
|
|||||||
|
|
||||||
exp -> exp '+' . exp (rule 1)
|
exp -> exp '+' . exp (rule 1)
|
||||||
|
|
||||||
NUM shift, and go to state 1
|
NUM shift, and go to state 1
|
||||||
|
|
||||||
exp go to state 8
|
exp go to state 8
|
||||||
|
|
||||||
state 5
|
state 5
|
||||||
|
|
||||||
exp -> exp '-' . exp (rule 2)
|
exp -> exp '-' . exp (rule 2)
|
||||||
|
|
||||||
NUM shift, and go to state 1
|
NUM shift, and go to state 1
|
||||||
|
|
||||||
exp go to state 9
|
exp go to state 9
|
||||||
|
|
||||||
state 6
|
state 6
|
||||||
|
|
||||||
exp -> exp '*' . exp (rule 3)
|
exp -> exp '*' . exp (rule 3)
|
||||||
|
|
||||||
NUM shift, and go to state 1
|
NUM shift, and go to state 1
|
||||||
|
|
||||||
exp go to state 10
|
exp go to state 10
|
||||||
|
|
||||||
state 7
|
state 7
|
||||||
|
|
||||||
exp -> exp '/' . exp (rule 4)
|
exp -> exp '/' . exp (rule 4)
|
||||||
|
|
||||||
NUM shift, and go to state 1
|
NUM shift, and go to state 1
|
||||||
|
|
||||||
exp go to state 11
|
exp go to state 11
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
As was announced in beginning of the report, @samp{State 8 contains 1
|
As was announced in beginning of the report, @samp{State 8 contains 1
|
||||||
@@ -5596,11 +5643,11 @@ state 8
|
|||||||
exp -> exp . '*' exp (rule 3)
|
exp -> exp . '*' exp (rule 3)
|
||||||
exp -> exp . '/' exp (rule 4)
|
exp -> exp . '/' exp (rule 4)
|
||||||
|
|
||||||
'*' shift, and go to state 6
|
'*' shift, and go to state 6
|
||||||
'/' shift, and go to state 7
|
'/' shift, and go to state 7
|
||||||
|
|
||||||
'/' [reduce using rule 1 (exp)]
|
'/' [reduce using rule 1 (exp)]
|
||||||
$default reduce using rule 1 (exp)
|
$default reduce using rule 1 (exp)
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Indeed, there are two actions associated to the lookahead @samp{/}:
|
Indeed, there are two actions associated to the lookahead @samp{/}:
|
||||||
@@ -5657,11 +5704,11 @@ state 9
|
|||||||
exp -> exp . '*' exp (rule 3)
|
exp -> exp . '*' exp (rule 3)
|
||||||
exp -> exp . '/' exp (rule 4)
|
exp -> exp . '/' exp (rule 4)
|
||||||
|
|
||||||
'*' shift, and go to state 6
|
'*' shift, and go to state 6
|
||||||
'/' shift, and go to state 7
|
'/' shift, and go to state 7
|
||||||
|
|
||||||
'/' [reduce using rule 2 (exp)]
|
'/' [reduce using rule 2 (exp)]
|
||||||
$default reduce using rule 2 (exp)
|
$default reduce using rule 2 (exp)
|
||||||
|
|
||||||
state 10
|
state 10
|
||||||
|
|
||||||
@@ -5671,10 +5718,10 @@ state 10
|
|||||||
exp -> exp '*' exp . (rule 3)
|
exp -> exp '*' exp . (rule 3)
|
||||||
exp -> exp . '/' exp (rule 4)
|
exp -> exp . '/' exp (rule 4)
|
||||||
|
|
||||||
'/' shift, and go to state 7
|
'/' shift, and go to state 7
|
||||||
|
|
||||||
'/' [reduce using rule 3 (exp)]
|
'/' [reduce using rule 3 (exp)]
|
||||||
$default reduce using rule 3 (exp)
|
$default reduce using rule 3 (exp)
|
||||||
|
|
||||||
state 11
|
state 11
|
||||||
|
|
||||||
@@ -5684,16 +5731,16 @@ state 11
|
|||||||
exp -> exp . '/' exp (rule 4)
|
exp -> exp . '/' exp (rule 4)
|
||||||
exp -> exp '/' exp . (rule 4)
|
exp -> exp '/' exp . (rule 4)
|
||||||
|
|
||||||
'+' shift, and go to state 4
|
'+' shift, and go to state 4
|
||||||
'-' shift, and go to state 5
|
'-' shift, and go to state 5
|
||||||
'*' shift, and go to state 6
|
'*' shift, and go to state 6
|
||||||
'/' shift, and go to state 7
|
'/' shift, and go to state 7
|
||||||
|
|
||||||
'+' [reduce using rule 4 (exp)]
|
'+' [reduce using rule 4 (exp)]
|
||||||
'-' [reduce using rule 4 (exp)]
|
'-' [reduce using rule 4 (exp)]
|
||||||
'*' [reduce using rule 4 (exp)]
|
'*' [reduce using rule 4 (exp)]
|
||||||
'/' [reduce using rule 4 (exp)]
|
'/' [reduce using rule 4 (exp)]
|
||||||
$default reduce using rule 4 (exp)
|
$default reduce using rule 4 (exp)
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
@@ -6171,18 +6218,21 @@ Macro to pretend that a syntax error has just been detected: call
|
|||||||
@code{yyparse} return 1. @xref{Error Recovery}.
|
@code{yyparse} return 1. @xref{Error Recovery}.
|
||||||
|
|
||||||
@item YYERROR_VERBOSE
|
@item YYERROR_VERBOSE
|
||||||
Macro that you define with @code{#define} in the Bison declarations
|
An obsolete macro that you define with @code{#define} in the Bison
|
||||||
section to request verbose, specific error message strings when
|
declarations section to request verbose, specific error message strings
|
||||||
@code{yyerror} is called.
|
when @code{yyerror} is called. It doesn't matter what definition you
|
||||||
|
use for @code{YYERROR_VERBOSE}, just whether you define it. Using
|
||||||
|
@code{%error-verbose} is preferred.
|
||||||
|
|
||||||
@item YYINITDEPTH
|
@item YYINITDEPTH
|
||||||
Macro for specifying the initial size of the parser stack.
|
Macro for specifying the initial size of the parser stack.
|
||||||
@xref{Stack Overflow}.
|
@xref{Stack Overflow}.
|
||||||
|
|
||||||
@item YYLEX_PARAM
|
@item YYLEX_PARAM
|
||||||
Macro for specifying an extra argument (or list of extra arguments) for
|
An obsolete macro for specifying an extra argument (or list of extra
|
||||||
@code{yyparse} to pass to @code{yylex}. @xref{Pure Calling,, Calling
|
arguments) for @code{yyparse} to pass to @code{yylex}. he use of this
|
||||||
Conventions for Pure Parsers}.
|
macro is deprecated, and is supported only for Yacc like parsers.
|
||||||
|
@xref{Pure Calling,, Calling Conventions for Pure Parsers}.
|
||||||
|
|
||||||
@item YYLTYPE
|
@item YYLTYPE
|
||||||
Macro for the data type of @code{yylloc}; a structure with four
|
Macro for the data type of @code{yylloc}; a structure with four
|
||||||
@@ -6196,8 +6246,10 @@ Macro for specifying the maximum size of the parser stack.
|
|||||||
@xref{Stack Overflow}.
|
@xref{Stack Overflow}.
|
||||||
|
|
||||||
@item YYPARSE_PARAM
|
@item YYPARSE_PARAM
|
||||||
Macro for specifying the name of a parameter that @code{yyparse} should
|
An obsolete macro for specifying the name of a parameter that
|
||||||
accept. @xref{Pure Calling,, Calling Conventions for Pure Parsers}.
|
@code{yyparse} should accept. The use of this macro is deprecated, and
|
||||||
|
is supported only for Yacc like parsers. @xref{Pure Calling,, Calling
|
||||||
|
Conventions for Pure Parsers}.
|
||||||
|
|
||||||
@item YYRECOVERING
|
@item YYRECOVERING
|
||||||
Macro whose value indicates whether the parser is recovering from a
|
Macro whose value indicates whether the parser is recovering from a
|
||||||
@@ -6278,6 +6330,10 @@ Bison declaration to assign a precedence to a rule that is used at parse
|
|||||||
time to resolve reduce/reduce conflicts. @xref{GLR Parsers, ,Writing
|
time to resolve reduce/reduce conflicts. @xref{GLR Parsers, ,Writing
|
||||||
@acronym{GLR} Parsers}.
|
@acronym{GLR} Parsers}.
|
||||||
|
|
||||||
|
@item %error-verbose
|
||||||
|
Bison declaration to request verbose, specific error message strings
|
||||||
|
when @code{yyerror} is called.
|
||||||
|
|
||||||
@item %file-prefix="@var{prefix}"
|
@item %file-prefix="@var{prefix}"
|
||||||
Bison declaration to set the prefix of the output files. @xref{Decl
|
Bison declaration to set the prefix of the output files. @xref{Decl
|
||||||
Summary}.
|
Summary}.
|
||||||
@@ -6298,6 +6354,11 @@ Parsers, ,Writing @acronym{GLR} Parsers}.
|
|||||||
Bison declaration to assign left associativity to token(s).
|
Bison declaration to assign left associativity to token(s).
|
||||||
@xref{Precedence Decl, ,Operator Precedence}.
|
@xref{Precedence Decl, ,Operator Precedence}.
|
||||||
|
|
||||||
|
@item %lex-param "@var{argument-declaration}" "@var{argument-name}"
|
||||||
|
Bison declaration to specifying an additional parameter that
|
||||||
|
@code{yylex} should accept. @xref{Pure Calling,, Calling Conventions
|
||||||
|
for Pure Parsers}.
|
||||||
|
|
||||||
@item %merge
|
@item %merge
|
||||||
Bison declaration to assign a merging function to a rule. If there is a
|
Bison declaration to assign a merging function to a rule. If there is a
|
||||||
reduce/reduce conflict with a rule having the same merging function, the
|
reduce/reduce conflict with a rule having the same merging function, the
|
||||||
@@ -6319,6 +6380,11 @@ Bison declaration to assign non-associativity to token(s).
|
|||||||
Bison declaration to set the name of the parser file. @xref{Decl
|
Bison declaration to set the name of the parser file. @xref{Decl
|
||||||
Summary}.
|
Summary}.
|
||||||
|
|
||||||
|
@item %parse-param "@var{argument-declaration}" "@var{argument-name}"
|
||||||
|
Bison declaration to specifying an additional parameter that
|
||||||
|
@code{yyparse} should accept. @xref{Parser Function,, The Parser
|
||||||
|
Function @code{yyparse}}.
|
||||||
|
|
||||||
@item %prec
|
@item %prec
|
||||||
Bison declaration to assign a precedence to a specific rule.
|
Bison declaration to assign a precedence to a specific rule.
|
||||||
@xref{Contextual Precedence, ,Context-Dependent Precedence}.
|
@xref{Contextual Precedence, ,Context-Dependent Precedence}.
|
||||||
|
|||||||
145
tests/calc.at
145
tests/calc.at
@@ -26,8 +26,8 @@
|
|||||||
# ------------------------- #
|
# ------------------------- #
|
||||||
|
|
||||||
|
|
||||||
# _AT_DATA_CALC_Y($1, $2, $3, [CPP-DIRECTIVES])
|
# _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
|
||||||
# ---------------------------------------------
|
# -----------------------------------------------
|
||||||
# Produce `calc.y'. Don't call this macro directly, because it contains
|
# Produce `calc.y'. Don't call this macro directly, because it contains
|
||||||
# some occurrences of `$1' etc. which will be interpreted by m4. So
|
# some occurrences of `$1' etc. which will be interpreted by m4. So
|
||||||
# you should call it with $1, $2, and $3 as arguments, which is what
|
# you should call it with $1, $2, and $3 as arguments, which is what
|
||||||
@@ -37,7 +37,7 @@ m4_define([_AT_DATA_CALC_Y],
|
|||||||
[m4_fatal([$0: Invalid arguments: $@])])dnl
|
[m4_fatal([$0: Invalid arguments: $@])])dnl
|
||||||
AT_DATA([calc.y],
|
AT_DATA([calc.y],
|
||||||
[[/* Infix notation calculator--calc */
|
[[/* Infix notation calculator--calc */
|
||||||
|
]$4[
|
||||||
%{
|
%{
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
/* We don't need perfect functions for these tests. */
|
/* We don't need perfect functions for these tests. */
|
||||||
@@ -63,9 +63,6 @@ int global_count = 0;
|
|||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%parse-param "value_t *result", "result"
|
|
||||||
%parse-param "int *count", "count"
|
|
||||||
|
|
||||||
/* Exercise %union. */
|
/* Exercise %union. */
|
||||||
%union
|
%union
|
||||||
{
|
{
|
||||||
@@ -81,16 +78,14 @@ int global_count = 0;
|
|||||||
# define VAL (yylval)
|
# define VAL (yylval)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define YYLLOC_FORMAL ]AT_LOCATION_IF([, YYLTYPE *yylloc])[
|
||||||
|
#define YYLLOC_ARG ]AT_LOCATION_IF([, yylloc])[
|
||||||
|
#define USE_YYLLOC ]AT_LOCATION_IF([(void) yylloc;])[
|
||||||
|
|
||||||
#if YYPURE
|
#if YYPURE
|
||||||
# if YYLSP_NEEDED
|
# define LEX_FORMALS YYSTYPE *yylval YYLLOC_FORMAL
|
||||||
# define LEX_FORMALS YYSTYPE *yylval, YYLTYPE *yylloc
|
# define LEX_ARGS yylval YYLLOC_ARG
|
||||||
# define LEX_ARGS yylval, yylloc
|
# define USE_LEX_ARGS (void) yylval; USE_YYLLOC
|
||||||
# define USE_LEX_ARGS (void) yylval; (void) yylloc;
|
|
||||||
# else
|
|
||||||
# define LEX_FORMALS YYSTYPE *yylval
|
|
||||||
# define LEX_ARGS yylval
|
|
||||||
# define USE_LEX_ARGS (void) yylval
|
|
||||||
# endif
|
|
||||||
# define LEX_PRE_FORMALS LEX_FORMALS,
|
# define LEX_PRE_FORMALS LEX_FORMALS,
|
||||||
# define LEX_PRE_ARGS LEX_ARGS,
|
# define LEX_PRE_ARGS LEX_ARGS,
|
||||||
#else
|
#else
|
||||||
@@ -102,7 +97,13 @@ int global_count = 0;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int power (int base, int exponent);
|
static int power (int base, int exponent);
|
||||||
static void yyerror (const char *s);
|
/* yyerror receives the location if:
|
||||||
|
- %location & %pure & %glr
|
||||||
|
- %location & %pure & %yacc & %parse-param. */
|
||||||
|
static void yyerror (const char *s
|
||||||
|
]AT_YYERROR_ARG_LOC_IF([, YYLTYPE *yylloc])[
|
||||||
|
]AT_PARAM_IF([, value_t *result, int *count])[
|
||||||
|
);
|
||||||
static int yylex (LEX_FORMALS);
|
static int yylex (LEX_FORMALS);
|
||||||
static int yygetc (LEX_FORMALS);
|
static int yygetc (LEX_FORMALS);
|
||||||
static void yyungetc (LEX_PRE_FORMALS int c);
|
static void yyungetc (LEX_PRE_FORMALS int c);
|
||||||
@@ -119,27 +120,25 @@ static void yyungetc (LEX_PRE_FORMALS int c);
|
|||||||
%left NEG /* negation--unary minus */
|
%left NEG /* negation--unary minus */
|
||||||
%right '^' /* exponentiation */
|
%right '^' /* exponentiation */
|
||||||
|
|
||||||
]$4[
|
|
||||||
|
|
||||||
/* Grammar follows */
|
/* Grammar follows */
|
||||||
%%
|
%%
|
||||||
input:
|
input:
|
||||||
line
|
line
|
||||||
| input line { ++*count; ++global_count; }
|
| input line { ]AT_PARAM_IF([++*count; ++global_count;])[ }
|
||||||
;
|
;
|
||||||
|
|
||||||
line:
|
line:
|
||||||
'\n'
|
'\n'
|
||||||
| exp '\n' { *result = global_result = $1; }
|
| exp '\n' { ]AT_PARAM_IF([*result = global_result = $1;])[ }
|
||||||
;
|
;
|
||||||
|
|
||||||
exp:
|
exp:
|
||||||
NUM { $$ = $1; }
|
NUM { $$ = $1; }
|
||||||
| exp '=' exp
|
| exp '=' exp
|
||||||
{
|
{
|
||||||
if ($1 != $3)
|
if ($1 != $3)
|
||||||
fprintf (stderr, "calc: error: %d != %d\n", $1, $3);
|
fprintf (stderr, "calc: error: %d != %d\n", $1, $3);
|
||||||
$$ = $1;
|
$$ = $1;
|
||||||
}
|
}
|
||||||
| exp '+' exp { $$ = $1 + $3; }
|
| exp '+' exp { $$ = $1 + $3; }
|
||||||
| exp '-' exp { $$ = $1 - $3; }
|
| exp '-' exp { $$ = $1 - $3; }
|
||||||
@@ -155,26 +154,28 @@ exp:
|
|||||||
FILE *yyin;
|
FILE *yyin;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
yyerror (const char *s)
|
yyerror (const char *s
|
||||||
|
]AT_YYERROR_ARG_LOC_IF([, YYLTYPE *yylloc])[
|
||||||
|
]AT_PARAM_IF([, value_t *result, int *count])[)
|
||||||
{
|
{
|
||||||
#if YYLSP_NEEDED
|
]AT_YYERROR_SEES_LOC_IF([
|
||||||
fprintf (stderr, "%d.%d-%d.%d: ",
|
fprintf (stderr, "%d.%d-%d.%d: ",
|
||||||
LOC.first_line, LOC.first_column,
|
LOC.first_line, LOC.first_column,
|
||||||
LOC.last_line, LOC.last_column);
|
LOC.last_line, LOC.last_column);
|
||||||
#endif
|
])[
|
||||||
fprintf (stderr, "%s\n", s);
|
fprintf (stderr, "%s\n", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if YYLSP_NEEDED
|
]AT_LOCATION_IF([
|
||||||
static YYLTYPE last_yylloc;
|
static YYLTYPE last_yylloc;
|
||||||
#endif
|
])[
|
||||||
static int
|
static int
|
||||||
yygetc (LEX_FORMALS)
|
yygetc (LEX_FORMALS)
|
||||||
{
|
{
|
||||||
int res = getc (yyin);
|
int res = getc (yyin);
|
||||||
USE_LEX_ARGS;
|
USE_LEX_ARGS;
|
||||||
#if YYLSP_NEEDED
|
]AT_LOCATION_IF([
|
||||||
last_yylloc = LOC;
|
last_yylloc = LOC;
|
||||||
if (res == '\n')
|
if (res == '\n')
|
||||||
{
|
{
|
||||||
@@ -183,7 +184,7 @@ yygetc (LEX_FORMALS)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
LOC.last_column++;
|
LOC.last_column++;
|
||||||
#endif
|
])[
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,10 +193,10 @@ static void
|
|||||||
yyungetc (LEX_PRE_FORMALS int c)
|
yyungetc (LEX_PRE_FORMALS int c)
|
||||||
{
|
{
|
||||||
USE_LEX_ARGS;
|
USE_LEX_ARGS;
|
||||||
#if YYLSP_NEEDED
|
]AT_LOCATION_IF([
|
||||||
/* Wrong when C == `\n'. */
|
/* Wrong when C == `\n'. */
|
||||||
LOC = last_yylloc;
|
LOC = last_yylloc;
|
||||||
#endif
|
])[
|
||||||
ungetc (c, yyin);
|
ungetc (c, yyin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,24 +242,24 @@ yylex (LEX_FORMALS)
|
|||||||
if (init)
|
if (init)
|
||||||
{
|
{
|
||||||
init = 0;
|
init = 0;
|
||||||
#if YYLSP_NEEDED
|
]AT_LOCATION_IF([
|
||||||
LOC.last_column = 1;
|
LOC.last_column = 1;
|
||||||
LOC.last_line = 1;
|
LOC.last_line = 1;
|
||||||
#endif
|
])[
|
||||||
}
|
}
|
||||||
|
|
||||||
#if YYLSP_NEEDED
|
]AT_LOCATION_IF([
|
||||||
LOC.first_column = LOC.last_column;
|
LOC.first_column = LOC.last_column;
|
||||||
LOC.first_line = LOC.last_line;
|
LOC.first_line = LOC.last_line;
|
||||||
#endif
|
])[
|
||||||
|
|
||||||
/* Skip white space. */
|
/* Skip white space. */
|
||||||
while ((c = yygetc (LEX_ARGS)) == ' ' || c == '\t')
|
while ((c = yygetc (LEX_ARGS)) == ' ' || c == '\t')
|
||||||
{
|
{
|
||||||
#if YYLSP_NEEDED
|
]AT_LOCATION_IF([
|
||||||
LOC.first_column = LOC.last_column;
|
LOC.first_column = LOC.last_column;
|
||||||
LOC.first_line = LOC.last_line;
|
LOC.first_line = LOC.last_line;
|
||||||
#endif
|
])[
|
||||||
}
|
}
|
||||||
|
|
||||||
/* process numbers */
|
/* process numbers */
|
||||||
@@ -309,7 +310,7 @@ main (int argc, const char **argv)
|
|||||||
#if YYDEBUG
|
#if YYDEBUG
|
||||||
yydebug = 1;
|
yydebug = 1;
|
||||||
#endif
|
#endif
|
||||||
yyparse (&result, &count);
|
yyparse (]AT_PARAM_IF([&result, &count])[);
|
||||||
assert (global_result == result);
|
assert (global_result == result);
|
||||||
assert (global_count == count);
|
assert (global_count == count);
|
||||||
|
|
||||||
@@ -352,8 +353,8 @@ m4_bmatch([$1],
|
|||||||
|
|
||||||
|
|
||||||
# _AT_CHECK_CALC_ERROR(BISON-OPTIONS, INPUT, [NUM-DEBUG-LINES],
|
# _AT_CHECK_CALC_ERROR(BISON-OPTIONS, INPUT, [NUM-DEBUG-LINES],
|
||||||
# [ERROR-LOCATION], [IF-YYERROR-VERBOSE])
|
# [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
|
||||||
# ------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
# Run `calc' on INPUT, and expect a `parse error' message.
|
# Run `calc' on INPUT, and expect a `parse error' message.
|
||||||
#
|
#
|
||||||
# If INPUT starts with a slash, it is used as absolute input file name,
|
# If INPUT starts with a slash, it is used as absolute input file name,
|
||||||
@@ -402,7 +403,7 @@ AT_DATA([[expout]],
|
|||||||
[$4
|
[$4
|
||||||
])
|
])
|
||||||
# 3. If locations are not used, remove them.
|
# 3. If locations are not used, remove them.
|
||||||
m4_bmatch([$1], [%locations], [],
|
AT_YYERROR_SEES_LOC_IF([],
|
||||||
[[sed 's/^[-0-9.]*: //' expout >at-expout
|
[[sed 's/^[-0-9.]*: //' expout >at-expout
|
||||||
mv at-expout expout]])
|
mv at-expout expout]])
|
||||||
# 4. If error-verbose is not used, strip the`, unexpected....' part.
|
# 4. If error-verbose is not used, strip the`, unexpected....' part.
|
||||||
@@ -414,6 +415,54 @@ AT_CHECK([cat stderr], 0, [expout])
|
|||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# AT_CALC_PUSHDEFS($1, $2, [BISON-OPTIONS])
|
||||||
|
# -----------------------------------------
|
||||||
|
# This macro works around the impossibility to define macros
|
||||||
|
# inside macros, because issuing `[$1]' is not possible in M4 :(.
|
||||||
|
# This sucks hard, GNU M4 should really provide M5 like $$1.
|
||||||
|
m4_define([AT_CHECK_PUSHDEFS],
|
||||||
|
[m4_if([$1$2], $[1]$[2], [],
|
||||||
|
[m4_fatal([$0: Invalid arguments: $@])])dnl
|
||||||
|
m4_pushdef([AT_PARAM_IF],
|
||||||
|
[m4_bmatch([$3], [%parse-param], [$1], [$2])])
|
||||||
|
m4_pushdef([AT_LOCATION_IF],
|
||||||
|
[m4_bmatch([$3], [%locations], [$1], [$2])])
|
||||||
|
m4_pushdef([AT_PURE_IF],
|
||||||
|
[m4_bmatch([$3], [%pure-parser], [$1], [$2])])
|
||||||
|
m4_pushdef([AT_GLR_IF],
|
||||||
|
[m4_bmatch([$3], [%glr-parser], [$1], [$2])])
|
||||||
|
m4_pushdef([AT_PURE_AND_LOC_IF],
|
||||||
|
[m4_bmatch([$3], [%locations.*%pure-parser\|%pure-parser.*%locations],
|
||||||
|
[$1], [$2])])
|
||||||
|
m4_pushdef([AT_GLR_OR_PARAM_IF],
|
||||||
|
[m4_bmatch([$3], [%glr-parser\|%parse-param], [$1], [$2])])
|
||||||
|
|
||||||
|
# yyerror receives the location if %location & %pure & (%glr or %parse-param).
|
||||||
|
m4_pushdef([AT_YYERROR_ARG_LOC_IF],
|
||||||
|
[AT_GLR_OR_PARAM_IF([AT_PURE_AND_LOC_IF([$1], [$2])],
|
||||||
|
[$2])])
|
||||||
|
# yyerror cannot see the locations if !glr & pure.
|
||||||
|
m4_pushdef([AT_YYERROR_SEES_LOC_IF],
|
||||||
|
[AT_LOCATION_IF([AT_GLR_IF([$1],
|
||||||
|
[AT_PURE_IF([$2], [$1])])],
|
||||||
|
[$2])])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# AT_CALC_POPDEFS
|
||||||
|
# ---------------
|
||||||
|
m4_define([AT_CHECK_POPDEFS],
|
||||||
|
[m4_popdef([AT_YYERROR_SEES_LOC_IF])
|
||||||
|
m4_popdef([AT_YYERROR_ARG_LOC_IF])
|
||||||
|
m4_popdef([AT_GLR_OR_PARAM_IF])
|
||||||
|
m4_popdef([AT_PURE_AND_LOC_IF])
|
||||||
|
m4_popdef([AT_GLR_IF])
|
||||||
|
m4_popdef([AT_LOCATION_IF])
|
||||||
|
m4_popdef([AT_PARAM_IF])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# AT_CHECK_CALC([BISON-OPTIONS])
|
# AT_CHECK_CALC([BISON-OPTIONS])
|
||||||
# ------------------------------
|
# ------------------------------
|
||||||
# Start a testing chunk which compiles `calc' grammar with
|
# Start a testing chunk which compiles `calc' grammar with
|
||||||
@@ -422,6 +471,8 @@ m4_define([AT_CHECK_CALC],
|
|||||||
[# We use integers to avoid dependencies upon the precision of doubles.
|
[# We use integers to avoid dependencies upon the precision of doubles.
|
||||||
AT_SETUP([Calculator $1])
|
AT_SETUP([Calculator $1])
|
||||||
|
|
||||||
|
AT_CHECK_PUSHDEFS($[1], $[2], [$1])
|
||||||
|
|
||||||
AT_DATA_CALC_Y([$1])
|
AT_DATA_CALC_Y([$1])
|
||||||
|
|
||||||
# Specify the output files to avoid problems on different file systems.
|
# Specify the output files to avoid problems on different file systems.
|
||||||
@@ -473,6 +524,8 @@ _AT_CHECK_CALC_ERROR([$1], [(1 ++ 2) + (0 0) = 1], [82],
|
|||||||
1.15-1.16: parse error, unexpected "number"
|
1.15-1.16: parse error, unexpected "number"
|
||||||
calc: error: 0 != 1])
|
calc: error: 0 != 1])
|
||||||
|
|
||||||
|
AT_CHECK_POPDEFS
|
||||||
|
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
])# AT_CHECK_CALC
|
])# AT_CHECK_CALC
|
||||||
|
|
||||||
@@ -508,7 +561,9 @@ AT_CHECK_CALC_LALR([%error-verbose %locations %defines %name-prefix="calc" %verb
|
|||||||
AT_CHECK_CALC_LALR([%debug])
|
AT_CHECK_CALC_LALR([%debug])
|
||||||
AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
|
AT_CHECK_CALC_LALR([%error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
|
||||||
|
|
||||||
# AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
|
AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
|
||||||
|
|
||||||
|
AT_CHECK_CALC_LALR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param "value_t *result", "result" %parse-param "int *count", "count"])
|
||||||
|
|
||||||
|
|
||||||
# ----------------------- #
|
# ----------------------- #
|
||||||
@@ -541,4 +596,6 @@ AT_CHECK_CALC_GLR([%error-verbose %locations %defines %name-prefix="calc" %verbo
|
|||||||
AT_CHECK_CALC_GLR([%debug])
|
AT_CHECK_CALC_GLR([%debug])
|
||||||
AT_CHECK_CALC_GLR([%error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
|
AT_CHECK_CALC_GLR([%error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
|
||||||
|
|
||||||
# AT_CHECK_CALC_GLR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
|
AT_CHECK_CALC_GLR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc])
|
||||||
|
|
||||||
|
AT_CHECK_CALC_GLR([%pure-parser %error-verbose %debug %locations %defines %name-prefix="calc" %verbose %yacc %parse-param "value_t *result", "result" %parse-param "int *count", "count"])
|
||||||
|
|||||||
@@ -36,7 +36,11 @@ $1
|
|||||||
]m4_bmatch([$2], [stmtMerge],
|
]m4_bmatch([$2], [stmtMerge],
|
||||||
[ static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1);])[
|
[ static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1);])[
|
||||||
#define YYINITDEPTH 10
|
#define YYINITDEPTH 10
|
||||||
int yyerror (const char *s);
|
int yyerror (const char *s
|
||||||
|
#if YYPURE && YYLSP_NEEDED
|
||||||
|
, YYLTYPE *yylocation
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
#if YYPURE
|
#if YYPURE
|
||||||
]m4_bmatch([$1], [location],
|
]m4_bmatch([$1], [location],
|
||||||
@@ -130,7 +134,7 @@ yylex ()
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (isalpha (c))
|
if (isalpha (c))
|
||||||
{
|
{
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
@@ -153,8 +157,15 @@ yylex ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
yyerror (const char *s)
|
yyerror (const char *s
|
||||||
|
#if YYPURE && YYLSP_NEEDED
|
||||||
|
, YYLTYPE *yylocation
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
#if YYPURE && YYLSP_NEEDED
|
||||||
|
(void) *yylocation;
|
||||||
|
#endif
|
||||||
fprintf (stderr, "%s\n", s);
|
fprintf (stderr, "%s\n", s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user