* src/muscle_tab.c (muscle_grow): Remove trailing debugging code.

* data/glr.c (YY_USER_FORMALS, YY_USER_ARGS): New.
(yyuserAction, yydoAction, yyglrReduce, yyresolveValue)
(yyresolveStates, yyresolveAction, yyresolveStack)
(yyprocessOneStack): Use them.
(yy_reduce_print): New.
* tests/calc.at (_AT_DATA_CALC_Y): Exercise %parse-param.
This commit is contained in:
Akim Demaille
2002-10-20 16:09:47 +00:00
parent 0245f82d31
commit e7cb57c0b8
4 changed files with 101 additions and 57 deletions

View File

@@ -1,3 +1,13 @@
2002-10-20 Akim Demaille <akim@epita.fr>
* src/muscle_tab.c (muscle_grow): Remove trailing debugging code.
* data/glr.c (YY_USER_FORMALS, YY_USER_ARGS): New.
(yyuserAction, yydoAction, yyglrReduce, yyresolveValue)
(yyresolveStates, yyresolveAction, yyresolveStack)
(yyprocessOneStack): Use them.
(yy_reduce_print): New.
* tests/calc.at (_AT_DATA_CALC_Y): Exercise %parse-param.
2002-10-20 Akim Demaille <akim@epita.fr> 2002-10-20 Akim Demaille <akim@epita.fr>
* data/c.m4 (b4_c_ansi_args): Recognize functions with no * data/c.m4 (b4_c_ansi_args): Recognize functions with no

View File

@@ -383,9 +383,16 @@ 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)
/* Error token number */ m4_ifset([b4_parse_param],
[#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
@@ -581,7 +588,8 @@ yytokenName (yySymbol yytoken)
* yyerr for YYERROR, yyabort for YYABORT. */ * yyerr for YYERROR, yyabort for YYABORT. */
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)
{ {
/* Avoid `unused' warnings in there are no $n. */ /* Avoid `unused' warnings in there are no $n. */
(void) yystack; (void) yystack;
@@ -983,7 +991,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) YYSTYPE* yyvalp, YYLTYPE* yylocp YY_USER_FORMALS)
{ {
int yynrhs = yyrhsLength (yyrule); int yynrhs = yyrhsLength (yyrule);
@@ -1005,7 +1013,8 @@ yydoAction (yyGLRStack* yystack, int yyk, yyRuleNum yyrule,
*yyvalp = rhs[1-yynrhs].yystate.yysemantics.yysval; *yyvalp = rhs[1-yynrhs].yystate.yysemantics.yysval;
*yylocp = rhs[1-yynrhs].yystate.yyloc; *yylocp = rhs[1-yynrhs].yystate.yyloc;
} }
return yyuserAction (yyrule, yynrhs, rhs, yyvalp, yylocp, yystack); return yyuserAction (yyrule, yynrhs, rhs,
yyvalp, yylocp, yystack YY_USER_ARGS);
} }
else else
{ {
@@ -1033,10 +1042,36 @@ 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); yyvalp, yylocp, yystack YY_USER_ARGS);
} }
} }
#if !YYDEBUG
# define YY_REDUCE_PRINT(K, Rule)
#else
# define YY_REDUCE_PRINT(K, Rule) \
do { \
if (yydebug) \
yy_reduce_print (K, Rule); \
} while (0)
/*----------------------------------------------------------.
| Report that the RULE is going to be reduced on stack #K. |
`----------------------------------------------------------*/
static inline void
yy_reduce_print (size_t yyk, yyRuleNum yyrule)
{
int yyi;
YYDPRINTF ((stderr, "Reducing stack %d by rule %d (line %d),",
yyk, yyrule - 1, yyrline[yyrule]));
/* Print the symbols being reduced, and their result. */
for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
YYFPRINTF (stderr, "%s ", yytokenName (yyrhs[yyi]));
YYFPRINTF (stderr, " -> %s\n", yytokenName (yyr1[yyrule]));
}
#endif
/** Pop items off stack #K of STACK according to grammar rule RULE, /** Pop items off stack #K of STACK according to grammar rule RULE,
* and push back on the resulting nonterminal symbol. Perform the * and push back on the resulting nonterminal symbol. Perform the
* semantic action associated with RULE and store its value with the * semantic action associated with RULE and store its value with the
@@ -1050,7 +1085,7 @@ yydoAction (yyGLRStack* yystack, int 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) bool yyforceEval YY_USER_FORMALS)
{ {
size_t yyposn = yystack->yytops.yystates[yyk]->yyposn; size_t yyposn = yystack->yytops.yystates[yyk]->yyposn;
@@ -1059,19 +1094,8 @@ yyglrReduce (yyGLRStack* yystack, size_t yyk, yyRuleNum yyrule,
YYSTYPE yysval; YYSTYPE yysval;
YYLTYPE yyloc; YYLTYPE yyloc;
#if YYDEBUG YY_REDUCE_PRINT (yyk, yyrule);
if (yydebug) YYCHK (yydoAction (yystack, yyk, yyrule, &yysval, &yyloc YY_USER_ARGS));
{
int yyi;
YYDPRINTF ((stderr, "Reducing stack %d by rule %d (line %d),",
yyk, yyrule - 1, yyrline[yyrule]));
/* Print the symbols being reduced, and their result. */
for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
YYFPRINTF (stderr, "%s ", yytokenName (yyrhs[yyi]));
YYFPRINTF (stderr, " -> %s\n", yytokenName (yyr1[yyrule]));
}
#endif
YYCHK (yydoAction (yystack, yyk, yyrule, &yysval, &yyloc));
yyglrShift (yystack, yyk, yyglrShift (yystack, yyk,
yyLRgotoState (yystack->yytops.yystates[yyk]->yylrState, yyLRgotoState (yystack->yytops.yystates[yyk]->yylrState,
yylhsNonterm (yyrule)), yylhsNonterm (yyrule)),
@@ -1217,22 +1241,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); YYLTYPE* yylocp YY_USER_FORMALS);
static YYRESULTTAG static YYRESULTTAG
yyresolveStates (yyGLRState* yys, int yyn, yyGLRStack* yystack) yyresolveStates (yyGLRState* yys, int yyn, yyGLRStack* yystack YY_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); yyflag = yyresolveStates (yys->yypred, yyn-1, yystack YY_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);
if (yyflag != yyok) if (yyflag != yyok)
return yyflag; return yyflag;
yys->yyresolved = yytrue; yys->yyresolved = yytrue;
@@ -1243,14 +1268,14 @@ yyresolveStates (yyGLRState* yys, int yyn, yyGLRStack* yystack)
static YYRESULTTAG static YYRESULTTAG
yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack, yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack,
YYSTYPE* yyvalp, YYLTYPE* yylocp) YYSTYPE* yyvalp, YYLTYPE* yylocp YY_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)); YYCHK (yyresolveStates (yyopt->yystate, yynrhs, yystack YY_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)
{ {
@@ -1260,7 +1285,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); yyvalp, yylocp, yystack YY_USER_ARGS);
} }
#if YYDEBUG #if YYDEBUG
@@ -1275,7 +1300,8 @@ static yyGLRState YYLEFTMOST_STATE =
} }
}; };
static void yyreportTree (yySemanticOption* yyx, int yyindent) static void
yyreportTree (yySemanticOption* yyx, int yyindent)
{ {
int yynrhs = yyrhsLength (yyx->yyrule); int yynrhs = yyrhsLength (yyx->yyrule);
int yyi; int yyi;
@@ -1339,7 +1365,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) YYSTYPE* yyvalp, YYLTYPE* yylocp YY_USER_FORMALS)
{ {
yySemanticOption* yybest; yySemanticOption* yybest;
yySemanticOption* yyp; yySemanticOption* yyp;
@@ -1372,25 +1398,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)); YYCHK (yyresolveAction (yybest, yystack, yyvalp, yylocp YY_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)); YYCHK (yyresolveAction (yyp, yystack, &yyval1, &yydummy YY_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); return yyresolveAction (yybest, yystack, yyvalp, yylocp YY_USER_ARGS);
} }
static YYRESULTTAG static YYRESULTTAG
yyresolveStack (yyGLRStack* yystack) yyresolveStack (yyGLRStack* yystack YY_USER_FORMALS)
{ {
if (yystack->yysplitPoint != NULL) if (yystack->yysplitPoint != NULL)
{ {
@@ -1401,7 +1427,8 @@ yyresolveStack (yyGLRStack* yystack)
yys != yystack->yysplitPoint; yys != yystack->yysplitPoint;
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));
} }
return yyok; return yyok;
} }
@@ -1438,7 +1465,8 @@ 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)
{ {
int yyaction; int yyaction;
const short* yyconflicts; const short* yyconflicts;
@@ -1459,7 +1487,7 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk,
yymarkStackDeleted (yystack, yyk); yymarkStackDeleted (yystack, yyk);
return yyok; return yyok;
} }
YYCHK (yyglrReduce (yystack, yyk, yyrule, yyfalse)); YYCHK (yyglrReduce (yystack, yyk, yyrule, yyfalse YY_USER_ARGS));
} }
else else
{ {
@@ -1478,9 +1506,10 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk,
int yynewStack = yysplitStack (yystack, yyk); int yynewStack = yysplitStack (yystack, 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, *yyconflicts, yyfalse)); YYCHK (yyglrReduce (yystack, yynewStack,
*yyconflicts, yyfalse YY_USER_ARGS));
YYCHK (yyprocessOneStack (yystack, yynewStack, yyposn, YYCHK (yyprocessOneStack (yystack, yynewStack, yyposn,
yylvalp, yyllocp)); yylvalp, yyllocp YY_USER_ARGS));
yyconflicts += 1; yyconflicts += 1;
} }
@@ -1500,7 +1529,7 @@ yyprocessOneStack (yyGLRStack* yystack, int yyk,
break; break;
} }
else else
YYCHK (yyglrReduce (yystack, yyk, -yyaction, yyfalse)); YYCHK (yyglrReduce (yystack, yyk, -yyaction, yyfalse YY_USER_ARGS));
} }
} }
return yyok; return yyok;
@@ -1704,7 +1733,7 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
yyreportParseError (&yystack, yylvalp, yyllocp); yyreportParseError (&yystack, yylvalp, yyllocp);
goto yyuser_error; goto yyuser_error;
} }
YYCHK1 (yyglrReduce (&yystack, 0, yyrule, yytrue)); YYCHK1 (yyglrReduce (&yystack, 0, yyrule, yytrue YY_USER_ARGS));
} }
else else
{ {
@@ -1738,7 +1767,7 @@ yyrecoverParseError (yyGLRStack* yystack, YYSTYPE* yylvalp, YYLTYPE* yyllocp)
goto yyuser_error; goto yyuser_error;
} }
else else
YYCHK1 (yyglrReduce (&yystack, 0, -yyaction, yytrue)); YYCHK1 (yyglrReduce (&yystack, 0, -yyaction, yytrue YY_USER_ARGS));
} }
} }
@@ -1748,7 +1777,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)); yylvalp, yyllocp YY_USER_ARGS));
yytoken = YYEMPTY; yytoken = YYEMPTY;
yyposn += 1; yyposn += 1;
yyremoveDeletes (&yystack); yyremoveDeletes (&yystack);
@@ -1757,14 +1786,14 @@ 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, "parse error");
YYCHK1 (yyresolveStack (&yystack)); YYCHK1 (yyresolveStack (&yystack YY_USER_ARGS));
YYDPRINTF ((stderr, "Returning to deterministic operation.\n")); YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
yyreportParseError (&yystack, yylvalp, yyllocp); yyreportParseError (&yystack, yylvalp, yyllocp);
goto yyuser_error; goto yyuser_error;
} }
else if (yystack.yytops.yysize == 1) else if (yystack.yytops.yysize == 1)
{ {
YYCHK1 (yyresolveStack (&yystack)); YYCHK1 (yyresolveStack (&yystack YY_USER_ARGS));
YYDPRINTF ((stderr, "Returning to deterministic operation.\n")); YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
yycompressStack (&yystack); yycompressStack (&yystack);
break; break;
@@ -1850,7 +1879,6 @@ yypdumpstack (yyGLRStack* yystack)
(long) YYINDEX (yystack->yytops.yystates[yyi])); (long) YYINDEX (yystack->yytops.yystates[yyi]));
fprintf (stderr, "\n"); fprintf (stderr, "\n");
} }
] ]
b4_epilogue b4_epilogue

View File

@@ -139,7 +139,6 @@ muscle_grow (const char *key, const char *val, const char *separator)
{ {
/* Grow the current value. */ /* Grow the current value. */
char *new_val; char *new_val;
fprintf (stderr, "<= %s + %s\n", entry->value, val);
obstack_sgrow (&muscle_obstack, entry->value); obstack_sgrow (&muscle_obstack, entry->value);
free (entry->value); free (entry->value);
obstack_sgrow (&muscle_obstack, separator); obstack_sgrow (&muscle_obstack, separator);
@@ -147,7 +146,6 @@ muscle_grow (const char *key, const char *val, const char *separator)
obstack_1grow (&muscle_obstack, 0); obstack_1grow (&muscle_obstack, 0);
new_val = obstack_finish (&muscle_obstack); new_val = obstack_finish (&muscle_obstack);
entry->value = xstrdup (new_val); entry->value = xstrdup (new_val);
fprintf (stderr, "=> %s\n", new_val);
obstack_free (&muscle_obstack, new_val); obstack_free (&muscle_obstack, new_val);
} }
} }

View File

@@ -53,14 +53,21 @@ AT_DATA([calc.y],
char *strcat(char *dest, const char *src); char *strcat(char *dest, const char *src);
#endif #endif
#include <ctype.h> #include <ctype.h>
#include <assert.h>
extern void perror (const char *s); extern void perror (const char *s);
/* Exercise pre-prologue dependency to %union. */ /* Exercise pre-prologue dependency to %union. */
typedef int value_t; typedef int value_t;
value_t global_result = 0;
int global_count = 0;
%} %}
%parse-param "value_t *result", "result"
%parse-param "int *count", "count"
/* Exercise %union. */ /* Exercise %union. */
%union %union
{ {
@@ -120,12 +127,12 @@ static void yyungetc (LEX_PRE_FORMALS int c);
%% %%
input: input:
line line
| input line | input line { ++*count; ++global_count; }
; ;
line: line:
'\n' '\n'
| exp '\n' | exp '\n' { *result = global_result = $1; }
; ;
exp: exp:
@@ -134,7 +141,7 @@ 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 == $3; $$ = $1;
} }
| exp '+' exp { $$ = $1 + $3; } | exp '+' exp { $$ = $1 + $3; }
| exp '-' exp { $$ = $1 - $3; } | exp '-' exp { $$ = $1 - $3; }
@@ -286,6 +293,8 @@ power (int base, int exponent)
int int
main (int argc, const char **argv) main (int argc, const char **argv)
{ {
value_t result = 0;
int count = 0;
yyin = NULL; yyin = NULL;
if (argc == 2) if (argc == 2)
@@ -302,7 +311,10 @@ main (int argc, const char **argv)
#if YYDEBUG #if YYDEBUG
yydebug = 1; yydebug = 1;
#endif #endif
yyparse (); yyparse (&result, &count);
assert (global_result == result);
assert (global_count == count);
return 0; return 0;
} }
]]) ]])
@@ -435,7 +447,8 @@ _AT_CHECK_CALC([$1],
1 - (2 - 3) = 2 1 - (2 - 3) = 2
2^2^3 = 256 2^2^3 = 256
(2^2)^3 = 64], [486]) (2^2)^3 = 64],
[486])
# Some parse errors. # Some parse errors.
_AT_CHECK_CALC_ERROR([$1], [0 0], [11], _AT_CHECK_CALC_ERROR([$1], [0 0], [11],
@@ -463,11 +476,6 @@ _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])
# Add a studid example demonstrating that Bison can further improve the
# error message. FIXME: Fix this ridiculous message.
_AT_CHECK_CALC_ERROR([$1], [()], [21],
[1.2-1.3: parse error, unexpected ')', expecting "number" or '-' or '('])
AT_CLEANUP AT_CLEANUP
])# AT_CHECK_CALC ])# AT_CHECK_CALC