From 89c4e1becfa35af33950b730f1aa3e375140999b Mon Sep 17 00:00:00 2001 From: Akim Demaille Date: Mon, 27 Apr 2020 08:06:49 +0200 Subject: [PATCH] scanner: avoid spurious errors about empty character literals On an invalid character literal such as "'\777'" we used to produce two errors: input.y:2.9-12: error: invalid number after \-escape: 777 input.y:2.8-13: error: empty character literal Get rid of the second one. * src/scan-gram.l (STRING_GROW_ESCAPE): New. * tests/input.at: Adjust. --- src/scan-gram.l | 40 ++++++++++++++++++++++------------------ tests/input.at | 10 ---------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/scan-gram.l b/src/scan-gram.l index a6ea01ce..0a6b3c04 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -83,6 +83,23 @@ static boundary scanner_cursor; unput (Msg[i - 1]); \ } while (0) + +#define STRING_GROW_ESCAPE(Char) \ + do { \ + long c = Char; \ + if (0 < c && c <= UCHAR_MAX) \ + obstack_1grow (&obstack_for_string, c); \ + else \ + { \ + complain (loc, complaint, \ + _("invalid number after \\-escape: %s"), \ + yytext + 1); \ + /* Avoid additional errors about empty char literal. */ \ + obstack_1grow (&obstack_for_string, '?'); \ + } \ + } while (0) + + /* The current file name. Might change with #line. */ static uniqstr current_file = NULL; @@ -619,22 +636,12 @@ eqopt ({sp}=)? { \\[0-7]{1,3} { verify (UCHAR_MAX < ULONG_MAX); - long c = strtol (yytext + 1, NULL, 8); - if (0 < c && c <= UCHAR_MAX) - obstack_1grow (&obstack_for_string, c); - else - complain (loc, complaint, _("invalid number after \\-escape: %s"), - yytext+1); + STRING_GROW_ESCAPE (strtol (yytext + 1, NULL, 8)); } \\x[0-9abcdefABCDEF]+ { verify (UCHAR_MAX < ULONG_MAX); - long c = strtol (yytext + 2, NULL, 16); - if (0 < c && c <= UCHAR_MAX) - obstack_1grow (&obstack_for_string, c); - else - complain (loc, complaint, _("invalid number after \\-escape: %s"), - yytext+1); + STRING_GROW_ESCAPE (strtol (yytext + 2, NULL, 16)); } \\a obstack_1grow (&obstack_for_string, '\a'); @@ -649,13 +656,9 @@ eqopt ({sp}=)? \\("\""|"'"|"?"|"\\") obstack_1grow (&obstack_for_string, yytext[1]); \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} { - int c = convert_ucn_to_byte (yytext); - if (c <= 0) - complain (loc, complaint, _("invalid number after \\-escape: %s"), - yytext+1); - else - obstack_1grow (&obstack_for_string, c); + STRING_GROW_ESCAPE (convert_ucn_to_byte (yytext)); } + \\(.|{eol}) { char const *p = yytext + 1; /* Quote only if escaping won't make the character visible. */ @@ -665,6 +668,7 @@ eqopt ({sp}=)? p = quotearg_style_mem (escape_quoting_style, p, 1); complain (loc, complaint, _("invalid character after \\-escape: %s"), p); + obstack_1grow (&obstack_for_string, '?'); } } diff --git a/tests/input.at b/tests/input.at index a5501b3e..97bd4e08 100644 --- a/tests/input.at +++ b/tests/input.at @@ -2408,25 +2408,15 @@ AT_PERL_REQUIRE([[-e 'print "start: \"\\\t\\\f\\\0\\\1\" ;";' >> input.y]]) AT_BISON_CHECK([input.y], [1], [], [[input.y:2.9-12: error: invalid number after \-escape: 777 -input.y:2.8-13: error: empty character literal input.y:2.16-17: error: invalid number after \-escape: 0 -input.y:2.15-18: error: empty character literal input.y:2.21-25: error: invalid number after \-escape: xfff -input.y:2.20-26: error: empty character literal input.y:2.29-31: error: invalid number after \-escape: x0 -input.y:2.28-32: error: empty character literal input.y:3.9-14: error: invalid number after \-escape: uffff -input.y:3.8-15: error: empty character literal input.y:3.18-23: error: invalid number after \-escape: u0000 -input.y:3.17-24: error: empty character literal input.y:3.27-36: error: invalid number after \-escape: Uffffffff -input.y:3.26-37: error: empty character literal input.y:3.40-49: error: invalid number after \-escape: U00000000 -input.y:3.39-50: error: empty character literal input.y:4.9-10: error: invalid character after \-escape: ' ' -input.y:4.8-11: error: empty character literal input.y:4.14-15: error: invalid character after \-escape: A -input.y:4.13-16: error: empty character literal input.y:5.9-16: error: invalid character after \-escape: \t input.y:5.17: error: invalid character after \-escape: \f input.y:5.18: error: invalid character after \-escape: \0