summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2017-06-03 20:52:59 +0300
committerSergey Poznyakoff <gray@gnu.org>2017-06-03 20:52:59 +0300
commit66da33c354a4a54d0107ea719c77c70ec20d85a3 (patch)
tree83c6e8b427f3c76a452a17b61a99b6a47b4e5023
parentd30e5a07f35c756df64559fddcd69d8aaa23ab8d (diff)
downloadmailutils-66da33c354a4a54d0107ea719c77c70ec20d85a3.tar.gz
mailutils-66da33c354a4a54d0107ea719c77c70ec20d85a3.tar.bz2
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.
-rw-r--r--mimeview/Makefile.am4
-rw-r--r--mimeview/mimetypes.l55
-rw-r--r--mimeview/mimetypes.y12
-rw-r--r--mimeview/mimeview.h2
4 files changed, 62 insertions, 11 deletions
diff --git a/mimeview/Makefile.am b/mimeview/Makefile.am
index 2ae80fc92..5334e40c0 100644
--- a/mimeview/Makefile.am
+++ b/mimeview/Makefile.am
@@ -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
diff --git a/mimeview/mimetypes.l b/mimeview/mimetypes.l
index de03ea097..dd2311bf9 100644
--- a/mimeview/mimetypes.l
+++ b/mimeview/mimetypes.l
@@ -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--;
}
diff --git a/mimeview/mimetypes.y b/mimeview/mimetypes.y
index 6d6bc31ed..cfb4fbe8d 100644
--- a/mimeview/mimetypes.y
+++ b/mimeview/mimetypes.y
@@ -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;
}
;
diff --git a/mimeview/mimeview.h b/mimeview/mimeview.h
index 36f9fbfa3..39fb7f44f 100644
--- a/mimeview/mimeview.h
+++ b/mimeview/mimeview.h
@@ -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);

Return to:

Send suggestions and report system problems to the System administrator.