[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: GLR parsers and locations
From: |
Paul Hilfinger |
Subject: |
Re: GLR parsers and locations |
Date: |
Mon, 09 Jun 2003 19:52:33 -0700 |
I have checked in the following patch for the location-tracking
problem that Frank Heckenbach reported, and have also corrected a few
other errors with the handling of YYERROR and of non-positive semantic
value indices ($0, $<type>-2, etc.), and have spruced up the tests for
location-tracking as well.
GLR parsers now seem to handle YYERROR correctly, but I see that C++
parsers still go into loops.
Paul Hilfinger
2003-06-09 Paul Hilfinger <address@hidden>
* 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.
Index: bison-1_5.70/src/output.c
--- bison-1_5.70/src/output.c Thu, 05 Jun 2003 15:41:29 -0700 hilfingr
(glrbison/48_output.c 1.1.1.3.1.1.1.2.1.1.1.2.1.1.1.1.1.1.1.1.1.19 644)
+++ bison-1_5.70(w)/src/output.c Fri, 06 Jun 2003 21:05:08 -0700 hilfingr
(glrbison/48_output.c 1.1.1.3.1.1.1.2.1.1.1.2.1.1.1.1.1.1.1.1.1.19 644)
@@ -253,6 +253,7 @@ prepare_rules (void)
muscle_insert_short_table ("merger", merger, 0, 0, nrules);
MUSCLE_INSERT_INT ("rules_number", nrules);
+ MUSCLE_INSERT_INT ("max_left_semantic_context", max_left_semantic_context);
free (rhs);
free (prhs);
Index: bison-1_5.70/src/reader.h
--- bison-1_5.70/src/reader.h Thu, 05 Jun 2003 15:41:29 -0700 hilfingr
(glrbison/b/20_reader.h 1.1.1.3.1.1.1.2.1.1.1.1.1.10 644)
+++ bison-1_5.70(w)/src/reader.h Fri, 06 Jun 2003 21:05:08 -0700 hilfingr
(glrbison/b/20_reader.h 1.1.1.3.1.1.1.2.1.1.1.1.1.10 644)
@@ -38,6 +38,7 @@ typedef struct merger_list
extern FILE *gram_in;
extern int gram__flex_debug;
extern boundary scanner_cursor;
+extern int max_left_semantic_context;
void scanner_initialize (void);
void scanner_free (void);
void scanner_last_string_free (void);
Index: bison-1_5.70/src/scan-gram.l
--- bison-1_5.70/src/scan-gram.l Thu, 05 Jun 2003 15:41:29 -0700 hilfingr
(glrbison/g/8_scan-gram. 1.1.1.1.1.1.1.1.1.1.1.1.1.17 644)
+++ bison-1_5.70(w)/src/scan-gram.l Fri, 06 Jun 2003 21:05:08 -0700 hilfingr
(glrbison/g/8_scan-gram. 1.1.1.1.1.1.1.1.1.1.1.1.1.17 644)
@@ -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
size SIZE. */
@@ -781,6 +786,8 @@ handle_action_dollar (char *text, locati
if (INT_MIN <= num && num <= rule_length && ! get_errno ())
{
int n = num;
+ if (1-n > max_left_semantic_context)
+ max_left_semantic_context = 1-n;
if (!type_name && n > 0)
type_name = symbol_list_n_type_name_get (current_rule, loc, n);
if (!type_name && typed)
Index: bison-1_5.70/tests/cxx-type.at
--- bison-1_5.70/tests/cxx-type.at Thu, 17 Apr 2003 10:12:58 -0700 hilfingr
(glrbison/g/23_cxx-type.a 1.11 644)
+++ bison-1_5.70(w)/tests/cxx-type.at Mon, 09 Jun 2003 18:17:12 -0700 hilfingr
(glrbison/g/23_cxx-type.a 1.11 644)
@@ -24,7 +24,10 @@ AT_BANNER([[C++ Type Syntax (GLR).]])
# and with RESOLVE1 and RESOLVE2 as annotations on the conflicted rule for
# stmt. Then compile the result.
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. */
$1
@@ -32,24 +35,10 @@ $1
%{
#include <stdio.h>
#define YYSTYPE const char*
- #define YYLTYPE int
]m4_bmatch([$2], [stmtMerge],
[ static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1);])[
#define YYINITDEPTH 10
- int yyerror (
-#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
+ static char* format (const char*, ...);
%}
@@ -63,30 +52,35 @@ $1
%%
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
- | error ';'
- | '@' { YYACCEPT; }
+ | error ';' { $$ = "<error>"; }
+ | '@' { YYACCEPT; }
;
-expr : ID { printf ("%s ", ]$[1); }
- | TYPENAME '(' expr ')'
- { printf ("%s <cast> ", ]$[1); }
- | expr '+' expr { printf ("+ "); }
- | expr '=' expr { printf ("= "); }
+expr : ID
+ | TYPENAME '(' expr ')' { $$ = format ("<cast>(%s,%s)", ]$[3, ]$[1); }
+ | expr '+' expr { $$ = format ("+(%s,%s)", ]$[1, ]$[3); }
+ | expr '=' expr { $$ = format ("=(%s,%s)", ]$[1, ]$[3); }
;
decl : TYPENAME declarator ';'
- { printf ("%s <declare> ", ]$[1); }
+ { $$ = format ("<declare>(%s,%s)", ]$[1, ]$[2); }
| TYPENAME declarator '=' expr ';'
- { printf ("%s <init-declare> ", ]$[1); }
+ { $$ = format ("<init-declare>(%s,%s,%s)", ]$[1, ]$[2,
]$[4); }
;
-declarator : ID { printf ("\"%s\" ", ]$[1); }
- | '(' declarator ')'
+declarator : ID
+ | '(' declarator ')' { $$ = ]$[2; }
;
%%
@@ -94,6 +88,7 @@ declarator : ID { printf ("\"%s\" ", ]$
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
int
main (int argc, char** argv)
@@ -105,23 +100,25 @@ main (int argc, char** argv)
exit (yyparse ());
}
-#if YYPURE
int
-]m4_bmatch([$1], [location],
-[yylex (YYSTYPE *lvalp, YYLTYPE *llocp)],
-[yylex (YYSTYPE *lvalp)])[
+#if YYPURE && YYLSP_NEEDED
+ yylex (YYSTYPE *lvalp, YYLTYPE *llocp)
+#elif YYPURE
+ yylex (YYSTYPE *lvalp)
#else
-int
-yylex ()
+ yylex ()
#endif
{
char buffer[256];
int c;
unsigned int i;
+ static int lineNum = 1;
+ static int colNum = 1;
+
#if YYPURE
+# define yylloc (*llocp)
# define yylval (*lvalp)
-]m4_bmatch([$1], [location],[ (void) llocp;])[
#endif
while (1)
@@ -131,28 +128,53 @@ yylex ()
{
case EOF:
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;
default:
- if (isalpha (c))
- {
- i = 0;
-
- do
- {
- buffer[i++] = c;
- if (i == sizeof buffer - 1)
- abort ();
- c = getchar ();
- }
- while (isalnum (c) || c == '_');
-
- ungetc (c, stdin);
- buffer[i++] = 0;
- yylval = strcpy (malloc (i), buffer);
- return isupper ((unsigned char) buffer[0]) ? TYPENAME : ID;
- }
- return c;
+ {
+ int tok;
+#if YYLSP_NEEDED
+ yylloc.first_line = yylloc.last_line = lineNum;
+ yylloc.first_column = colNum;
+#endif
+ if (isalpha (c))
+ {
+ i = 0;
+
+ do
+ {
+ buffer[i++] = c;
+ colNum += 1;
+ if (i == sizeof buffer - 1)
+ abort ();
+ c = getchar ();
+ }
+ while (isalnum (c) || c == '_');
+
+ ungetc (c, stdin);
+ buffer[i++] = 0;
+ tok = isupper ((unsigned char) buffer[0]) ? TYPENAME : ID;
+ yylval = strcpy (malloc (i), buffer);
+ }
+ else
+ {
+ colNum += 1;
+ tok = c;
+ yylval = "";
+ }
+#if YYLSP_NEEDED
+ yylloc.last_column = colNum-1;
+#endif
+ return tok;
+ }
}
}
}
@@ -160,28 +182,32 @@ yylex ()
int
yyerror (
#if YYPURE && YYLSP_NEEDED
- YYLTYPE *yylocation,
+ YYLTYPE *llocp,
#endif
const char *s
)
{
-#if YYPURE && YYLSP_NEEDED
- (void) *yylocation;
-#endif
fprintf (stderr, "%s\n", s);
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],
[[static YYSTYPE
stmtMerge (YYSTYPE x0, YYSTYPE x1)
{
- /* Use the arguments. */
- (void) x0;
- (void) x1;
- printf ("<OR> ");
- return "";
+ return format ("<OR>(%s,%s)", x0, x1);
}
]])
)
@@ -214,30 +240,55 @@ This is total garbage, but it should be
AT_CHECK([bison -o types.c types.y], 0, [], ignore)
AT_COMPILE([types])
+AT_BISON_OPTION_POPDEFS
])
m4_define([_AT_RESOLVED_GLR_OUTPUT],
-[[z q +
-"x" T <declare>
-"x" y T <init-declare>
-x y =
-x T <cast> y +
-"x" T <declare>
-"y" z q + T <init-declare>
-y
-z q +
+[[+(z,q)
+<declare>(T,x)
+<init-declare>(T,x,y)
+=(x,y)
++(<cast>(x,T),y)
+<declare>(T,x)
+<init-declare>(T,y,+(z,q))
+<error>
++(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],
-[[z q +
-"x" T <declare>
-"x" y T <init-declare>
-x y =
-x T <cast> y +
-"x" T <declare> x T <cast> <OR>
-"y" z q + T <init-declare> y T <cast> z q + = <OR>
-y
-z q +
+[[+(z,q)
+<declare>(T,x)
+<init-declare>(T,x,y)
+=(x,y)
++(<cast>(x,T),y)
+<OR>(<declare>(T,x),<cast>(x,T))
+<OR>(<init-declare>(T,y,+(z,q)),=(<cast>(y,T),+(z,q)))
+<error>
++(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],
@@ -262,7 +313,7 @@ AT_CLEANUP
AT_SETUP([GLR: Resolve ambiguity, impure, locations])
_AT_TEST_GLR_CXXTYPES([%locations],[%dprec 1],[%dprec 2])
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_SETUP([GLR: Resolve ambiguity, pure, no locations])
@@ -276,7 +327,7 @@ AT_SETUP([GLR: Resolve ambiguity, pure,
_AT_TEST_GLR_CXXTYPES([%pure-parser %locations],
[%dprec 1], [%dprec 2])
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_SETUP([GLR: Merge conflicting parses, impure, no locations])
@@ -290,7 +341,7 @@ AT_SETUP([GLR: Merge conflicting parses,
_AT_TEST_GLR_CXXTYPES([%locations],
[%merge <stmtMerge>], [%merge <stmtMerge>])
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_SETUP([GLR: Merge conflicting parses, pure, no locations])
@@ -303,7 +354,7 @@ AT_SETUP([GLR: Merge conflicting parses,
_AT_TEST_GLR_CXXTYPES([%pure-parser %locations],
[%merge <stmtMerge>],[%merge <stmtMerge>])
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_SETUP([GLR: Verbose messages, resolve ambiguity, impure, no locations])
Index: bison-1_5.70/data/glr.c
--- bison-1_5.70/data/glr.c Thu, 05 Jun 2003 15:41:29 -0700 hilfingr
(glrbison/e/14_glr-parser 1.27.1.33 644)
+++ bison-1_5.70(w)/data/glr.c Mon, 09 Jun 2003 18:17:12 -0700 hilfingr
(glrbison/e/14_glr-parser 1.27.1.33 644)
@@ -192,10 +192,12 @@ b4_syncline(address@hidden@], address@hidden@])],
#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
typedef struct YYLTYPE
{
+]b4_location_if([
int first_line;
int first_column;
int last_line;
int last_column;
+])[
} YYLTYPE;
# define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1
@@ -254,6 +256,9 @@ b4_syncline(address@hidden@], address@hidden@])
#define YYNSTATES ]b4_states_number[
/* YYMAXRHS -- Maximum number of symbols on right-hand side of rule. */
#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. */
#define YYUNDEFTOK ]b4_undef_token_number[
@@ -402,15 +407,22 @@ static const ]b4_int_type_for([b4_stos])
/* YYLLOC_DEFAULT -- Compute the default location (before the actions
are run). */
-#define YYRHSLOC(yyRhs,YYK) (yyRhs[YYK].yystate.yyloc)
+]b4_location_if([[
+#define YYRHSLOC(yyRhs,YYK) ((yyRhs)[YYK].yystate.yyloc)
#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(yyCurrent, yyRhs, YYN) \
- yyCurrent.first_line = YYRHSLOC(yyRhs,1).first_line; \
- yyCurrent.first_column = YYRHSLOC(yyRhs,1).first_column; \
- yyCurrent.last_line = YYRHSLOC(yyRhs,YYN).last_line; \
- yyCurrent.last_column = YYRHSLOC(yyRhs,YYN).last_column;
+ (yyCurrent).first_line = YYRHSLOC(yyRhs,1).first_line; \
+ (yyCurrent).first_column = YYRHSLOC(yyRhs,1).first_column; \
+ (yyCurrent).last_line = YYRHSLOC(yyRhs,YYN).last_line; \
+ (yyCurrent).last_column = YYRHSLOC(yyRhs,YYN).last_column;
+#endif
+]],[
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(yyCurrent, yyRhs, YYN)
#endif
+])[
+
/* YYLEX -- calling `yylex' with the right arguments. */
#define YYLEX ]b4_c_function_call([yylex], [int], b4_lex_param)[
@@ -663,16 +675,6 @@ yyuserAction (yyRuleNum yyn, int yyrhsle
yybool yynormal ATTRIBUTE_UNUSED = (yystack->yysplitPoint == NULL);
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
# define yyerrok (yystack->yyerrState = 0)
# undef YYACCEPT
@@ -680,7 +682,7 @@ yyuserAction (yyRuleNum yyn, int yyrhsle
# undef YYABORT
# define YYABORT return yyabort
# undef YYERROR
-# define YYERROR return yyerr
+# define YYERROR do { yystack->yyerrState = 0; return yyerr; } while (0)
# undef YYRECOVERING
# define YYRECOVERING (yystack->yyerrState != 0)
# undef yyclearin
@@ -694,14 +696,25 @@ yyuserAction (yyRuleNum yyn, int yyrhsle
YYERROR; \
} while (0)
+ yylow = 1;
+ if (yyrhslen == 0)
+ {
+ *yyvalp = yyval_default;
+ *yylocp = yyloc_default;
+ }
+ else
+ {
+ *yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yysval;
+ YYLLOC_DEFAULT (*yylocp, yyvsp - yyrhslen, yyrhslen);
+ }
+
]
- yylow = 1;
- switch (yyn)
- {
- b4_actions
- }
+ switch (yyn)
+ {
+ b4_actions
+ }
- return yyok;
+ return yyok;
# undef yyerrok
# undef YYABORT
# undef YYACCEPT
@@ -1080,16 +1093,6 @@ yydoAction (yyGLRStack* yystack, int yyk
yystack->yynextFree -= yynrhs;
yystack->yyspaceLeft += yynrhs;
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,
yyvalp, yylocp, yystack]b4_user_args[);
}
@@ -1097,8 +1100,9 @@ yydoAction (yyGLRStack* yystack, int yyk
{
int yyi;
yyGLRState* yys;
- yyGLRStackItem yyrhsVals[YYMAXRHS+1];
- yys = yyrhsVals[YYMAXRHS].yystate.yypred = yystack->yytops.yystates[yyk];
+ yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
+ yys = yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred
+ = yystack->yytops.yystates[yyk];
for (yyi = 0; yyi < yynrhs; yyi += 1)
{
yys = yys->yypred;
@@ -1107,17 +1111,7 @@ yydoAction (yyGLRStack* yystack, int yyk
}
yyupdateSplit (yystack, yys);
yystack->yytops.yystates[yyk] = yys;
- if (yynrhs == 0)
- {
- *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,
+ return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT -
1,
yyvalp, yylocp, yystack]b4_user_args[);
}
}
@@ -1348,13 +1342,14 @@ static YYRESULTTAG
yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystack,
YYSTYPE* yyvalp, YYLTYPE* yylocp]b4_user_formals[)
{
- yyGLRStackItem yyrhsVals[YYMAXRHS+1];
+ yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
int yynrhs;
yynrhs = yyrhsLength (yyopt->yyrule);
YYCHK (yyresolveStates (yyopt->yystate, yynrhs, yystack]b4_user_args[));
- yyrhsVals[YYMAXRHS].yystate.yypred = yyopt->yystate;
- return yyuserAction (yyopt->yyrule, yynrhs, yyrhsVals + YYMAXRHS - 1,
+ yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred = yyopt->yystate;
+ return yyuserAction (yyopt->yyrule, yynrhs,
+ yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
yyvalp, yylocp, yystack]b4_user_args[);
}
@@ -1687,17 +1682,14 @@ yyrecoverSyntaxError (yyGLRStack* yystac
size_t yyk;
int yyj;
- if (yystack->yyerrState == 0)
- yystack->yyerrState = 3;
- else if (yystack->yyerrState == 3)
+ if (yystack->yyerrState == 3)
/* We just shifted the error token and (perhaps) took some
reductions. Skip tokens until we can proceed. */
while (yytrue)
{
if (*yytokenp == YYEOF)
{
- /* Now pop stack until we find a state that shifts the
- error token. */
+ /* Now pop stack until empty and fail. */
while (yystack->yytops.yystates[0] != NULL)
{
yyGLRState *yys = yystack->yytops.yystates[0];
@@ -1723,8 +1715,7 @@ yyrecoverSyntaxError (yyGLRStack* yystac
YYDSYMPRINTF ("Next token is", *yytokenp, yylvalp, yyllocp);
yyj = yypact[yystack->yytops.yystates[0]->yylrState];
if (yyis_pact_ninf (yyj))
- /* Something's not right; we shouldn't be here. */
- yyFail (yystack][]b4_lpure_args[, NULL);
+ return;
yyj += *yytokenp;
if (yyj < 0 || YYLAST < yyj || yycheck[yyj] != *yytokenp)
{
@@ -1747,6 +1738,7 @@ yyrecoverSyntaxError (yyGLRStack* yystac
yycompressStack (yystack);
/* Now pop stack until we find a state that shifts the error token. */
+ yystack->yyerrState = 3;
while (yystack->yytops.yystates[0] != NULL)
{
yyGLRState *yys = yystack->yytops.yystates[0];
@@ -2016,20 +2008,21 @@ b4_syncline(address@hidden@], address@hidden@])],
b4_pure_if([],
[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
{
+b4_location_if([
int first_line;
int first_column;
int last_line;
int last_column;
+])
} YYLTYPE;
# define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1
#endif
-m4_if(b4_pure, [0],
+b4_location_if([m4_if(b4_pure, [0],
[extern YYLTYPE b4_prefix[]lloc;])
])
])
- GLR parsers and locations, Frank Heckenbach, 2003/06/05
- Re: GLR parsers and locations, Paul Eggert, 2003/06/05
- Re: GLR parsers and locations, Frank Heckenbach, 2003/06/05
- Re: GLR parsers and locations, Paul Hilfinger, 2003/06/05
- Re: GLR parsers and locations, Frank Heckenbach, 2003/06/08
- Re: GLR parsers and locations,
Paul Hilfinger <=
- Re: GLR parsers and locations, Frank Heckenbach, 2003/06/15
- Re: GLR parsers and locations, Paul Hilfinger, 2003/06/15
- Re: GLR parsers and locations, Paul Eggert, 2003/06/17