X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/ac9b0e954b1d3aed514a3bbd363da1514202af0f..468455e12b995d4b44a648cb47b749ead4453bae:/src/scan-gram.l diff --git a/src/scan-gram.l b/src/scan-gram.l index 0c12cbaa..dbea2a1d 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -1,7 +1,6 @@ /* Bison Grammar Scanner -*- C -*- - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free - Software Foundation, Inc. + Copyright (C) 2002-2012 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -18,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -%option debug nodefault nounput noyywrap never-interactive +%option debug nodefault noinput nounput noyywrap never-interactive %option prefix="gram_" outfile="lex.yy.c" %{ @@ -37,6 +36,7 @@ #include "reader.h" #include "uniqstr.h" +#include #include #include @@ -88,11 +88,11 @@ static void unexpected_newline (boundary, char const *); /* Strings and characters in directives/rules. */ %x SC_ESCAPED_STRING SC_ESCAPED_CHARACTER /* A identifier was just read in directives/rules. Special state - to capture the sequence `identifier :'. */ + to capture the sequence 'identifier :'. */ %x SC_AFTER_IDENTIFIER /* Three types of user code: - - prologue (code between `%{' `%}' in the first section, before %%); + - prologue (code between '%{' '%}' in the first section, before %%); - actions, printers, union, etc, (between braced in the middle section); - epilogue (everything after the second %%). */ %x SC_PROLOGUE SC_BRACED_CODE SC_EPILOGUE @@ -103,8 +103,8 @@ static void unexpected_newline (boundary, char const *); /* Bracketed identifiers support. */ %x SC_BRACKETED_ID SC_RETURN_BRACKETED_ID -letter [-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] -id {letter}({letter}|[0-9])* +letter [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] +id {letter}({letter}|[-0-9])* directive %{id} int [0-9]+ @@ -120,13 +120,13 @@ splice (\\[ \f\t\v]*\n)* %% %{ /* Nesting level of the current code in braces. */ - int braces_level IF_LINT (= 0); + int braces_level PACIFY_CC (= 0); /* Parent context state, when applicable. */ - int context_state IF_LINT (= 0); + int context_state PACIFY_CC (= 0); /* Location of most recent identifier, when applicable. */ - location id_loc IF_LINT (= empty_location); + location id_loc PACIFY_CC (= empty_location); /* Where containing code started, when applicable. Its initial value is relevant only when yylex is invoked in the SC_EPILOGUE @@ -135,7 +135,7 @@ splice (\\[ \f\t\v]*\n)* /* Where containing comment or string or character literal started, when applicable. */ - boundary token_start IF_LINT (= scanner_cursor); + boundary token_start PACIFY_CC (= scanner_cursor); %} @@ -146,7 +146,7 @@ splice (\\[ \f\t\v]*\n)* { /* Comments and white space. */ - "," warn_at (*loc, _("stray `,' treated as white space")); + "," warn_at (*loc, _("stray ',' treated as white space")); [ \f\n\t\v] | "//".* ; "/*" { @@ -251,7 +251,7 @@ splice (\\[ \f\t\v]*\n)* } /* Characters. */ - "'" STRING_GROW; token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER; + "'" token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER; /* Strings. */ "\"" token_start = loc->start; BEGIN SC_ESCAPED_STRING; @@ -397,7 +397,7 @@ splice (\\[ \f\t\v]*\n)* /*---------------------------------------------------------------. - | Scanning a Yacc comment. The initial `/ *' is already eaten. | + | Scanning a Yacc comment. The initial '/ *' is already eaten. | `---------------------------------------------------------------*/ @@ -409,7 +409,7 @@ splice (\\[ \f\t\v]*\n)* /*------------------------------------------------------------. - | Scanning a C comment. The initial `/ *' is already eaten. | + | Scanning a C comment. The initial '/ *' is already eaten. | `------------------------------------------------------------*/ @@ -420,7 +420,7 @@ splice (\\[ \f\t\v]*\n)* /*--------------------------------------------------------------. - | Scanning a line comment. The initial `//' is already eaten. | + | Scanning a line comment. The initial '//' is already eaten. | `--------------------------------------------------------------*/ @@ -465,16 +465,18 @@ splice (\\[ \f\t\v]*\n)* { "'"|"\n" { - STRING_GROW; STRING_FINISH; loc->start = token_start; - val->character = last_string[1]; + val->character = last_string[0]; { /* FIXME: Eventually, make these errors. */ - size_t length = strlen (last_string); - if (strlen (last_string) < 3) - warn_at (*loc, _("empty character literal")); - else if (strlen (last_string) > 3) + if (last_string[0] == '\0') + { + warn_at (*loc, _("empty character literal")); + /* '\0' seems dangerous even if we are about to complain. */ + val->character = '\''; + } + else if (last_string[1] != '\0') warn_at (*loc, _("extra characters in character literal")); } if (yytext[0] == '\n') @@ -486,17 +488,17 @@ splice (\\[ \f\t\v]*\n)* <> { STRING_FINISH; loc->start = token_start; + val->character = last_string[0]; { - size_t length = strlen (last_string); /* FIXME: Eventually, make these errors. */ - if (length < 2) - warn_at (*loc, _("empty character literal")); - else if (length > 2) + if (last_string[0] == '\0') + { + warn_at (*loc, _("empty character literal")); + /* '\0' seems dangerous even if we are about to complain. */ + val->character = '\''; + } + else if (last_string[1] != '\0') warn_at (*loc, _("extra characters in character literal")); - if (length > 1) - val->character = last_string[1]; - else - val->character = last_string[0]; } unexpected_eof (token_start, "'"); STRING_FREE; @@ -519,10 +521,9 @@ splice (\\[ \f\t\v]*\n)* { \\[0-7]{1,3} { unsigned long int c = strtoul (yytext + 1, NULL, 8); - if (UCHAR_MAX < c) - complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext)); - else if (! c) - complain_at (*loc, _("invalid null character: %s"), quote (yytext)); + if (!c || UCHAR_MAX < c) + complain_at (*loc, _("invalid number after \\-escape: %s"), + yytext+1); else obstack_1grow (&obstack_for_string, c); } @@ -530,10 +531,9 @@ splice (\\[ \f\t\v]*\n)* \\x[0-9abcdefABCDEF]+ { verify (UCHAR_MAX < ULONG_MAX); unsigned long int c = strtoul (yytext + 2, NULL, 16); - if (UCHAR_MAX < c) - complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext)); - else if (! c) - complain_at (*loc, _("invalid null character: %s"), quote (yytext)); + if (!c || UCHAR_MAX < c) + complain_at (*loc, _("invalid number after \\-escape: %s"), + yytext+1); else obstack_1grow (&obstack_for_string, c); } @@ -551,16 +551,20 @@ splice (\\[ \f\t\v]*\n)* \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} { int c = convert_ucn_to_byte (yytext); - if (c < 0) - complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext)); - else if (! c) - complain_at (*loc, _("invalid null character: %s"), quote (yytext)); + if (c <= 0) + complain_at (*loc, _("invalid number after \\-escape: %s"), + yytext+1); else obstack_1grow (&obstack_for_string, c); } \\(.|\n) { - complain_at (*loc, _("unrecognized escape sequence: %s"), quote (yytext)); - STRING_GROW; + char const *p = yytext + 1; + /* Quote only if escaping won't make the character visible. */ + if (c_isspace ((unsigned char) *p) && c_isprint ((unsigned char) *p)) + p = quote (p); + else + p = quotearg_style_mem (escape_quoting_style, p, 1); + complain_at (*loc, _("invalid character after \\-escape: %s"), p); } } @@ -644,8 +648,8 @@ splice (\\[ \f\t\v]*\n)* } } - /* Tokenize `<<%' correctly (as `<<' `%') rather than incorrrectly - (as `<' `<%'). */ + /* Tokenize '<<%' correctly (as '<<' '%') rather than incorrrectly + (as '<' '<%'). */ "<"{splice}"<" STRING_GROW; <> { @@ -836,7 +840,7 @@ convert_ucn_to_byte (char const *ucn) /*----------------------------------------------------------------. -| Handle `#line INT "FILE"'. ARGS has already skipped `#line '. | +| Handle '#line INT "FILE"'. ARGS has already skipped '#line '. | `----------------------------------------------------------------*/ static void @@ -844,8 +848,8 @@ handle_syncline (char *args, location loc) { char *after_num; unsigned long int lineno = strtoul (args, &after_num, 10); - char *file = strchr (after_num, '"') + 1; - *strchr (file, '"') = '\0'; + char *file = mbschr (after_num, '"') + 1; + *mbschr (file, '"') = '\0'; if (INT_MAX <= lineno) { warn_at (loc, _("line number overflow")); @@ -868,6 +872,10 @@ unexpected_end (boundary start, char const *msgid, char const *token_end) location loc; loc.start = start; loc.end = scanner_cursor; + token_end = quote (token_end); + // Instead of '\'', display "'". + if (!strcmp (token_end, "'\\''")) + token_end = "\"'\""; complain_at (loc, _(msgid), token_end); } @@ -880,7 +888,7 @@ unexpected_end (boundary start, char const *msgid, char const *token_end) static void unexpected_eof (boundary start, char const *token_end) { - unexpected_end (start, N_("missing `%s' at end of file"), token_end); + unexpected_end (start, N_("missing %s at end of file"), token_end); } @@ -891,7 +899,7 @@ unexpected_eof (boundary start, char const *token_end) static void unexpected_newline (boundary start, char const *token_end) { - unexpected_end (start, N_("missing `%s' at end of line"), token_end); + unexpected_end (start, N_("missing %s at end of line"), token_end); }