Commit 66da33c3 66da33c354a4a54d0107ea719c77c70ec20d85a3 by Sergey Poznyakoff

mimeview: improve parser error recovery

* mimeview/Makefile.am: Silent rules
* mimeview/mimetypes.l (lex_reset): Remove.
(lex_next_rule): New function.
* mimeview/mimetypes.y: Expect 12 shift/reduce conflicts.
Rewrite the error rule
(yyprint): Print TYPE token correctly
* mimeview/mimeview.h (lex_next_rule): New proto.
1 parent d30e5a07
......@@ -36,13 +36,13 @@ AM_LEXFLAGS=-d
EXTRA_DIST = mimetypes.y mimetypes.l
mimetypes-gram.c mimetypes-decl.h: $(srcdir)/mimetypes.y
$(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \
$(AM_V_GEN)$(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \
y.tab.c mimetypes-gram.c y.tab.h mimetypes-decl.h \
y.output mimetypes.output \
-- -yy mimetypes_yy
mimetypes-lex.c: $(srcdir)/mimetypes.l mimetypes-decl.h
$(YLWRAP) "$(LEX) $(AM_LEXFLAGS) $(LEXFLAGS)" \
$(AM_V_GEN)$(YLWRAP) "$(LEX) $(AM_LEXFLAGS) $(LEXFLAGS)" \
$(srcdir)/mimetypes.l lex.yy.c mimetypes-lex.c \
-- -yy mimetypes_yy
......
......@@ -92,7 +92,7 @@ finish_string (void)
if (mu_debug_level_p (MU_DEBCAT_APP, MU_DEBUG_TRACE5))
{
size_t i;
mu_debug_log_begin ("string %d: ", yylval.string.len);
mu_debug_log_begin ("string %zu: ", yylval.string.len);
for (i = 0; i < yylval.string.len; i++)
if (mu_isprint (yylval.string.ptr[i]))
mu_debug_log_cont ("%c", yylval.string.ptr[i]);
......@@ -109,9 +109,6 @@ finish_string (void)
#define YY_USER_ACTION advance_locus ();
%}
%option nounput
%option noinput
%x RULE ARGS ASTRING
X [0-9a-fA-F]
IDENT [a-zA-Z_\.][a-zA-Z0-9_\.-]*
......@@ -317,8 +314,54 @@ mimetypes_malloc (size_t size)
return mu_opool_finish (pool, NULL);
}
/* Position input at the beginning of the next rule as a final part of error
recovery */
void
lex_reset (void)
lex_next_rule (void)
{
BEGIN (INITIAL);
int bol = 0;
int c;
if (newline)
{
loc.mu_col = 0;
loc.mu_line++;
newline = 0;
bol = 1;
}
if (yy_flex_debug)
{
YY_LOCATION_PRINT (stderr, yylloc);
fprintf (stderr, ": started error recovery\n");
}
while ((c = input ()) != EOF)
{
loc.mu_col++;
if (c == '\n')
{
loc.mu_line++;
loc.mu_col = 0;
bol = 1;
}
else if (bol)
{
bol = 0;
if (!(c == ' ' || c == '\t'))
{
unput (c);
break;
}
}
}
if (yy_flex_debug)
{
yylloc.beg = yylloc.end = loc;
YY_LOCATION_PRINT (stderr, yylloc);
fprintf (stderr, ": finished error recovery\n");
}
BEGIN (RULE);
unput ('\n');
loc.mu_col = 0;
loc.mu_line--;
}
......
......@@ -30,6 +30,7 @@ yyprint (FILE *output, unsigned short toknum, YYSTYPE val)
{
switch (toknum)
{
case TYPE:
case IDENT:
case STRING:
fprintf (output, "[%lu] %s", (unsigned long) val.string.len,
......@@ -124,6 +125,7 @@ static mu_list_t rule_list;
%}
%locations
%expect 12
%token <string> TYPE IDENT
%token <string> STRING
......@@ -165,14 +167,20 @@ rule_line: /* empty */
p->priority = $3;
p->loc.beg = @1.beg;
p->loc.end = @3.end;
#if 0
YY_LOCATION_PRINT (stderr, p->loc);
fprintf (stderr, ": rule %s\n", p->type);
#endif
mu_list_append (rule_list, p);
}
| error EOL
| error
{
if (arg_list)
mu_list_destroy (&arg_list);
arg_list = NULL;
lex_reset ();
lex_next_rule ();
yyerrok;
yyclearin;
}
;
......
......@@ -38,7 +38,7 @@ void mimetypes_close (void);
int mimetypes_parse (const char *name);
void mimetypes_lex_init (void);
void lex_reset (void);
void lex_next_rule (void);
void *mimetypes_malloc (size_t size);
struct mimetypes_string *mimetypes_string_dup (struct mimetypes_string *s);
......