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.
Showing
4 changed files
with
62 additions
and
11 deletions
... | @@ -36,13 +36,13 @@ AM_LEXFLAGS=-d | ... | @@ -36,13 +36,13 @@ AM_LEXFLAGS=-d |
36 | EXTRA_DIST = mimetypes.y mimetypes.l | 36 | EXTRA_DIST = mimetypes.y mimetypes.l |
37 | 37 | ||
38 | mimetypes-gram.c mimetypes-decl.h: $(srcdir)/mimetypes.y | 38 | mimetypes-gram.c mimetypes-decl.h: $(srcdir)/mimetypes.y |
39 | $(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \ | 39 | $(AM_V_GEN)$(YLWRAP) "$(YACC) $(AM_YFLAGS) -d" $< \ |
40 | y.tab.c mimetypes-gram.c y.tab.h mimetypes-decl.h \ | 40 | y.tab.c mimetypes-gram.c y.tab.h mimetypes-decl.h \ |
41 | y.output mimetypes.output \ | 41 | y.output mimetypes.output \ |
42 | -- -yy mimetypes_yy | 42 | -- -yy mimetypes_yy |
43 | 43 | ||
44 | mimetypes-lex.c: $(srcdir)/mimetypes.l mimetypes-decl.h | 44 | mimetypes-lex.c: $(srcdir)/mimetypes.l mimetypes-decl.h |
45 | $(YLWRAP) "$(LEX) $(AM_LEXFLAGS) $(LEXFLAGS)" \ | 45 | $(AM_V_GEN)$(YLWRAP) "$(LEX) $(AM_LEXFLAGS) $(LEXFLAGS)" \ |
46 | $(srcdir)/mimetypes.l lex.yy.c mimetypes-lex.c \ | 46 | $(srcdir)/mimetypes.l lex.yy.c mimetypes-lex.c \ |
47 | -- -yy mimetypes_yy | 47 | -- -yy mimetypes_yy |
48 | 48 | ... | ... |
... | @@ -92,7 +92,7 @@ finish_string (void) | ... | @@ -92,7 +92,7 @@ finish_string (void) |
92 | if (mu_debug_level_p (MU_DEBCAT_APP, MU_DEBUG_TRACE5)) | 92 | if (mu_debug_level_p (MU_DEBCAT_APP, MU_DEBUG_TRACE5)) |
93 | { | 93 | { |
94 | size_t i; | 94 | size_t i; |
95 | mu_debug_log_begin ("string %d: ", yylval.string.len); | 95 | mu_debug_log_begin ("string %zu: ", yylval.string.len); |
96 | for (i = 0; i < yylval.string.len; i++) | 96 | for (i = 0; i < yylval.string.len; i++) |
97 | if (mu_isprint (yylval.string.ptr[i])) | 97 | if (mu_isprint (yylval.string.ptr[i])) |
98 | mu_debug_log_cont ("%c", yylval.string.ptr[i]); | 98 | mu_debug_log_cont ("%c", yylval.string.ptr[i]); |
... | @@ -109,9 +109,6 @@ finish_string (void) | ... | @@ -109,9 +109,6 @@ finish_string (void) |
109 | #define YY_USER_ACTION advance_locus (); | 109 | #define YY_USER_ACTION advance_locus (); |
110 | %} | 110 | %} |
111 | 111 | ||
112 | %option nounput | ||
113 | %option noinput | ||
114 | |||
115 | %x RULE ARGS ASTRING | 112 | %x RULE ARGS ASTRING |
116 | X [0-9a-fA-F] | 113 | X [0-9a-fA-F] |
117 | IDENT [a-zA-Z_\.][a-zA-Z0-9_\.-]* | 114 | IDENT [a-zA-Z_\.][a-zA-Z0-9_\.-]* |
... | @@ -317,8 +314,54 @@ mimetypes_malloc (size_t size) | ... | @@ -317,8 +314,54 @@ mimetypes_malloc (size_t size) |
317 | return mu_opool_finish (pool, NULL); | 314 | return mu_opool_finish (pool, NULL); |
318 | } | 315 | } |
319 | 316 | ||
317 | /* Position input at the beginning of the next rule as a final part of error | ||
318 | recovery */ | ||
320 | void | 319 | void |
321 | lex_reset (void) | 320 | lex_next_rule (void) |
322 | { | 321 | { |
323 | BEGIN (INITIAL); | 322 | int bol = 0; |
323 | int c; | ||
324 | |||
325 | if (newline) | ||
326 | { | ||
327 | loc.mu_col = 0; | ||
328 | loc.mu_line++; | ||
329 | newline = 0; | ||
330 | bol = 1; | ||
331 | } | ||
332 | |||
333 | if (yy_flex_debug) | ||
334 | { | ||
335 | YY_LOCATION_PRINT (stderr, yylloc); | ||
336 | fprintf (stderr, ": started error recovery\n"); | ||
337 | } | ||
338 | while ((c = input ()) != EOF) | ||
339 | { | ||
340 | loc.mu_col++; | ||
341 | if (c == '\n') | ||
342 | { | ||
343 | loc.mu_line++; | ||
344 | loc.mu_col = 0; | ||
345 | bol = 1; | ||
346 | } | ||
347 | else if (bol) | ||
348 | { | ||
349 | bol = 0; | ||
350 | if (!(c == ' ' || c == '\t')) | ||
351 | { | ||
352 | unput (c); | ||
353 | break; | ||
354 | } | ||
355 | } | ||
356 | } | ||
357 | if (yy_flex_debug) | ||
358 | { | ||
359 | yylloc.beg = yylloc.end = loc; | ||
360 | YY_LOCATION_PRINT (stderr, yylloc); | ||
361 | fprintf (stderr, ": finished error recovery\n"); | ||
362 | } | ||
363 | BEGIN (RULE); | ||
364 | unput ('\n'); | ||
365 | loc.mu_col = 0; | ||
366 | loc.mu_line--; | ||
324 | } | 367 | } | ... | ... |
... | @@ -30,6 +30,7 @@ yyprint (FILE *output, unsigned short toknum, YYSTYPE val) | ... | @@ -30,6 +30,7 @@ yyprint (FILE *output, unsigned short toknum, YYSTYPE val) |
30 | { | 30 | { |
31 | switch (toknum) | 31 | switch (toknum) |
32 | { | 32 | { |
33 | case TYPE: | ||
33 | case IDENT: | 34 | case IDENT: |
34 | case STRING: | 35 | case STRING: |
35 | fprintf (output, "[%lu] %s", (unsigned long) val.string.len, | 36 | fprintf (output, "[%lu] %s", (unsigned long) val.string.len, |
... | @@ -124,6 +125,7 @@ static mu_list_t rule_list; | ... | @@ -124,6 +125,7 @@ static mu_list_t rule_list; |
124 | %} | 125 | %} |
125 | 126 | ||
126 | %locations | 127 | %locations |
128 | %expect 12 | ||
127 | 129 | ||
128 | %token <string> TYPE IDENT | 130 | %token <string> TYPE IDENT |
129 | %token <string> STRING | 131 | %token <string> STRING |
... | @@ -165,14 +167,20 @@ rule_line: /* empty */ | ... | @@ -165,14 +167,20 @@ rule_line: /* empty */ |
165 | p->priority = $3; | 167 | p->priority = $3; |
166 | p->loc.beg = @1.beg; | 168 | p->loc.beg = @1.beg; |
167 | p->loc.end = @3.end; | 169 | p->loc.end = @3.end; |
170 | #if 0 | ||
171 | YY_LOCATION_PRINT (stderr, p->loc); | ||
172 | fprintf (stderr, ": rule %s\n", p->type); | ||
173 | #endif | ||
168 | mu_list_append (rule_list, p); | 174 | mu_list_append (rule_list, p); |
169 | } | 175 | } |
170 | | error EOL | 176 | | error |
171 | { | 177 | { |
172 | if (arg_list) | 178 | if (arg_list) |
173 | mu_list_destroy (&arg_list); | 179 | mu_list_destroy (&arg_list); |
174 | arg_list = NULL; | 180 | arg_list = NULL; |
175 | lex_reset (); | 181 | lex_next_rule (); |
182 | yyerrok; | ||
183 | yyclearin; | ||
176 | } | 184 | } |
177 | ; | 185 | ; |
178 | 186 | ... | ... |
... | @@ -38,7 +38,7 @@ void mimetypes_close (void); | ... | @@ -38,7 +38,7 @@ void mimetypes_close (void); |
38 | int mimetypes_parse (const char *name); | 38 | int mimetypes_parse (const char *name); |
39 | void mimetypes_lex_init (void); | 39 | void mimetypes_lex_init (void); |
40 | 40 | ||
41 | void lex_reset (void); | 41 | void lex_next_rule (void); |
42 | void *mimetypes_malloc (size_t size); | 42 | void *mimetypes_malloc (size_t size); |
43 | 43 | ||
44 | struct mimetypes_string *mimetypes_string_dup (struct mimetypes_string *s); | 44 | struct mimetypes_string *mimetypes_string_dup (struct mimetypes_string *s); | ... | ... |
-
Please register or sign in to post a comment