diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2017-06-03 20:52:59 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2017-06-03 20:52:59 +0300 |
commit | 66da33c354a4a54d0107ea719c77c70ec20d85a3 (patch) | |
tree | 83c6e8b427f3c76a452a17b61a99b6a47b4e5023 | |
parent | d30e5a07f35c756df64559fddcd69d8aaa23ab8d (diff) | |
download | mailutils-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.am | 4 | ||||
-rw-r--r-- | mimeview/mimetypes.l | 55 | ||||
-rw-r--r-- | mimeview/mimetypes.y | 12 | ||||
-rw-r--r-- | mimeview/mimeview.h | 2 |
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); |