]> git.saurik.com Git - bison.git/blobdiff - src/scan-gram.l
Do not use date ranges in copyright notices.
[bison.git] / src / scan-gram.l
index 279bba974b11922b773b88ce7b773cfce9353a23..9d3d34280b8de5ef60f6eb63fa0213e3ab5232c6 100644 (file)
@@ -1,6 +1,6 @@
 /* Bison Grammar Scanner                             -*- C -*-
 
 /* Bison Grammar Scanner                             -*- C -*-
 
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
    Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
@@ -18,7 +18,7 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-%option debug nodefault nounput noyywrap never-interactive
+%option debug nodefault noinput nounput noyywrap never-interactive
 %option prefix="gram_" outfile="lex.yy.c"
 
 %{
 %option prefix="gram_" outfile="lex.yy.c"
 
 %{
@@ -37,6 +37,7 @@
 #include <src/reader.h>
 #include <src/uniqstr.h>
 
 #include <src/reader.h>
 #include <src/uniqstr.h>
 
+#include <ctype.h>
 #include <mbswidth.h>
 #include <quote.h>
 
 #include <mbswidth.h>
 #include <quote.h>
 
@@ -55,10 +56,16 @@ static boundary scanner_cursor;
 static size_t no_cr_read (FILE *, char *, size_t);
 #define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
 
 static size_t no_cr_read (FILE *, char *, size_t);
 #define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
 
-#define RETURN_PERCENT_FLAG(Value)              \
+#define RETURN_PERCENT_PARAM(Value)                     \
+  RETURN_VALUE(PERCENT_PARAM, param, param_ ## Value)
+
+#define RETURN_PERCENT_FLAG(Value)                              \
+  RETURN_VALUE(PERCENT_FLAG, uniqstr, uniqstr_new (Value))
+
+#define RETURN_VALUE(Token, Field, Value)       \
   do {                                          \
   do {                                          \
-    val->uniqstr = uniqstr_new (Value);         \
-    return PERCENT_FLAG;                        \
+    val->Field = Value;                         \
+    return Token;                               \
   } while (0)
 
 #define ROLLBACK_CURRENT_TOKEN                                  \
   } while (0)
 
 #define ROLLBACK_CURRENT_TOKEN                                  \
@@ -70,7 +77,7 @@ static size_t no_cr_read (FILE *, char *, size_t);
 /* A string representing the most recently saved token.  */
 static char *last_string;
 
 /* A string representing the most recently saved token.  */
 static char *last_string;
 
-/* Bracketed identifier */
+/* Bracketed identifier. */
 static uniqstr bracketed_id_str = 0;
 static location bracketed_id_loc;
 static boundary bracketed_id_start;
 static uniqstr bracketed_id_str = 0;
 static location bracketed_id_loc;
 static boundary bracketed_id_start;
@@ -108,7 +115,7 @@ static void unexpected_newline (boundary, char const *);
 %x SC_COMMENT SC_LINE_COMMENT
  /* Strings and characters in code. */
 %x SC_STRING SC_CHARACTER
 %x SC_COMMENT SC_LINE_COMMENT
  /* Strings and characters in code. */
 %x SC_STRING SC_CHARACTER
- /* Bracketed identifiers support */
+ /* Bracketed identifiers support. */
 %x SC_BRACKETED_ID SC_RETURN_BRACKETED_ID
 
 letter   [-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]
 %x SC_BRACKETED_ID SC_RETURN_BRACKETED_ID
 
 letter   [-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]
@@ -203,7 +210,7 @@ splice       (\\[ \f\t\v]*\n)*
   "%glr-parser"                     return PERCENT_GLR_PARSER;
   "%language"                       return PERCENT_LANGUAGE;
   "%left"                           return PERCENT_LEFT;
   "%glr-parser"                     return PERCENT_GLR_PARSER;
   "%language"                       return PERCENT_LANGUAGE;
   "%left"                           return PERCENT_LEFT;
-  "%lex-param"                      return PERCENT_LEX_PARAM;
+  "%lex-param"                      RETURN_PERCENT_PARAM(lex);
   "%locations"                      RETURN_PERCENT_FLAG("locations");
   "%merge"                          return PERCENT_MERGE;
   "%name"[-_]"prefix"               return PERCENT_NAME_PREFIX;
   "%locations"                      RETURN_PERCENT_FLAG("locations");
   "%merge"                          return PERCENT_MERGE;
   "%name"[-_]"prefix"               return PERCENT_NAME_PREFIX;
@@ -213,7 +220,8 @@ splice       (\\[ \f\t\v]*\n)*
   "%nondeterministic-parser"        return PERCENT_NONDETERMINISTIC_PARSER;
   "%nterm"                          return PERCENT_NTERM;
   "%output"                         return PERCENT_OUTPUT;
   "%nondeterministic-parser"        return PERCENT_NONDETERMINISTIC_PARSER;
   "%nterm"                          return PERCENT_NTERM;
   "%output"                         return PERCENT_OUTPUT;
-  "%parse-param"                    return PERCENT_PARSE_PARAM;
+  "%param"                          RETURN_PERCENT_PARAM(both);
+  "%parse-param"                    RETURN_PERCENT_PARAM(parse);
   "%prec"                           return PERCENT_PREC;
   "%precedence"                     return PERCENT_PRECEDENCE;
   "%printer"                        return PERCENT_PRINTER;
   "%prec"                           return PERCENT_PREC;
   "%precedence"                     return PERCENT_PRECEDENCE;
   "%printer"                        return PERCENT_PRINTER;
@@ -260,8 +268,8 @@ splice       (\\[ \f\t\v]*\n)*
     complain_at (*loc, _("invalid identifier: %s"), quote (yytext));
   }
 
     complain_at (*loc, _("invalid identifier: %s"), quote (yytext));
   }
 
-  /* Characters.  We don't check there is only one.  */
-  "'"        STRING_GROW; token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
+  /* Characters.  */
+  "'"        token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
 
   /* Strings. */
   "\""       token_start = loc->start; BEGIN SC_ESCAPED_STRING;
 
   /* Strings. */
   "\""       token_start = loc->start; BEGIN SC_ESCAPED_STRING;
@@ -336,19 +344,19 @@ splice     (\\[ \f\t\v]*\n)*
 <SC_AFTER_IDENTIFIER>
 {
   "[" {
 <SC_AFTER_IDENTIFIER>
 {
   "[" {
-    if (!bracketed_id_str)
-      {
-       bracketed_id_start = loc->start;
-       bracketed_id_context_state = YY_START;
-       BEGIN SC_BRACKETED_ID;
-      }
-    else
+    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;
+      }
   }
   ":" {
     BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
   }
   ":" {
     BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
@@ -375,15 +383,15 @@ splice     (\\[ \f\t\v]*\n)*
 <SC_BRACKETED_ID>
 {
   {id} {
 <SC_BRACKETED_ID>
 {
   {id} {
-    if (!bracketed_id_str)
+    if (bracketed_id_str)
       {
       {
-       bracketed_id_str = uniqstr_new (yytext);
-       bracketed_id_loc = *loc;
+       complain_at (*loc, _("unexpected identifier in bracketed name: %s"),
+                    quote (yytext));
       }
     else
       {
       }
     else
       {
-       complain_at (*loc, _("redundant identifier in bracketed name: %s"),
-                    quote (yytext));
+       bracketed_id_str = uniqstr_new (yytext);
+       bracketed_id_loc = *loc;
       }
   }
   "]" {
       }
   }
   "]" {
@@ -399,7 +407,7 @@ splice       (\\[ \f\t\v]*\n)*
          }
       }
     else
          }
       }
     else
-      complain_at (*loc, _("a non empty identifier expected"));
+      complain_at (*loc, _("an identifier expected"));
   }
   . {
     complain_at (*loc, _("invalid character in bracketed name: %s"),
   }
   . {
     complain_at (*loc, _("invalid character in bracketed name: %s"),
@@ -493,24 +501,42 @@ splice     (\\[ \f\t\v]*\n)*
 <SC_ESCAPED_CHARACTER>
 {
   "'"|"\n" {
 <SC_ESCAPED_CHARACTER>
 {
   "'"|"\n" {
-    if (yytext[0] == '\n')
-      unexpected_newline (token_start, "'");
-    STRING_GROW;
     STRING_FINISH;
     loc->start = token_start;
     STRING_FINISH;
     loc->start = token_start;
-    val->character = last_string[1];
+    val->character = last_string[0];
+    {
+      /* FIXME: Eventually, make these errors.  */
+      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')
+      unexpected_newline (token_start, "'");
     STRING_FREE;
     BEGIN INITIAL;
     return CHAR;
   }
   <<EOF>> {
     STRING_FREE;
     BEGIN INITIAL;
     return CHAR;
   }
   <<EOF>> {
-    unexpected_eof (token_start, "'");
     STRING_FINISH;
     loc->start = token_start;
     STRING_FINISH;
     loc->start = token_start;
-    if (strlen (last_string) > 1)
-      val->character = last_string[1];
-    else
-      val->character = last_string[0];
+    val->character = last_string[0];
+    {
+      /* FIXME: Eventually, make these errors.  */
+      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"));
+    }
+    unexpected_eof (token_start, "'");
     STRING_FREE;
     BEGIN INITIAL;
     return CHAR;
     STRING_FREE;
     BEGIN INITIAL;
     return CHAR;
@@ -560,10 +586,9 @@ splice      (\\[ \f\t\v]*\n)*
 {
   \\[0-7]{1,3} {
     unsigned long int c = strtoul (yytext + 1, NULL, 8);
 {
   \\[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);
   }
     else
       obstack_1grow (&obstack_for_string, c);
   }
@@ -571,10 +596,9 @@ splice      (\\[ \f\t\v]*\n)*
   \\x[0-9abcdefABCDEF]+ {
     verify (UCHAR_MAX < ULONG_MAX);
     unsigned long int c = strtoul (yytext + 2, NULL, 16);
   \\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);
   }
     else
       obstack_1grow (&obstack_for_string, c);
   }
@@ -592,16 +616,20 @@ splice     (\\[ \f\t\v]*\n)*
 
   \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
     int c = convert_ucn_to_byte (yytext);
 
   \\(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)     {
     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 (isspace ((unsigned char) *p) && 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);
   }
 }
 
   }
 }