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 ...@@ -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);
......