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.
This commit is contained in:
Akim Demaille
2020-04-27 08:06:49 +02:00
parent 3262747c5b
commit 89c4e1becf
2 changed files with 22 additions and 28 deletions

View File

@@ -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, '?');
}
}

View File

@@ -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