* data/glr.c (YYERROR): Update definition.

(yyrecoverSyntaxError): Correct yyerrState logic. Correct comment.
Allow states with only a default reduction.

Fixes to avoid problem that $-N rules in GLR parsers can cause
buffer overruns, corrupting state.

* src/output.c (prepare_rules): Output max_left_semantic_context.
* src/reader.h (max_left_semantic_context): New
* src/scan-gram.l (max_left_semantic_context): Define.
(handle_action_dollar): Update max_left_semantic_context.
* data/glr.c (YYMAXLEFT): New.
(yydoAction): Increase yyrhsVals size.
(yyresolveAction): Ditto.

Fixes to problems with location handling in GLR parsers reported by
Frank Heckenbach (2003/06/05).

* data/glr.c (YYLTYPE): Make trivial if locations not used.
(YYRHSLOC): Add parentheses, make depend on whether locations used.
(YYLLOC_DEFAULT): Ditto.
(yyuserAction): Use YYLLOC_DEFAULT.
(yydoAction): Remove redundant code.

* tests/cxx-type.at: Exercise location information.
(yylex): Track locations.
(stmtMerge): Return value rather than printing.
This commit is contained in:
Paul Hilfinger
2003-06-10 02:44:58 +00:00
parent 144c1e767a
commit 25005f6ab0
6 changed files with 240 additions and 144 deletions

View File

@@ -1,3 +1,46 @@
2003-06-09 Paul Hilfinger <Hilfinger@CS.Berkeley.EDU>
* data/glr.c (YYERROR): Update definition to reset yyerrState to 0
first.
(yyrecoverSyntaxError): Correct the logic for setting and testing
yyerrState.
Correct comment on handling EOF.
Allow states with only a default reduction, rather than failing
(I can't quite reconstruct why these were not allowed before).
Fixes to avoid problem that $-N rules in GLR parsers can cause
buffer overruns, corrupting state.
* src/output.c (prepare_rules): Output max_left_semantic_context
definition.
* src/reader.h (max_left_semantic_context): New variable declaration.
* src/scan-gram.l (max_left_semantic_context): Define.
(handle_action_dollar): Update max_left_semantic_context.
* data/glr.c (YYMAXLEFT): New definition.
(yydoAction): Increase size of yyrhsVals by YYMAXLEFT.
(yyresolveAction): Ditto.
Fixes to problems with location handling in GLR parsers reported by
Frank Heckenbach (2003/06/05).
* data/glr.c (YYLTYPE): Make trivial if locations not used.
(YYRHSLOC): Add parentheses, and define only if locations used.
(YYLLOC_DEFAULT): Add parentheses, and give trivial definition if
locations not used.
(yyuserAction): Use YYLLOC_DEFAULT to set *yylocp.
(yydoAction): Remove redundant initialization of *yyvalp and *yylocp.
* tests/cxx-type.at: Exercise location information; update tests
to differentiate output with and without locations.
Remove forward declarations of yylex and yyerror---caused errors
because default YYLTYPE not yet defined.
Change semantic actions to compute strings, rather than printing
them directly (to test proper passing of semantics values). Change
output to prefix notation and update test data and expected results.
(yylex): Track locations.
(stmtMerge): Return value rather than printing, and include arguments
in value.
2003-06-03 Paul Eggert <eggert@twinsun.com> 2003-06-03 Paul Eggert <eggert@twinsun.com>
Avoid warnings generated by GCC 2.95.4 when Bison is Avoid warnings generated by GCC 2.95.4 when Bison is

View File

@@ -192,10 +192,12 @@ b4_syncline([@oline@], [@ofile@])],
#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED) #if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
typedef struct YYLTYPE typedef struct YYLTYPE
{ {
]b4_location_if([
int first_line; int first_line;
int first_column; int first_column;
int last_line; int last_line;
int last_column; int last_column;
])[
} YYLTYPE; } YYLTYPE;
# define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1 # define YYLTYPE_IS_TRIVIAL 1
@@ -254,6 +256,9 @@ b4_syncline([@oline@], [@ofile@])
#define YYNSTATES ]b4_states_number[ #define YYNSTATES ]b4_states_number[
/* YYMAXRHS -- Maximum number of symbols on right-hand side of rule. */ /* YYMAXRHS -- Maximum number of symbols on right-hand side of rule. */
#define YYMAXRHS ]b4_r2_max[ #define YYMAXRHS ]b4_r2_max[
/* YYMAXLEFT -- Maximum number of symbols to the left of a handle
accessed by $0, $-1, etc., in any rule. */
#define YYMAXLEFT ]b4_max_left_semantic_context[
/* YYTRANSLATE(X) -- Bison symbol number corresponding to X. */ /* YYTRANSLATE(X) -- Bison symbol number corresponding to X. */
#define YYUNDEFTOK ]b4_undef_token_number[ #define YYUNDEFTOK ]b4_undef_token_number[
@@ -402,15 +407,22 @@ static const ]b4_int_type_for([b4_stos])[ yystos[] =
/* YYLLOC_DEFAULT -- Compute the default location (before the actions /* YYLLOC_DEFAULT -- Compute the default location (before the actions
are run). */ are run). */
#define YYRHSLOC(yyRhs,YYK) (yyRhs[YYK].yystate.yyloc) ]b4_location_if([[
#define YYRHSLOC(yyRhs,YYK) ((yyRhs)[YYK].yystate.yyloc)
#ifndef YYLLOC_DEFAULT #ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(yyCurrent, yyRhs, YYN) \ # define YYLLOC_DEFAULT(yyCurrent, yyRhs, YYN) \
yyCurrent.first_line = YYRHSLOC(yyRhs,1).first_line; \ (yyCurrent).first_line = YYRHSLOC(yyRhs,1).first_line; \
yyCurrent.first_column = YYRHSLOC(yyRhs,1).first_column; \ (yyCurrent).first_column = YYRHSLOC(yyRhs,1).first_column; \
yyCurrent.last_line = YYRHSLOC(yyRhs,YYN).last_line; \ (yyCurrent).last_line = YYRHSLOC(yyRhs,YYN).last_line; \
yyCurrent.last_column = YYRHSLOC(yyRhs,YYN).last_column; (yyCurrent).last_column = YYRHSLOC(yyRhs,YYN).last_column;
#endif #endif
]],[
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(yyCurrent, yyRhs, YYN)
#endif
])[
/* YYLEX -- calling `yylex' with the right arguments. */ /* YYLEX -- calling `yylex' with the right arguments. */
#define YYLEX ]b4_c_function_call([yylex], [int], b4_lex_param)[ #define YYLEX ]b4_c_function_call([yylex], [int], b4_lex_param)[
@@ -663,16 +675,6 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
yybool yynormal ATTRIBUTE_UNUSED = (yystack->yysplitPoint == NULL); yybool yynormal ATTRIBUTE_UNUSED = (yystack->yysplitPoint == NULL);
int yylow; int yylow;
if (yyrhslen == 0)
{
*yyvalp = yyval_default;
*yylocp = yyloc_default;
}
else
{
*yyvalp = yyvsp[1-yyrhslen].yystate.yysemantics.yysval;
*yylocp = yyvsp[1-yyrhslen].yystate.yyloc;
}
# undef yyerrok # undef yyerrok
# define yyerrok (yystack->yyerrState = 0) # define yyerrok (yystack->yyerrState = 0)
# undef YYACCEPT # undef YYACCEPT
@@ -680,7 +682,7 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
# undef YYABORT # undef YYABORT
# define YYABORT return yyabort # define YYABORT return yyabort
# undef YYERROR # undef YYERROR
# define YYERROR return yyerr # define YYERROR do { yystack->yyerrState = 0; return yyerr; } while (0)
# undef YYRECOVERING # undef YYRECOVERING
# define YYRECOVERING (yystack->yyerrState != 0) # define YYRECOVERING (yystack->yyerrState != 0)
# undef yyclearin # undef yyclearin
@@ -694,14 +696,25 @@ yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
YYERROR; \ YYERROR; \
} while (0) } while (0)
] yylow = 1;
yylow = 1; if (yyrhslen == 0)
switch (yyn) {
{ *yyvalp = yyval_default;
b4_actions *yylocp = yyloc_default;
} }
else
{
*yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yysval;
YYLLOC_DEFAULT (*yylocp, yyvsp - yyrhslen, yyrhslen);
}
return yyok; ]
switch (yyn)
{
b4_actions
}
return yyok;
# undef yyerrok # undef yyerrok
# undef YYABORT # undef YYABORT
# undef YYACCEPT # undef YYACCEPT
@@ -1080,16 +1093,6 @@ yydoAction (yyGLRStack* yystack, int yyk, yyRuleNum yyrule,
yystack->yynextFree -= yynrhs; yystack->yynextFree -= yynrhs;
yystack->yyspaceLeft += yynrhs; yystack->yyspaceLeft += yynrhs;
yystack->yytops.yystates[0] = & yystack->yynextFree[-1].yystate; yystack->yytops.yystates[0] = & yystack->yynextFree[-1].yystate;
if (yynrhs == 0)
{
*yyvalp = yyval_default;
*yylocp = yyloc_default;
}
else
{
*yyvalp = rhs[1-yynrhs].yystate.yysemantics.yysval;
*yylocp = rhs[1-yynrhs].yystate.yyloc;
}
return yyuserAction (yyrule, yynrhs, rhs, return yyuserAction (yyrule, yynrhs, rhs,
yyvalp, yylocp, yystack]b4_user_args[); yyvalp, yylocp, yystack]b4_user_args[);
} }
@@ -1097,8 +1100,9 @@ yydoAction (yyGLRStack* yystack, int yyk, yyRuleNum yyrule,
{ {
int yyi; int yyi;
yyGLRState* yys; yyGLRState* yys;
yyGLRStackItem yyrhsVals[YYMAXRHS+1]; yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
yys = yyrhsVals[YYMAXRHS].yystate.yypred = yystack->yytops.yystates[yyk]; yys = yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred
= yystack->yytops.yystates[yyk];
for (yyi = 0; yyi < yynrhs; yyi += 1) for (yyi = 0; yyi < yynrhs; yyi += 1)
{ {
yys = yys->yypred; yys = yys->yypred;
@@ -1107,17 +1111,7 @@ yydoAction (yyGLRStack* yystack, int yyk, yyRuleNum yyrule,
} }
yyupdateSplit (yystack, yys); yyupdateSplit (yystack, yys);
yystack->yytops.yystates[yyk] = yys; yystack->yytops.yystates[yyk] = yys;
if (yynrhs == 0) return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
{
*yyvalp = yyval_default;
*yylocp = yyloc_default;
}
else
{
*yyvalp = yyrhsVals[1].yystate.yysemantics.yysval;
*yylocp = yyrhsVals[1].yystate.yyloc;
}
return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS - 1,
yyvalp, yylocp, yystack]b4_user_args[); yyvalp, yylocp, yystack]b4_user_args[);
} }
} }
@@ -1348,13 +1342,14 @@ static YYRESULTTAG
yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack, yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack,
YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[) YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
{ {
yyGLRStackItem yyrhsVals[YYMAXRHS+1]; yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
int yynrhs; int yynrhs;
yynrhs = yyrhsLength (yyopt->yyrule); yynrhs = yyrhsLength (yyopt->yyrule);
YYCHK (yyresolveStates (yyopt->yystate, yynrhs, yystack]b4_user_args[)); YYCHK (yyresolveStates (yyopt->yystate, yynrhs, yystack]b4_user_args[));
yyrhsVals[YYMAXRHS].yystate.yypred = yyopt->yystate; yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred = yyopt->yystate;
return yyuserAction (yyopt->yyrule, yynrhs, yyrhsVals + YYMAXRHS - 1, return yyuserAction (yyopt->yyrule, yynrhs,
yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
yyvalp, yylocp, yystack]b4_user_args[); yyvalp, yylocp, yystack]b4_user_args[);
} }
@@ -1687,17 +1682,14 @@ yyrecoverSyntaxError (yyGLRStack* yystack,
size_t yyk; size_t yyk;
int yyj; int yyj;
if (yystack->yyerrState == 0) if (yystack->yyerrState == 3)
yystack->yyerrState = 3;
else if (yystack->yyerrState == 3)
/* We just shifted the error token and (perhaps) took some /* We just shifted the error token and (perhaps) took some
reductions. Skip tokens until we can proceed. */ reductions. Skip tokens until we can proceed. */
while (yytrue) while (yytrue)
{ {
if (*yytokenp == YYEOF) if (*yytokenp == YYEOF)
{ {
/* Now pop stack until we find a state that shifts the /* Now pop stack until empty and fail. */
error token. */
while (yystack->yytops.yystates[0] != NULL) while (yystack->yytops.yystates[0] != NULL)
{ {
yyGLRState *yys = yystack->yytops.yystates[0]; yyGLRState *yys = yystack->yytops.yystates[0];
@@ -1723,8 +1715,7 @@ yyrecoverSyntaxError (yyGLRStack* yystack,
YYDSYMPRINTF ("Next token is", *yytokenp, yylvalp, yyllocp); YYDSYMPRINTF ("Next token is", *yytokenp, yylvalp, yyllocp);
yyj = yypact[yystack->yytops.yystates[0]->yylrState]; yyj = yypact[yystack->yytops.yystates[0]->yylrState];
if (yyis_pact_ninf (yyj)) if (yyis_pact_ninf (yyj))
/* Something's not right; we shouldn't be here. */ return;
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)
{ {
@@ -1747,6 +1738,7 @@ yyrecoverSyntaxError (yyGLRStack* yystack,
yycompressStack (yystack); yycompressStack (yystack);
/* Now pop stack until we find a state that shifts the error token. */ /* Now pop stack until we find a state that shifts the error token. */
yystack->yyerrState = 3;
while (yystack->yytops.yystates[0] != NULL) while (yystack->yytops.yystates[0] != NULL)
{ {
yyGLRState *yys = yystack->yytops.yystates[0]; yyGLRState *yys = yystack->yytops.yystates[0];
@@ -2016,20 +2008,21 @@ b4_syncline([@oline@], [@ofile@])],
b4_pure_if([], b4_pure_if([],
[extern YYSTYPE b4_prefix[]lval;]) [extern YYSTYPE b4_prefix[]lval;])
b4_location_if( #if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
[#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
typedef struct YYLTYPE typedef struct YYLTYPE
{ {
b4_location_if([
int first_line; int first_line;
int first_column; int first_column;
int last_line; int last_line;
int last_column; int last_column;
])
} YYLTYPE; } YYLTYPE;
# define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1 # define YYLTYPE_IS_TRIVIAL 1
#endif #endif
m4_if(b4_pure, [0], b4_location_if([m4_if(b4_pure, [0],
[extern YYLTYPE b4_prefix[]lloc;]) [extern YYLTYPE b4_prefix[]lloc;])
]) ])
]) ])

View File

@@ -253,6 +253,7 @@ prepare_rules (void)
muscle_insert_short_table ("merger", merger, 0, 0, nrules); muscle_insert_short_table ("merger", merger, 0, 0, nrules);
MUSCLE_INSERT_INT ("rules_number", nrules); MUSCLE_INSERT_INT ("rules_number", nrules);
MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context);
free (rhs); free (rhs);
free (prhs); free (prhs);

View File

@@ -38,6 +38,7 @@ typedef struct merger_list
extern FILE *gram_in; extern FILE *gram_in;
extern int gram__flex_debug; extern int gram__flex_debug;
extern boundary scanner_cursor; extern boundary scanner_cursor;
extern int max_left_semantic_context;
void scanner_initialize (void); void scanner_initialize (void);
void scanner_free (void); void scanner_free (void);
void scanner_last_string_free (void); void scanner_last_string_free (void);

View File

@@ -649,6 +649,11 @@ splice (\\[ \f\t\v]*\n)*
%% %%
/* Keeps track of the maximum number of semantic values to the left of
a handle (those referenced by $0, $-1, etc.) are required by the
semantic actions of this grammar. */
int max_left_semantic_context = 0;
/* Set *LOC and adjust scanner cursor to account for token TOKEN of /* Set *LOC and adjust scanner cursor to account for token TOKEN of
size SIZE. */ size SIZE. */
@@ -781,6 +786,8 @@ handle_action_dollar (char *text, location loc)
if (INT_MIN <= num && num <= rule_length && ! get_errno ()) if (INT_MIN <= num && num <= rule_length && ! get_errno ())
{ {
int n = num; int n = num;
if (1-n > max_left_semantic_context)
max_left_semantic_context = 1-n;
if (!type_name && n > 0) if (!type_name && n > 0)
type_name = symbol_list_n_type_name_get (current_rule, loc, n); type_name = symbol_list_n_type_name_get (current_rule, loc, n);
if (!type_name && typed) if (!type_name && typed)

View File

@@ -24,7 +24,10 @@ AT_BANNER([[C++ Type Syntax (GLR).]])
# and with RESOLVE1 and RESOLVE2 as annotations on the conflicted rule for # and with RESOLVE1 and RESOLVE2 as annotations on the conflicted rule for
# stmt. Then compile the result. # stmt. Then compile the result.
m4_define([_AT_TEST_GLR_CXXTYPES], m4_define([_AT_TEST_GLR_CXXTYPES],
[AT_DATA_GRAMMAR([types.y], [
AT_BISON_OPTION_PUSHDEFS([$1])
AT_DATA_GRAMMAR([types.y],
[[/* Simplified C++ Type and Expression Grammar. */ [[/* Simplified C++ Type and Expression Grammar. */
$1 $1
@@ -32,24 +35,10 @@ $1
%{ %{
#include <stdio.h> #include <stdio.h>
#define YYSTYPE const char* #define YYSTYPE const char*
#define YYLTYPE int
]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 ( static char* format (const char*, ...);
#if YYPURE && YYLSP_NEEDED
YYLTYPE *yylocation,
#endif
const char *s
);
#if YYPURE
]m4_bmatch([$1], [location],
[ int yylex (YYSTYPE *lvalp, YYLTYPE *llocp);],
[ int yylex (YYSTYPE *lvalp);])[
#else
int yylex (void);
#endif
%} %}
@@ -63,30 +52,35 @@ $1
%% %%
prog : prog :
| prog stmt { printf ("\n"); } | prog stmt {
]AT_LOCATION_IF([
printf ("%d.%d-%d.%d: ",
@2.first_line, @2.first_column,
@2.last_line, @2.last_column);])[
printf ("%s\n", ]$[2);
}
; ;
stmt : expr ';' $2 stmt : expr ';' $2 { $$ = ]$[1; }
| decl $3 | decl $3
| error ';' | error ';' { $$ = "<error>"; }
| '@' { YYACCEPT; } | '@' { YYACCEPT; }
; ;
expr : ID { printf ("%s ", ]$[1); } expr : ID
| TYPENAME '(' expr ')' | TYPENAME '(' expr ')' { $$ = format ("<cast>(%s,%s)", ]$[3, ]$[1); }
{ printf ("%s <cast> ", ]$[1); } | expr '+' expr { $$ = format ("+(%s,%s)", ]$[1, ]$[3); }
| expr '+' expr { printf ("+ "); } | expr '=' expr { $$ = format ("=(%s,%s)", ]$[1, ]$[3); }
| expr '=' expr { printf ("= "); }
; ;
decl : TYPENAME declarator ';' decl : TYPENAME declarator ';'
{ printf ("%s <declare> ", ]$[1); } { $$ = format ("<declare>(%s,%s)", ]$[1, ]$[2); }
| TYPENAME declarator '=' expr ';' | TYPENAME declarator '=' expr ';'
{ printf ("%s <init-declare> ", ]$[1); } { $$ = format ("<init-declare>(%s,%s,%s)", ]$[1, ]$[2, ]$[4); }
; ;
declarator : ID { printf ("\"%s\" ", ]$[1); } declarator : ID
| '(' declarator ')' | '(' declarator ')' { $$ = ]$[2; }
; ;
%% %%
@@ -94,6 +88,7 @@ declarator : ID { printf ("\"%s\" ", ]$[1); }
#include <ctype.h> #include <ctype.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdarg.h>
int int
main (int argc, char** argv) main (int argc, char** argv)
@@ -105,23 +100,25 @@ main (int argc, char** argv)
exit (yyparse ()); exit (yyparse ());
} }
#if YYPURE
int int
]m4_bmatch([$1], [location], #if YYPURE && YYLSP_NEEDED
[yylex (YYSTYPE *lvalp, YYLTYPE *llocp)], yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
[yylex (YYSTYPE *lvalp)])[ #elif YYPURE
yylex (YYSTYPE *lvalp)
#else #else
int yylex ()
yylex ()
#endif #endif
{ {
char buffer[256]; char buffer[256];
int c; int c;
unsigned int i; unsigned int i;
static int lineNum = 1;
static int colNum = 1;
#if YYPURE #if YYPURE
# define yylloc (*llocp)
# define yylval (*lvalp) # define yylval (*lvalp)
]m4_bmatch([$1], [location],[ (void) llocp;])[
#endif #endif
while (1) while (1)
@@ -131,28 +128,53 @@ yylex ()
{ {
case EOF: case EOF:
return 0; return 0;
case ' ': case '\t': case '\n': case '\f': case '\t':
colNum = 1 + ((colNum + 7) & ~7);
break;
case ' ': case '\f':
colNum += 1;
break;
case '\n':
lineNum += 1;
colNum = 1;
break; break;
default: default:
if (isalpha (c)) {
{ int tok;
i = 0; #if YYLSP_NEEDED
yylloc.first_line = yylloc.last_line = lineNum;
yylloc.first_column = colNum;
#endif
if (isalpha (c))
{
i = 0;
do do
{ {
buffer[i++] = c; buffer[i++] = c;
if (i == sizeof buffer - 1) colNum += 1;
abort (); if (i == sizeof buffer - 1)
c = getchar (); abort ();
} c = getchar ();
while (isalnum (c) || c == '_'); }
while (isalnum (c) || c == '_');
ungetc (c, stdin); ungetc (c, stdin);
buffer[i++] = 0; buffer[i++] = 0;
yylval = strcpy (malloc (i), buffer); tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID;
return isupper ((unsigned char) buffer[0]) ? TYPENAME : ID; yylval = strcpy (malloc (i), buffer);
} }
return c; else
{
colNum += 1;
tok = c;
yylval = "";
}
#if YYLSP_NEEDED
yylloc.last_column = colNum-1;
#endif
return tok;
}
} }
} }
} }
@@ -160,28 +182,32 @@ yylex ()
int int
yyerror ( yyerror (
#if YYPURE && YYLSP_NEEDED #if YYPURE && YYLSP_NEEDED
YYLTYPE *yylocation, YYLTYPE *llocp,
#endif #endif
const char *s const char *s
) )
{ {
#if YYPURE && YYLSP_NEEDED
(void) *yylocation;
#endif
fprintf (stderr, "%s\n", s); fprintf (stderr, "%s\n", s);
return 0; return 0;
} }
static char* format (const char* form, ...)
{
char buffer[1024];
va_list args;
va_start (args, form);
vsprintf (buffer, form, args);
va_end (args);
return strcpy (malloc (strlen (buffer) + 1), buffer);
}
]] ]]
m4_bmatch([$2], [stmtMerge], m4_bmatch([$2], [stmtMerge],
[[static YYSTYPE [[static YYSTYPE
stmtMerge (YYSTYPE x0, YYSTYPE x1) stmtMerge (YYSTYPE x0, YYSTYPE x1)
{ {
/* Use the arguments. */ return format ("<OR>(%s,%s)", x0, x1);
(void) x0;
(void) x1;
printf ("<OR> ");
return "";
} }
]]) ]])
) )
@@ -214,30 +240,55 @@ This is total garbage, but it should be ignored.
AT_CHECK([bison -o types.c types.y], 0, [], ignore) AT_CHECK([bison -o types.c types.y], 0, [], ignore)
AT_COMPILE([types]) AT_COMPILE([types])
AT_BISON_OPTION_POPDEFS
]) ])
m4_define([_AT_RESOLVED_GLR_OUTPUT], m4_define([_AT_RESOLVED_GLR_OUTPUT],
[[z q + [[+(z,q)
"x" T <declare> <declare>(T,x)
"x" y T <init-declare> <init-declare>(T,x,y)
x y = =(x,y)
x T <cast> y + +(<cast>(x,T),y)
"x" T <declare> <declare>(T,x)
"y" z q + T <init-declare> <init-declare>(T,y,+(z,q))
y <error>
z q + +(z,q)
]])
m4_define([_AT_RESOLVED_GLR_OUTPUT_WITH_LOC],
[[3.1-3.6: +(z,q)
5.1-5.4: <declare>(T,x)
7.1-7.8: <init-declare>(T,x,y)
9.1-9.6: =(x,y)
11.1-11.10: +(<cast>(x,T),y)
13.1-13.6: <declare>(T,x)
15.1-15.14: <init-declare>(T,y,+(z,q))
17.6-17.16: <error>
19.1-19.6: +(z,q)
]]) ]])
m4_define([_AT_AMBIG_GLR_OUTPUT], m4_define([_AT_AMBIG_GLR_OUTPUT],
[[z q + [[+(z,q)
"x" T <declare> <declare>(T,x)
"x" y T <init-declare> <init-declare>(T,x,y)
x y = =(x,y)
x T <cast> y + +(<cast>(x,T),y)
"x" T <declare> x T <cast> <OR> <OR>(<declare>(T,x),<cast>(x,T))
"y" z q + T <init-declare> y T <cast> z q + = <OR> <OR>(<init-declare>(T,y,+(z,q)),=(<cast>(y,T),+(z,q)))
y <error>
z q + +(z,q)
]])
m4_define([_AT_AMBIG_GLR_OUTPUT_WITH_LOC],
[[3.1-3.6: +(z,q)
5.1-5.4: <declare>(T,x)
7.1-7.8: <init-declare>(T,x,y)
9.1-9.6: =(x,y)
11.1-11.10: +(<cast>(x,T),y)
13.1-13.6: <OR>(<declare>(T,x),<cast>(x,T))
15.1-15.14: <OR>(<init-declare>(T,y,+(z,q)),=(<cast>(y,T),+(z,q)))
17.6-17.16: <error>
19.1-19.6: +(z,q)
]]) ]])
m4_define([_AT_GLR_STDERR], m4_define([_AT_GLR_STDERR],
@@ -262,7 +313,7 @@ AT_CLEANUP
AT_SETUP([GLR: Resolve ambiguity, impure, locations]) AT_SETUP([GLR: Resolve ambiguity, impure, locations])
_AT_TEST_GLR_CXXTYPES([%locations],[%dprec 1],[%dprec 2]) _AT_TEST_GLR_CXXTYPES([%locations],[%dprec 1],[%dprec 2])
AT_PARSER_CHECK([[./types test-input | sed 's/ *$//']], 0, AT_PARSER_CHECK([[./types test-input | sed 's/ *$//']], 0,
_AT_RESOLVED_GLR_OUTPUT, _AT_GLR_STDERR) _AT_RESOLVED_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR)
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Resolve ambiguity, pure, no locations]) AT_SETUP([GLR: Resolve ambiguity, pure, no locations])
@@ -276,7 +327,7 @@ AT_SETUP([GLR: Resolve ambiguity, pure, locations])
_AT_TEST_GLR_CXXTYPES([%pure-parser %locations], _AT_TEST_GLR_CXXTYPES([%pure-parser %locations],
[%dprec 1], [%dprec 2]) [%dprec 1], [%dprec 2])
AT_PARSER_CHECK([[./types test-input | sed 's/ *$//']], 0, AT_PARSER_CHECK([[./types test-input | sed 's/ *$//']], 0,
_AT_RESOLVED_GLR_OUTPUT, _AT_GLR_STDERR) _AT_RESOLVED_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR)
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Merge conflicting parses, impure, no locations]) AT_SETUP([GLR: Merge conflicting parses, impure, no locations])
@@ -290,7 +341,7 @@ AT_SETUP([GLR: Merge conflicting parses, impure, locations])
_AT_TEST_GLR_CXXTYPES([%locations], _AT_TEST_GLR_CXXTYPES([%locations],
[%merge <stmtMerge>], [%merge <stmtMerge>]) [%merge <stmtMerge>], [%merge <stmtMerge>])
AT_PARSER_CHECK([[./types test-input | sed 's/ *$//']], 0, AT_PARSER_CHECK([[./types test-input | sed 's/ *$//']], 0,
_AT_AMBIG_GLR_OUTPUT, _AT_GLR_STDERR) _AT_AMBIG_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR)
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Merge conflicting parses, pure, no locations]) AT_SETUP([GLR: Merge conflicting parses, pure, no locations])
@@ -303,7 +354,7 @@ AT_SETUP([GLR: Merge conflicting parses, pure, locations])
_AT_TEST_GLR_CXXTYPES([%pure-parser %locations], _AT_TEST_GLR_CXXTYPES([%pure-parser %locations],
[%merge <stmtMerge>],[%merge <stmtMerge>]) [%merge <stmtMerge>],[%merge <stmtMerge>])
AT_PARSER_CHECK([[./types test-input | sed 's/ *$//']], 0, AT_PARSER_CHECK([[./types test-input | sed 's/ *$//']], 0,
_AT_AMBIG_GLR_OUTPUT, _AT_GLR_STDERR) _AT_AMBIG_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR)
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Verbose messages, resolve ambiguity, impure, no locations]) AT_SETUP([GLR: Verbose messages, resolve ambiguity, impure, no locations])