]> git.saurik.com Git - bison.git/blobdiff - src/scan-gram.l
Merge remote-tracking branch 'origin/maint'
[bison.git] / src / scan-gram.l
index b3a50988f4af0afef2ed89b325f935286aa21995..2275d022b7ffac51f2f11133859bad8a71dde4b8 100644 (file)
@@ -1,6 +1,6 @@
 /* Bison Grammar Scanner                             -*- C -*-
 
-   Copyright (C) 2002-2011 Free Software Foundation, Inc.
+   Copyright (C) 2002-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
@@ -36,7 +36,7 @@
 #include <src/reader.h>
 #include <src/uniqstr.h>
 
-#include <ctype.h>
+#include <c-ctype.h>
 #include <mbswidth.h>
 #include <quote.h>
 
@@ -44,8 +44,8 @@
 
 #define YY_DECL GRAM_LEX_DECL
 
-#define YY_USER_INIT                                   \
-   code_start = scanner_cursor = loc->start;           \
+#define YY_USER_INIT                                    \
+   code_start = scanner_cursor = loc->start;            \
 
 /* Location of scanner cursor.  */
 static boundary scanner_cursor;
@@ -69,7 +69,7 @@ static size_t no_cr_read (FILE *, char *, size_t);
 
 #define ROLLBACK_CURRENT_TOKEN                                  \
   do {                                                          \
-    scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0);    \
+    scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0);     \
     yyless (0);                                                 \
   } while (0)
 
@@ -100,16 +100,16 @@ 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
  /* A complex tag, with nested angles brackets. */
 %x SC_TAG
 
  /* Four 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 %%). 
-    - predicate (code between `%?{' and `{' in middle section); */
+    - epilogue (everything after the second %%).
+    - predicate (code between '%?{' and '{' in middle section); */
 %x SC_PROLOGUE SC_BRACED_CODE SC_EPILOGUE SC_PREDICATE
  /* C and C++ comments in code. */
 %x SC_COMMENT SC_LINE_COMMENT
@@ -118,33 +118,33 @@ 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]+
+int       [0-9]+
 
 /* POSIX says that a tag must be both an id and a C union member, but
    historically almost any character is allowed in a tag.  We disallow
    NUL, as this simplifies our implementation.  We disallow angle
    bracket to match them in nested pairs: several languages use them
    for generics/template types.  */
-tag     [^\0<>]+
+tag      [^\0<>]+
 
 /* Zero or more instances of backslash-newline.  Following GCC, allow
    white space between the backslash and the newline.  */
-splice  (\\[ \f\t\v]*\n)*
+splice   (\\[ \f\t\v]*\n)*
 
 %%
 %{
   /* Nesting level.  Either for nested braces, or nested angle brackets
      (but not mixed).  */
-  int nesting IF_LINT (= 0);
+  int nesting 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
@@ -153,7 +153,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);
 %}
 
 
@@ -164,7 +164,9 @@ splice       (\\[ \f\t\v]*\n)*
 <INITIAL,SC_AFTER_IDENTIFIER,SC_BRACKETED_ID,SC_RETURN_BRACKETED_ID>
 {
   /* Comments and white space.  */
-  ","         warn_at (*loc, _("stray `,' treated as white space"));
+  "," {
+     complain_at (*loc, Wother, _("stray ',' treated as white space"));
+  }
   [ \f\n\t\v]  |
   "//".*       ;
   "/*" {
@@ -186,7 +188,7 @@ splice       (\\[ \f\t\v]*\n)*
   `----------------------------*/
 
   /* For directives that are also command line options, the regex must be
-       "%..."
+        "%..."
      after "[-_]"s are removed, and the directive must match the --long
      option name, with a single string argument.  Otherwise, add exceptions
      to ../build-aux/cross-options.pl.  */
@@ -239,7 +241,7 @@ splice       (\\[ \f\t\v]*\n)*
   "%yacc"                           return PERCENT_YACC;
 
   {directive} {
-    complain_at (*loc, _("invalid directive: %s"), quote (yytext));
+    complain_at (*loc, complaint, _("invalid directive: %s"), quote (yytext));
   }
 
   "="                     return EQUAL;
@@ -265,14 +267,14 @@ splice     (\\[ \f\t\v]*\n)*
   /* Identifiers may not start with a digit.  Yet, don't silently
      accept "1FOO" as "1 FOO".  */
   {int}{id} {
-    complain_at (*loc, _("invalid identifier: %s"), quote (yytext));
+    complain_at (*loc, complaint, _("invalid identifier: %s"), quote (yytext));
   }
 
   /* Characters.  */
-  "'"        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;
+  "\""        token_start = loc->start; BEGIN SC_ESCAPED_STRING;
 
   /* Prologue. */
   "%{"        code_start = loc->start; BEGIN SC_PROLOGUE;
@@ -323,7 +325,7 @@ splice       (\\[ \f\t\v]*\n)*
   }
 
   . {
-    complain_at (*loc, _("invalid character: %s"), quote (yytext));
+    complain_at (*loc, complaint, _("invalid character: %s"), quote (yytext));
   }
 
   <<EOF>> {
@@ -340,7 +342,7 @@ splice       (\\[ \f\t\v]*\n)*
 
 <SC_ESCAPED_CHARACTER,SC_ESCAPED_STRING,SC_TAG>
 {
-  \0       complain_at (*loc, _("invalid null character"));
+  \0        complain_at (*loc, complaint, _("invalid null character"));
 }
 
 
@@ -353,16 +355,16 @@ splice     (\\[ \f\t\v]*\n)*
   "[" {
     if (bracketed_id_str)
       {
-       ROLLBACK_CURRENT_TOKEN;
-       BEGIN SC_RETURN_BRACKETED_ID;
-       *loc = id_loc;
-       return ID;
+        ROLLBACK_CURRENT_TOKEN;
+        BEGIN SC_RETURN_BRACKETED_ID;
+        *loc = id_loc;
+        return ID;
       }
     else
       {
-       bracketed_id_start = loc->start;
-       bracketed_id_context_state = YY_START;
-       BEGIN SC_BRACKETED_ID;
+        bracketed_id_start = loc->start;
+        bracketed_id_context_state = YY_START;
+        BEGIN SC_BRACKETED_ID;
       }
   }
   ":" {
@@ -392,33 +394,34 @@ splice     (\\[ \f\t\v]*\n)*
   {id} {
     if (bracketed_id_str)
       {
-       complain_at (*loc, _("unexpected identifier in bracketed name: %s"),
-                    quote (yytext));
+        complain_at (*loc, complaint,
+                     _("unexpected identifier in bracketed name: %s"),
+                     quote (yytext));
       }
     else
       {
-       bracketed_id_str = uniqstr_new (yytext);
-       bracketed_id_loc = *loc;
+        bracketed_id_str = uniqstr_new (yytext);
+        bracketed_id_loc = *loc;
       }
   }
   "]" {
     BEGIN bracketed_id_context_state;
     if (bracketed_id_str)
       {
-       if (INITIAL == bracketed_id_context_state)
-         {
-           val->uniqstr = bracketed_id_str;
-           bracketed_id_str = 0;
-           *loc = bracketed_id_loc;
-           return BRACKETED_ID;
-         }
+        if (INITIAL == bracketed_id_context_state)
+          {
+            val->uniqstr = bracketed_id_str;
+            bracketed_id_str = 0;
+            *loc = bracketed_id_loc;
+            return BRACKETED_ID;
+          }
       }
     else
-      complain_at (*loc, _("an identifier expected"));
+      complain_at (*loc, complaint, _("an identifier expected"));
   }
   . {
-    complain_at (*loc, _("invalid character in bracketed name: %s"),
-                quote (yytext));
+    complain_at (*loc, complaint, _("invalid character in bracketed name: %s"),
+                 quote (yytext));
   }
   <<EOF>> {
     BEGIN bracketed_id_context_state;
@@ -440,37 +443,37 @@ splice     (\\[ \f\t\v]*\n)*
 
 
   /*---------------------------------------------------------------.
-  | Scanning a Yacc comment.  The initial `/ *' is already eaten.  |
+  | Scanning a Yacc comment.  The initial '/ *' is already eaten.  |
   `---------------------------------------------------------------*/
 
 <SC_YACC_COMMENT>
 {
   "*/"     BEGIN context_state;
-  .|\n    ;
+  .|\n     ;
   <<EOF>>  unexpected_eof (token_start, "*/"); BEGIN context_state;
 }
 
 
   /*------------------------------------------------------------.
-  | Scanning a C comment.  The initial `/ *' is already eaten.  |
+  | Scanning a C comment.  The initial '/ *' is already eaten.  |
   `------------------------------------------------------------*/
 
 <SC_COMMENT>
 {
   "*"{splice}"/"  STRING_GROW; BEGIN context_state;
-  <<EOF>>        unexpected_eof (token_start, "*/"); BEGIN context_state;
+  <<EOF>>         unexpected_eof (token_start, "*/"); BEGIN context_state;
 }
 
 
   /*--------------------------------------------------------------.
-  | Scanning a line comment.  The initial `//' is already eaten.  |
+  | Scanning a line comment.  The initial '//' is already eaten.  |
   `--------------------------------------------------------------*/
 
 <SC_LINE_COMMENT>
 {
-  "\n"          STRING_GROW; BEGIN context_state;
-  {splice}      STRING_GROW;
-  <<EOF>>       BEGIN context_state;
+  "\n"           STRING_GROW; BEGIN context_state;
+  {splice}       STRING_GROW;
+  <<EOF>>        BEGIN context_state;
 }
 
 
@@ -502,7 +505,7 @@ splice       (\\[ \f\t\v]*\n)*
 
   /*----------------------------------------------------------.
   | Scanning a Bison character literal, decoding its escapes. |
-  | The initial quote is already eaten.                              |
+  | The initial quote is already eaten.                       |
   `----------------------------------------------------------*/
 
 <SC_ESCAPED_CHARACTER>
@@ -515,12 +518,13 @@ splice     (\\[ \f\t\v]*\n)*
       /* FIXME: Eventually, make these errors.  */
       if (last_string[0] == '\0')
         {
-          warn_at (*loc, _("empty character literal"));
+          complain_at (*loc, Wother, _("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"));
+        complain_at (*loc, Wother,
+                  _("extra characters in character literal"));
     }
     if (yytext[0] == '\n')
       unexpected_newline (token_start, "'");
@@ -536,12 +540,13 @@ splice     (\\[ \f\t\v]*\n)*
       /* FIXME: Eventually, make these errors.  */
       if (last_string[0] == '\0')
         {
-          warn_at (*loc, _("empty character literal"));
+          complain_at (*loc, Wother, _("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"));
+        complain_at (*loc, Wother,
+                  _("extra characters in character literal"));
     }
     unexpected_eof (token_start, "'");
     STRING_FREE;
@@ -594,7 +599,7 @@ splice       (\\[ \f\t\v]*\n)*
   \\[0-7]{1,3} {
     unsigned long int c = strtoul (yytext + 1, NULL, 8);
     if (!c || UCHAR_MAX < c)
-      complain_at (*loc, _("invalid number after \\-escape: %s"),
+      complain_at (*loc, complaint, _("invalid number after \\-escape: %s"),
                    yytext+1);
     else
       obstack_1grow (&obstack_for_string, c);
@@ -604,19 +609,19 @@ splice     (\\[ \f\t\v]*\n)*
     verify (UCHAR_MAX < ULONG_MAX);
     unsigned long int c = strtoul (yytext + 2, NULL, 16);
     if (!c || UCHAR_MAX < c)
-      complain_at (*loc, _("invalid number after \\-escape: %s"),
+      complain_at (*loc, complaint, _("invalid number after \\-escape: %s"),
                    yytext+1);
     else
       obstack_1grow (&obstack_for_string, c);
   }
 
-  \\a  obstack_1grow (&obstack_for_string, '\a');
-  \\b  obstack_1grow (&obstack_for_string, '\b');
-  \\f  obstack_1grow (&obstack_for_string, '\f');
-  \\n  obstack_1grow (&obstack_for_string, '\n');
-  \\r  obstack_1grow (&obstack_for_string, '\r');
-  \\t  obstack_1grow (&obstack_for_string, '\t');
-  \\v  obstack_1grow (&obstack_for_string, '\v');
+  \\a   obstack_1grow (&obstack_for_string, '\a');
+  \\b   obstack_1grow (&obstack_for_string, '\b');
+  \\f   obstack_1grow (&obstack_for_string, '\f');
+  \\n   obstack_1grow (&obstack_for_string, '\n');
+  \\r   obstack_1grow (&obstack_for_string, '\r');
+  \\t   obstack_1grow (&obstack_for_string, '\t');
+  \\v   obstack_1grow (&obstack_for_string, '\v');
 
   /* \\[\"\'?\\] would be shorter, but it confuses xgettext.  */
   \\("\""|"'"|"?"|"\\")  obstack_1grow (&obstack_for_string, yytext[1]);
@@ -624,19 +629,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 number after \\-escape: %s"),
+      complain_at (*loc, complaint, _("invalid number after \\-escape: %s"),
                    yytext+1);
     else
       obstack_1grow (&obstack_for_string, c);
   }
-  \\(.|\n)     {
+  \\(.|\n)      {
     char const *p = yytext + 1;
     /* Quote only if escaping won't make the character visible.  */
-    if (isspace ((unsigned char) *p) && isprint ((unsigned char) *p))
+    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);
+    complain_at (*loc, complaint, _("invalid character after \\-escape: %s"),
+                 p);
   }
 }
 
@@ -646,21 +652,21 @@ splice     (\\[ \f\t\v]*\n)*
 
 <SC_CHARACTER,SC_STRING>
 {
-  {splice}|\\{splice}[^\n\[\]] STRING_GROW;
+  {splice}|\\{splice}[^\n\[\]]  STRING_GROW;
 }
 
 <SC_CHARACTER>
 {
-  "'"          STRING_GROW; BEGIN context_state;
-  \n           unexpected_newline (token_start, "'"); BEGIN context_state;
-  <<EOF>>      unexpected_eof (token_start, "'"); BEGIN context_state;
+  "'"           STRING_GROW; BEGIN context_state;
+  \n            unexpected_newline (token_start, "'"); BEGIN context_state;
+  <<EOF>>       unexpected_eof (token_start, "'"); BEGIN context_state;
 }
 
 <SC_STRING>
 {
-  "\""         STRING_GROW; BEGIN context_state;
-  \n           unexpected_newline (token_start, "\""); BEGIN context_state;
-  <<EOF>>      unexpected_eof (token_start, "\""); BEGIN context_state;
+  "\""          STRING_GROW; BEGIN context_state;
+  \n            unexpected_newline (token_start, "\""); BEGIN context_state;
+  <<EOF>>       unexpected_eof (token_start, "\""); BEGIN context_state;
 }
 
 
@@ -707,8 +713,8 @@ splice       (\\[ \f\t\v]*\n)*
   "{"|"<"{splice}"%"  STRING_GROW; nesting++;
   "%"{splice}">"      STRING_GROW; nesting--;
 
-  /* Tokenize `<<%' correctly (as `<<' `%') rather than incorrrectly
-     (as `<' `<%').  */
+  /* Tokenize '<<%' correctly (as '<<' '%') rather than incorrrectly
+     (as '<' '<%').  */
   "<"{splice}"<"  STRING_GROW;
 
   <<EOF>> {
@@ -730,11 +736,11 @@ splice     (\\[ \f\t\v]*\n)*
     --nesting;
     if (nesting < 0)
       {
-       STRING_FINISH;
-       loc->start = code_start;
-       val->code = last_string;
-       BEGIN INITIAL;
-       return BRACED_CODE;
+        STRING_FINISH;
+        loc->start = code_start;
+        val->code = last_string;
+        BEGIN INITIAL;
+        return BRACED_CODE;
       }
   }
 }
@@ -745,11 +751,11 @@ splice     (\\[ \f\t\v]*\n)*
     --nesting;
     if (nesting < 0)
       {
-       STRING_FINISH;
-       loc->start = code_start;
-       val->code = last_string;
-       BEGIN INITIAL;
-       return BRACED_PREDICATE;
+        STRING_FINISH;
+        loc->start = code_start;
+        val->code = last_string;
+        BEGIN INITIAL;
+        return BRACED_PREDICATE;
       }
     else
       obstack_1grow (&obstack_for_string, '}');
@@ -802,8 +808,8 @@ splice       (\\[ \f\t\v]*\n)*
   | By default, grow the string obstack with the input.  |
   `-----------------------------------------------------*/
 
-<SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PREDICATE,SC_PROLOGUE,SC_EPILOGUE,SC_STRING,SC_CHARACTER,SC_ESCAPED_STRING,SC_ESCAPED_CHARACTER>.        |
-  <SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PREDICATE,SC_PROLOGUE,SC_EPILOGUE>\n   STRING_GROW;
+<SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PREDICATE,SC_PROLOGUE,SC_EPILOGUE,SC_STRING,SC_CHARACTER,SC_ESCAPED_STRING,SC_ESCAPED_CHARACTER>. |
+  <SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PREDICATE,SC_PROLOGUE,SC_EPILOGUE>\n    STRING_GROW;
 
 %%
 
@@ -819,35 +825,35 @@ no_cr_read (FILE *fp, char *buf, size_t size)
     {
       char *w = memchr (buf, '\r', bytes_read);
       if (w)
-       {
-         char const *r = ++w;
-         char const *lim = buf + bytes_read;
-
-         for (;;)
-           {
-             /* Found an '\r'.  Treat it like '\n', but ignore any
-                '\n' that immediately follows.  */
-             w[-1] = '\n';
-             if (r == lim)
-               {
-                 int ch = getc (fp);
-                 if (ch != '\n' && ungetc (ch, fp) != ch)
-                   break;
-               }
-             else if (*r == '\n')
-               r++;
-
-             /* Copy until the next '\r'.  */
-             do
-               {
-                 if (r == lim)
-                   return w - buf;
-               }
-             while ((*w++ = *r++) != '\r');
-           }
-
-         return w - buf;
-       }
+        {
+          char const *r = ++w;
+          char const *lim = buf + bytes_read;
+
+          for (;;)
+            {
+              /* Found an '\r'.  Treat it like '\n', but ignore any
+                 '\n' that immediately follows.  */
+              w[-1] = '\n';
+              if (r == lim)
+                {
+                  int ch = getc (fp);
+                  if (ch != '\n' && ungetc (ch, fp) != ch)
+                    break;
+                }
+              else if (*r == '\n')
+                r++;
+
+              /* Copy until the next '\r'.  */
+              do
+                {
+                  if (r == lim)
+                    return w - buf;
+                }
+              while ((*w++ = *r++) != '\r');
+            }
+
+          return w - buf;
+        }
     }
 
   return bytes_read;
@@ -867,7 +873,8 @@ scan_integer (char const *number, int base, location loc)
 
   if (INT_MAX < num)
     {
-      complain_at (loc, _("integer out of range: %s"), quote (number));
+      complain_at (loc, complaint, _("integer out of range: %s"),
+                   quote (number));
       num = INT_MAX;
     }
 
@@ -878,7 +885,7 @@ scan_integer (char const *number, int base, location loc)
 /*------------------------------------------------------------------.
 | Convert universal character name UCN to a single-byte character,  |
 | and return that character.  Return -1 if UCN does not correspond  |
-| to a single-byte character.                                      |
+| to a single-byte character.                                       |
 `------------------------------------------------------------------*/
 
 static int
@@ -906,22 +913,22 @@ convert_ucn_to_byte (char const *ucn)
        about.  */
     static signed char const table[] =
       {
-       '\0',   -1,   -1,   -1,   -1,   -1,   -1, '\a',
-       '\b', '\t', '\n', '\v', '\f', '\r',   -1,   -1,
-         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-         -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-        ' ',  '!',  '"',  '#',  '$',  '%',  '&', '\'',
-        '(',  ')',  '*',  '+',  ',',  '-',  '.',  '/',
-        '0',  '1',  '2',  '3',  '4',  '5',  '6',  '7',
-        '8',  '9',  ':',  ';',  '<',  '=',  '>',  '?',
-        '@',  'A',  'B',  'C',  'D',  'E',  'F',  'G',
-        'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',
-        'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',
-        'X',  'Y',  'Z',  '[', '\\',  ']',  '^',  '_',
-        '`',  'a',  'b',  'c',  'd',  'e',  'f',  'g',
-        'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
-        'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
-        'x',  'y',  'z',  '{',  '|',  '}',  '~'
+        '\0',   -1,   -1,   -1,   -1,   -1,   -1, '\a',
+        '\b', '\t', '\n', '\v', '\f', '\r',   -1,   -1,
+          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+          -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+         ' ',  '!',  '"',  '#',  '$',  '%',  '&', '\'',
+         '(',  ')',  '*',  '+',  ',',  '-',  '.',  '/',
+         '0',  '1',  '2',  '3',  '4',  '5',  '6',  '7',
+         '8',  '9',  ':',  ';',  '<',  '=',  '>',  '?',
+         '@',  'A',  'B',  'C',  'D',  'E',  'F',  'G',
+         'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',
+         'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',
+         'X',  'Y',  'Z',  '[', '\\',  ']',  '^',  '_',
+         '`',  'a',  'b',  'c',  'd',  'e',  'f',  'g',
+         'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
+         'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
+         'x',  'y',  'z',  '{',  '|',  '}',  '~'
       };
 
     code = code < sizeof table ? table[code] : -1;
@@ -933,7 +940,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
@@ -945,7 +952,7 @@ handle_syncline (char *args, location loc)
   *strchr (file, '"') = '\0';
   if (INT_MAX <= lineno)
     {
-      warn_at (loc, _("line number overflow"));
+      complain_at (loc, Wother, _("line number overflow"));
       lineno = INT_MAX;
     }
   current_file = uniqstr_new (file);
@@ -955,8 +962,8 @@ handle_syncline (char *args, location loc)
 
 /*----------------------------------------------------------------.
 | For a token or comment starting at START, report message MSGID, |
-| which should say that an end marker was found before           |
-| the expected TOKEN_END.                                        |
+| which should say that an end marker was found before            |
+| the expected TOKEN_END.                                         |
 `----------------------------------------------------------------*/
 
 static void
@@ -965,7 +972,11 @@ unexpected_end (boundary start, char const *msgid, char const *token_end)
   location loc;
   loc.start = start;
   loc.end = scanner_cursor;
-  complain_at (loc, _(msgid), token_end);
+  token_end = quote (token_end);
+  // Instead of '\'', display "'".
+  if (STREQ (token_end, "'\\''"))
+    token_end = "\"'\"";
+  complain_at (loc, complaint, _(msgid), token_end);
 }
 
 
@@ -977,7 +988,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);
 }
 
 
@@ -988,7 +999,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);
 }