GLR parsers sometimes raise parse errors instead of performing the

default reduction.
Reported by Charles-Henry de Boysson.
* tests/calc.at (_AT_CHECK_CALC, _AT_CHECK_CALC_ERROR): Don't
check the length of the	traces when %glr.
(_AT_CHECK_CALC_ERROR): Also skip `^Stack' lines, coming from
GLR's traces.
(AT_CHECK_CALC_LALR, AT_CHECK_CALC_GLR): New.
Test GLR parsers.
* data/glr.c (YYLEFTMOST_STATE): Fix its value.
(yyltype): Remove the yy prefix from the member names.
(yytable): Complete its comment.
(yygetLRActions): Map error action number from YYTABLE from
YYTABLE_NINF to 0.
(yyisErrorAction): No longer compare YYACTION to YYPACT_NINF
(which was a bug: it should have been YYTABEL_NINF, and yet it was
not satisfying as we could compare an YYACTION computed from
YYDEFACT to YYTABLE_NINF although they are unrelated): 0 is the
only value for error actions.
(yyreportParseError): In verbose parse error messages, don't issue
`error' in the list of expected tokens.
* data/yacc.c (yyparse) <yybackup>: Rewrite the decoding of the
next action to perform to match glr.c's decoding.
(yytable): Complete its comment.
This commit is contained in:
Akim Demaille
2002-10-13 14:25:14 +00:00
parent 3b7d4eb2cd
commit f50adbbdb0
6 changed files with 213 additions and 129 deletions

View File

@@ -1,3 +1,31 @@
2002-10-13 Akim Demaille <akim@epita.fr>
GLR parsers sometimes raise parse errors instead of performing the
default reduction.
Reported by Charles-Henry de Boysson.
* tests/calc.at (_AT_CHECK_CALC, _AT_CHECK_CALC_ERROR): Don't
check the length of the traces when %glr.
(_AT_CHECK_CALC_ERROR): Also skip `^Stack' lines, coming from
GLR's traces.
(AT_CHECK_CALC_LALR, AT_CHECK_CALC_GLR): New.
Test GLR parsers.
* data/glr.c (YYLEFTMOST_STATE): Fix its value.
(yyltype): Remove the yy prefix from the member names.
(yytable): Complete its comment.
(yygetLRActions): Map error action number from YYTABLE from
YYTABLE_NINF to 0.
(yyisErrorAction): No longer compare YYACTION to YYPACT_NINF
(which was a bug: it should have been YYTABEL_NINF, and yet it was
not satisfying as we could compare an YYACTION computed from
YYDEFACT to YYTABLE_NINF although they are unrelated): 0 is the
only value for error actions.
(yyreportParseError): In verbose parse error messages, don't issue
`error' in the list of expected tokens.
* data/yacc.c (yyparse) <yybackup>: Rewrite the decoding of the
next action to perform to match glr.c's decoding.
(yytable): Complete its comment.
2002-10-13 Paul Eggert <eggert@twinsun.com> 2002-10-13 Paul Eggert <eggert@twinsun.com>
Fix problem reported by Henrik Grubbstroem in Fix problem reported by Henrik Grubbstroem in

7
NEWS
View File

@@ -7,6 +7,13 @@ Changes in version 1.50a:
* Indonesian translation thanks to Tedi Heriyanto. * Indonesian translation thanks to Tedi Heriyanto.
* GLR parsers
Fix spurious parse errors.
* Pure parsers
Some people redefine yyerror to steal yyparse' private variables.
Reenable this trick until an official feature replaces it.
Changes in version 1.50, 2002-10-04: Changes in version 1.50, 2002-10-04:
* GLR parsing * GLR parsing

113
THANKS
View File

@@ -1,62 +1,63 @@
Bison was originally written by Robert Corbett. It would not be what Bison was originally written by Robert Corbett. It would not be what
it is today without the invaluable help of these people: it is today without the invaluable help of these people:
Airy Andre Airy.Andre@edf.fr Airy Andre Airy.Andre@edf.fr
Akim Demaille akim@freefriends.org Akim Demaille akim@freefriends.org
Albert Chin-A-Young china@thewrittenword.com Albert Chin-A-Young china@thewrittenword.com
Alexander Belopolsky alexb@rentec.com Alexander Belopolsky alexb@rentec.com
Andreas Schwab schwab@suse.de Andreas Schwab schwab@suse.de
Arnold Robbins arnold@skeeve.com Arnold Robbins arnold@skeeve.com
Art Haas ahaas@neosoft.com Art Haas ahaas@neosoft.com
Benoit Perrot benoit.perrot@epita.fr Benoit Perrot benoit.perrot@epita.fr
Bruce Lilly blilly@erols.com Bruce Lilly blilly@erols.com
Cris Bailiff c.bailiff+bison@awayweb.com Charles-Henri de Boysson deboys_c@epita.fr
Cris van Pelt cris@amf03054.office.wxs.nl Cris Bailiff c.bailiff+bison@awayweb.com
Daniel Hagerty hag@gnu.org Cris van Pelt cris@amf03054.office.wxs.nl
David J. MacKenzie djm@gnu.org Daniel Hagerty hag@gnu.org
Dick Streefland dick.streefland@altium.nl David J. MacKenzie djm@gnu.org
Enrico Scholz enrico.scholz@informatik.tu-chemnitz.de Dick Streefland dick.streefland@altium.nl
Evgeny Stambulchik fnevgeny@plasma-gate.weizmann.ac.il Enrico Scholz enrico.scholz@informatik.tu-chemnitz.de
Fabrice Bauzac noon@cote-dazur.com Evgeny Stambulchik fnevgeny@plasma-gate.weizmann.ac.il
Florian Krohm florian@edamail.fishkill.ibm.com Fabrice Bauzac noon@cote-dazur.com
H. Merijn Brand h.m.brand@hccnet.nl Florian Krohm florian@edamail.fishkill.ibm.com
Hans Aberg haberg@matematik.su.se H. Merijn Brand h.m.brand@hccnet.nl
Jan Nieuwenhuizen janneke@gnu.org Hans Aberg haberg@matematik.su.se
Jesse Thilo jthilo@gnu.org Jan Nieuwenhuizen janneke@gnu.org
Jim Meyering jim@meyering.net Jesse Thilo jthilo@gnu.org
Juan Manuel Guerrero ST001906@HRZ1.HRZ.TU-Darmstadt.De Jim Meyering jim@meyering.net
Kees Zeelenberg kzlg@users.sourceforge.net Juan Manuel Guerrero ST001906@HRZ1.HRZ.TU-Darmstadt.De
Keith Browne kbrowne@legato.com Kees Zeelenberg kzlg@users.sourceforge.net
Laurent Mascherpa laurent.mascherpa@epita.fr Keith Browne kbrowne@legato.com
Magnus Fromreide magfr@lysator.liu.se Laurent Mascherpa laurent.mascherpa@epita.fr
Marc Autret autret_m@epita.fr Magnus Fromreide magfr@lysator.liu.se
Martin Mokrejs mmokrejs@natur.cuni.cz Marc Autret autret_m@epita.fr
Matt Kraai kraai@alumni.cmu.edu Martin Mokrejs mmokrejs@natur.cuni.cz
Michael Hayes m.hayes@elec.canterbury.ac.nz Matt Kraai kraai@alumni.cmu.edu
Mike Castle dalgoda@ix.netcom.com Michael Hayes m.hayes@elec.canterbury.ac.nz
Neil Booth NeilB@earthling.net Mike Castle dalgoda@ix.netcom.com
Nelson H. F. Beebe beebe@math.utah.edu Neil Booth NeilB@earthling.net
Nicolas Burrus nicolas.burrus@epita.fr Nelson H. F. Beebe beebe@math.utah.edu
Nicolas Tisserand nicolas.tisserand@epita.fr Nicolas Burrus nicolas.burrus@epita.fr
Noah Friedman friedman@gnu.org Nicolas Tisserand nicolas.tisserand@epita.fr
Pascal Bart pascal.bart@epita.fr Noah Friedman friedman@gnu.org
Paul Eggert eggert@twinsun.com Pascal Bart pascal.bart@epita.fr
Paul Hilfinger Hilfinger@CS.Berkeley.EDU Paul Eggert eggert@twinsun.com
Per Allansson per@appgate.com Paul Hilfinger Hilfinger@CS.Berkeley.EDU
Peter Hámorský hamo@upjs.sk Per Allansson per@appgate.com
Piotr Gackiewicz gacek@intertel.com.pl Peter Hámorský hamo@upjs.sk
R Blake blakers@mac.com Piotr Gackiewicz gacek@intertel.com.pl
Raja R Harinath harinath@cs.umn.edu R Blake blakers@mac.com
Richard Stallman rms@gnu.org Raja R Harinath harinath@cs.umn.edu
Robert Anisko anisko_r@epita.fr Richard Stallman rms@gnu.org
Shura debil_urod@ngs.ru Robert Anisko anisko_r@epita.fr
Tim Josling tej@melbpc.org.au Shura debil_urod@ngs.ru
Tom Lane tgl@sss.pgh.pa.us Tim Josling tej@melbpc.org.au
Tom Tromey tromey@cygnus.com Tom Lane tgl@sss.pgh.pa.us
Wayne Green wayne@infosavvy.com Tom Tromey tromey@cygnus.com
Wolfram Wagner ww@mpi-sb.mpg.de Wayne Green wayne@infosavvy.com
Wwp subscript@free.fr Wolfram Wagner ww@mpi-sb.mpg.de
Zack Weinberg zack@codesourcery.com Wwp subscript@free.fr
Zack Weinberg zack@codesourcery.com
Many people are not named here because we lost track of them. We Many people are not named here because we lost track of them. We
thank them! Please, help us keeping this list up to date. thank them! Please, help us keeping this list up to date.

View File

@@ -169,10 +169,10 @@ typedef union b4_stype yystype;
typedef struct yyltype typedef struct yyltype
{ {
]b4_location_if([ ]b4_location_if([
int yyfirst_line; int first_line;
int yyfirst_column; int first_column;
int yylast_line; int last_line;
int yylast_column;])[ int last_column;])[
} yyltype; } yyltype;
# define YYLTYPE ]b4_ltype[ # define YYLTYPE ]b4_ltype[
# define YYLTYPE_IS_TRIVIAL 1 # define YYLTYPE_IS_TRIVIAL 1
@@ -333,7 +333,8 @@ static const ]b4_int_type_for([b4_pgoto])[ yypgoto[] =
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says. */ number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, parse error. */
#define YYTABLE_NINF ]b4_table_ninf[ #define YYTABLE_NINF ]b4_table_ninf[
static const ]b4_int_type_for([b4_table])[ yytable[] = static const ]b4_int_type_for([b4_table])[ yytable[] =
{ {
@@ -396,10 +397,10 @@ int yyparse (void);
#ifndef YYLLOC_DEFAULT #ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(yyCurrent, yyRhs, YYN) \ # define YYLLOC_DEFAULT(yyCurrent, yyRhs, YYN) \
yyCurrent.yyfirst_line = YYRHSLOC(yyRhs,1).yyfirst_line; \ yyCurrent.first_line = YYRHSLOC(yyRhs,1).first_line; \
yyCurrent.yyfirst_column = YYRHSLOC(yyRhs,1).yyfirst_column; \ yyCurrent.first_column = YYRHSLOC(yyRhs,1).first_column; \
yyCurrent.yylast_line = YYRHSLOC(yyRhs,YYN).yylast_line; \ yyCurrent.last_line = YYRHSLOC(yyRhs,YYN).last_line; \
yyCurrent.yylast_column = YYRHSLOC(yyRhs,YYN).yylast_column; yyCurrent.last_column = YYRHSLOC(yyRhs,YYN).last_column;
#endif #endif
/* YYLEX -- calling `yylex' with the right arguments. */ /* YYLEX -- calling `yylex' with the right arguments. */
@@ -705,16 +706,21 @@ yygetLRActions (yyStateNum yystate, int yytoken,
int* yyaction, const short** yyconflicts) int* yyaction, const short** yyconflicts)
{ {
int yyindex = yypact[yystate] + yytoken; int yyindex = yypact[yystate] + yytoken;
if (yyindex < 0 || yyindex > YYLAST || yycheck[yyindex] != yytoken) if (yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
{ {
*yyaction = -yydefact[yystate]; *yyaction = -yydefact[yystate];
*yyconflicts = yyconfl; *yyconflicts = yyconfl;
} }
else else if (yytable[yyindex] != YYTABLE_NINF)
{ {
*yyaction = yytable[yyindex]; *yyaction = yytable[yyindex];
*yyconflicts = yyconfl + yyconflp[yyindex]; *yyconflicts = yyconfl + yyconflp[yyindex];
} }
else
{
*yyaction = 0;
*yyconflicts = yyconfl + yyconflp[yyindex];
}
} }
static inline yyStateNum static inline yyStateNum
@@ -722,7 +728,7 @@ yyLRgotoState (yyStateNum yystate, yySymbol yylhs)
{ {
int yyr; int yyr;
yyr = yypgoto[yylhs - YYNTOKENS] + yystate; yyr = yypgoto[yylhs - YYNTOKENS] + yystate;
if (yyr >= 0 && yyr <= YYLAST && yycheck[yyr] == yystate) if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate)
return yytable[yyr]; return yytable[yyr];
else else
return yydefgoto[yylhs - YYNTOKENS]; return yydefgoto[yylhs - YYNTOKENS];
@@ -737,7 +743,7 @@ yyisShiftAction (int yyaction)
static inline bool static inline bool
yyisErrorAction (int yyaction) yyisErrorAction (int yyaction)
{ {
return yyaction == 0 || yyaction == YYPACT_NINF; return yyaction == 0;
} }
/* GLRStates */ /* GLRStates */
@@ -1256,7 +1262,7 @@ yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack,
} }
#if YYDEBUG #if YYDEBUG
static yyGLRState YYLEFTMOST_STATE = { 0, NULL, -1, 0, { NULL } }; static yyGLRState YYLEFTMOST_STATE = { 0, 0, -1, NULL, 0, { NULL } };
static void yyreportTree (yySemanticOption* yyx, int yyindent) static void yyreportTree (yySemanticOption* yyx, int yyindent)
{ {
@@ -1524,7 +1530,7 @@ yyreportParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
{ {
yyprefix = ", expecting "; yyprefix = ", expecting ";
for (yyx = yyn < 0 ? -yyn : 0; yyx < yytname_size; yyx += 1) for (yyx = yyn < 0 ? -yyn : 0; yyx < yytname_size; yyx += 1)
if (yycheck[yyx + yyn] == yyx) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{ {
yyp += sprintf (yyp, "%s%s", yyprefix, yytokenName (yyx)); yyp += sprintf (yyp, "%s%s", yyprefix, yytokenName (yyx));
yyprefix = " or "; yyprefix = " or ";
@@ -1540,13 +1546,9 @@ yyreportParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
} }
} }
/* Recover from a syntax error on STACK, assuming that TOKENP, /* Recover from a syntax error on YYSTACK, assuming that YYTOKENP,
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. */
NOTE: This uses the panic-mode recovery algorithm described in the
Bison documentation, which differs from what is in bison.simple.
Specifically, this routine performs no reductions before shifting
the error token. */
static void static void
yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp) yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
{ {
@@ -1855,10 +1857,10 @@ b4_location_if(
[#ifndef YYLTYPE [#ifndef YYLTYPE
typedef struct yyltype typedef struct yyltype
{ {
int yyfirst_line; int first_line;
int yyfirst_column; int first_column;
int yylast_line; int last_line;
int yylast_column; int last_column;
} yyltype; } yyltype;
# define YYLTYPE yyltype # define YYLTYPE yyltype
#endif #endif

View File

@@ -414,7 +414,8 @@ static const b4_int_type_for([b4_pgoto]) yypgoto[[]] =
/* YYTABLE[[YYPACT[STATE-NUM]]]. What to do in state STATE-NUM. If /* YYTABLE[[YYPACT[STATE-NUM]]]. What to do in state STATE-NUM. If
positive, shift that token. If negative, reduce the rule which positive, shift that token. If negative, reduce the rule which
number is the opposite. If zero, do what YYDEFACT says. */ number is the opposite. If zero, do what YYDEFACT says.
If YYTABLE_NINF, parse error. */
#define YYTABLE_NINF b4_table_ninf #define YYTABLE_NINF b4_table_ninf
static const b4_int_type_for([b4_table]) yytable[[]] = static const b4_int_type_for([b4_table]) yytable[[]] =
{ {
@@ -917,23 +918,22 @@ yybackup:
YYDPRINTF ((stderr, "\n")); YYDPRINTF ((stderr, "\n"));
} }
/* Set YYN to the action to take in STATE on seeing token YYCHAR1.
Result YYN means
- YYN < 0: Reduce on rule -YYN.
- YYN = 0: Error.
- YYN > 0: Shift to state YYN. */
yyn += yychar1; yyn += yychar1;
if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yychar1) if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yychar1)
goto yydefault; /* Defaulted action (reduction). */
yyn = -yydefact[yystate];
yyn = yytable[yyn]; else if (yytable[yyn] != YYTABLE_NINF)
yyn = yytable[yyn];
/* yyn is what to do for this token type in this state. else
Negative => reduce, -yyn is rule number. yyn = 0;
Positive => shift, yyn is new state.
New state is final state => don't bother to shift,
just return success.
0, or most negative number => error. */
if (yyn < 0) if (yyn < 0)
{ {
if (yyn == YYTABLE_NINF)
goto yyerrlab;
yyn = -yyn; yyn = -yyn;
goto yyreduce; goto yyreduce;
} }

View File

@@ -16,8 +16,6 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA. # 02111-1307, USA.
AT_BANNER([[Simple Calculator.]])
## ---------------------------------------------------- ## ## ---------------------------------------------------- ##
## Compile the grammar described in the documentation. ## ## Compile the grammar described in the documentation. ##
## ---------------------------------------------------- ## ## ---------------------------------------------------- ##
@@ -275,8 +273,8 @@ main (int argc, const char **argv)
# Produce `calc.y'. # Produce `calc.y'.
m4_define([AT_DATA_CALC_Y], m4_define([AT_DATA_CALC_Y],
[_AT_DATA_CALC_Y($[1], $[2], $[3], [_AT_DATA_CALC_Y($[1], $[2], $[3],
[m4_bmatch([$1], [--yyerror-verbose], [m4_bpatsubst([$1], [--[^ ]*])])
[[%error-verbose]])])]) ])
@@ -284,17 +282,22 @@ m4_define([AT_DATA_CALC_Y],
# ------------------------------------------------------------ # ------------------------------------------------------------
# Run `calc' on INPUT and expect no STDOUT nor STDERR. # Run `calc' on INPUT and expect no STDOUT nor STDERR.
# #
# If BISON-OPTIONS contains `--debug', then NUM-STDERR-LINES is the number # If BISON-OPTIONS contains `%debug' but not `%glr-parser', then
# of expected lines on stderr. # NUM-STDERR-LINES is the number of expected lines on stderr.
#
# We don't count GLR's traces yet, since its traces are somewhat
# different from LALR's.
m4_define([_AT_CHECK_CALC], m4_define([_AT_CHECK_CALC],
[AT_DATA([[input]], [AT_DATA([[input]],
[[$2 [[$2
]]) ]])
AT_PARSER_CHECK([./calc input], 0, [], [stderr])dnl AT_PARSER_CHECK([./calc input], 0, [], [stderr])
AT_CHECK([wc -l <stderr | sed 's/[[^0-9]]//g'], 0, m4_bmatch([$1],
[m4_bmatch([$1], [--debug], [%debug.*%glr\|%glr.*%debug],
[$3], [0]) [],
]) [%debug],
[AT_CHECK([wc -l <stderr | sed 's/[[^0-9]]//g'], 0, [$3
])])
]) ])
@@ -309,12 +312,12 @@ AT_CHECK([wc -l <stderr | sed 's/[[^0-9]]//g'], 0,
# If BISON-OPTIONS contains `--location', then make sure the ERROR-LOCATION # If BISON-OPTIONS contains `--location', then make sure the ERROR-LOCATION
# is correctly output on stderr. # is correctly output on stderr.
# #
# If BISON-OPTIONS contains `--yyerror-verbose', then make sure the # If BISON-OPTIONS contains `%error-verbose', then make sure the
# IF-YYERROR-VERBOSE message is properly output after `parse error, ' # IF-YYERROR-VERBOSE message is properly output after `parse error, '
# on STDERR. # on STDERR.
# #
# If BISON-OPTIONS contains `--debug', then NUM-STDERR-LINES is the number # If BISON-OPTIONS contains `%debug' but not `%glr', then NUM-STDERR-LINES
# of expected lines on stderr. # is the number of expected lines on stderr.
m4_define([_AT_CHECK_CALC_ERROR], m4_define([_AT_CHECK_CALC_ERROR],
[m4_bmatch([$2], [^/], [m4_bmatch([$2], [^/],
[AT_PARSER_CHECK([./calc $2], 0, [], [stderr])], [AT_PARSER_CHECK([./calc $2], 0, [], [stderr])],
@@ -322,9 +325,11 @@ m4_define([_AT_CHECK_CALC_ERROR],
[[$2 [[$2
]]) ]])
AT_PARSER_CHECK([./calc input], 0, [], [stderr])]) AT_PARSER_CHECK([./calc input], 0, [], [stderr])])
m4_bmatch([$1],
m4_bmatch([$1], [--debug], [%debug.*%glr\|%glr.*%debug],
[AT_CHECK([wc -l <stderr | sed 's/[[^0-9]]//g'], 0, [$3 [],
[%debug],
[AT_CHECK([wc -l <stderr | sed 's/[[^0-9]]//g'], 0, [$3
])]) ])])
# Normalize the observed and expected error messages, depending upon the # Normalize the observed and expected error messages, depending upon the
@@ -332,6 +337,7 @@ m4_bmatch([$1], [--debug],
# 1. Remove the traces from observed. # 1. Remove the traces from observed.
sed '/^Starting/d sed '/^Starting/d
/^Entering/d /^Entering/d
/^Stack/d
/^Reading/d /^Reading/d
/^Reducing/d /^Reducing/d
/^Shifting/d /^Shifting/d
@@ -350,7 +356,7 @@ m4_bmatch([$1], [--location], [],
[[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.
m4_bmatch([$1], [--yyerror-verbose], [], m4_bmatch([$1], [%error-verbose], [],
[[sed 's/parse error, .*$/parse error/' expout >at-expout [[sed 's/parse error, .*$/parse error/' expout >at-expout
mv at-expout expout]]) mv at-expout expout]])
# 5. Check # 5. Check
@@ -358,8 +364,8 @@ AT_CHECK([cat stderr], 0, [expout])
]) ])
# AT_CHECK_CALC([BISON-OPTIONS], [PARSER-EXPECTED-STDERR]) # AT_CHECK_CALC([BISON-OPTIONS])
# -------------------------------------------------------- # ------------------------------
# Start a testing chunk which compiles `calc' grammar with # Start a testing chunk which compiles `calc' grammar with
# BISON-OPTIONS, and performs several tests over the parser. # BISON-OPTIONS, and performs several tests over the parser.
m4_define([AT_CHECK_CALC], m4_define([AT_CHECK_CALC],
@@ -369,7 +375,7 @@ AT_SETUP([Calculator $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.
AT_CHECK([bison calc.y -o calc.c m4_bpatsubst([$1], [--yyerror-verbose])], AT_CHECK([bison calc.y -o calc.c m4_bpatsubst([$1], [%[^ ]*])],
[0], [], []) [0], [], [])
AT_COMPILE([calc]) AT_COMPILE([calc])
@@ -427,22 +433,62 @@ AT_CLEANUP
# ------------------ # # ------------------------ #
# Test the parsers. # # Simple LALR Calculator. #
# ------------------ # # ------------------------ #
AT_CHECK_CALC() AT_BANNER([[Simple LALR Calculator.]])
AT_CHECK_CALC([--defines]) # AT_CHECK_CALC_LALR([BISON-OPTIONS])
AT_CHECK_CALC([--locations]) # -----------------------------------
AT_CHECK_CALC([--name-prefix=calc]) # Start a testing chunk which compiles `calc' grammar with
AT_CHECK_CALC([--verbose]) # BISON-OPTIONS, and performs several tests over the parser.
AT_CHECK_CALC([--yacc]) m4_define([AT_CHECK_CALC_LALR],
AT_CHECK_CALC([--yyerror-verbose]) [AT_CHECK_CALC($@)])
AT_CHECK_CALC([--locations --yyerror-verbose]) AT_CHECK_CALC_LALR()
AT_CHECK_CALC([--defines --locations --name-prefix=calc --verbose --yacc --yyerror-verbose]) AT_CHECK_CALC_LALR([--defines])
AT_CHECK_CALC_LALR([--locations])
AT_CHECK_CALC_LALR([--name-prefix=calc])
AT_CHECK_CALC_LALR([--verbose])
AT_CHECK_CALC_LALR([--yacc])
AT_CHECK_CALC_LALR([%error-verbose])
AT_CHECK_CALC([--debug]) AT_CHECK_CALC_LALR([%error-verbose --locations])
AT_CHECK_CALC([--debug --defines --locations --name-prefix=calc --verbose --yacc --yyerror-verbose])
AT_CHECK_CALC_LALR([%error-verbose --defines --locations --name-prefix=calc --verbose --yacc])
AT_CHECK_CALC_LALR([%debug])
AT_CHECK_CALC_LALR([%error-verbose %debug --defines --locations --name-prefix=calc --verbose --yacc])
# ----------------------- #
# Simple GLR Calculator. #
# ----------------------- #
AT_BANNER([[Simple GLR Calculator.]])
# AT_CHECK_CALC_GLR([BISON-OPTIONS])
# ----------------------------------
# Start a testing chunk which compiles `calc' grammar with
# BISON-OPTIONS and %glr-parser, and performs several tests over the parser.
m4_define([AT_CHECK_CALC_GLR],
[AT_CHECK_CALC([%glr_parser] $@)])
AT_CHECK_CALC_GLR()
AT_CHECK_CALC_GLR([--defines])
AT_CHECK_CALC_GLR([--locations])
AT_CHECK_CALC_GLR([--name-prefix=calc])
AT_CHECK_CALC_GLR([--verbose])
AT_CHECK_CALC_GLR([--yacc])
AT_CHECK_CALC_GLR([%error-verbose])
AT_CHECK_CALC_GLR([%error-verbose --locations])
AT_CHECK_CALC_GLR([%error-verbose --defines --locations --name-prefix=calc --verbose --yacc])
AT_CHECK_CALC_GLR([%debug])
AT_CHECK_CALC_GLR([%error-verbose %debug --defines --locations --name-prefix=calc --verbose --yacc])