]> git.saurik.com Git - bison.git/blobdiff - src/scan-gram.l
Describe Yacc library, lex-param and parse-param changes.
[bison.git] / src / scan-gram.l
index ad20026711ceb298f850a16789b57c81771f6c9a..6f04435020d9a9b6e08c03248802d38efc5a3d00 100644 (file)
 #include "mbswidth.h"
 #include "complain.h"
 #include "quote.h"
+#include "struniq.h"
 #include "getargs.h"
 #include "gram.h"
 #include "reader.h"
 
-/* Each time we match a string, move the end cursor to its end. */
 #define YY_USER_INIT                           \
 do {                                           \
-  LOCATION_RESET (*yylloc);                    \
-  yylloc->file = infile;                       \
-   /* This is only to avoid GCC warnings. */   \
-  if (yycontrol) {;};                          \
+  LOCATION_RESET (*loc);                       \
+  loc->file = current_file;                    \
 } while (0)
 
-#define YY_USER_ACTION  extend_location (yylloc, yytext, yyleng);
-#define YY_STEP         LOCATION_STEP (*yylloc)
+/* Each time we match a string, move the end cursor to its end. */
+#define STEP  LOCATION_STEP (*loc)
+
+#define YY_USER_ACTION  extend_location (loc, yytext, yyleng);
 
 #define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
 
@@ -134,25 +134,34 @@ extend_location (location_t *loc, char const *token, int size)
    keep (to construct ID, STRINGS etc.).  Use the following macros to
    use it.
 
-   Use YY_OBS_GROW to append what has just been matched, and
-   YY_OBS_FINISH to end the string (it puts the ending 0).
-   YY_OBS_FINISH also stores this string in LAST_STRING, which can be
-   used, and which is used by YY_OBS_FREE to free the last string.  */
+   Use STRING_GROW to append what has just been matched, and
+   STRING_FINISH to end the string (it puts the ending 0).
+   STRING_FINISH also stores this string in LAST_STRING, which can be
+   used, and which is used by STRING_FREE to free the last string.  */
 
 static struct obstack string_obstack;
 
-#define YY_OBS_GROW   \
+/* A string representing the most recently saved token.  */
+static char *last_string;
+
+
+#define STRING_GROW   \
   obstack_grow (&string_obstack, yytext, yyleng)
 
-#define YY_OBS_FINISH                                  \
+#define STRING_FINISH                                  \
   do {                                                 \
     obstack_1grow (&string_obstack, '\0');             \
     last_string = obstack_finish (&string_obstack);    \
   } while (0)
 
-#define YY_OBS_FREE \
+#define STRING_FREE \
   obstack_free (&string_obstack, last_string)
 
+void
+scanner_last_string_free (void)
+{
+  STRING_FREE;
+}
 
 /* Within well-formed rules, RULE_LENGTH is the number of values in
    the current rule so far, which says where to find `$0' with respect
@@ -168,7 +177,7 @@ static void handle_at (braced_code_t code_kind,
                       char *cp, location_t location);
 static void handle_syncline (char *args, location_t *location);
 static int convert_ucn_to_byte (char const *hex_text);
-static void unexpected_end_of_file (location_t, char const *);
+static void unexpected_end_of_file (location_t *, char const *);
 
 %}
 %x SC_COMMENT SC_LINE_COMMENT SC_YACC_COMMENT
@@ -198,12 +207,9 @@ splice      (\\[ \f\t\v]*\n)*
   /* Scanner context when scanning C code.  */
   int c_context IF_LINT (= 0);
 
-  /* A string representing the most recently saved token.  */
-  char *last_string;
-
   /* At each yylex invocation, mark the current position as the
      start of the next token.  */
-  YY_STEP;
+  STEP;
 %}
 
 
@@ -248,22 +254,29 @@ splice     (\\[ \f\t\v]*\n)*
   "%yacc"                 return PERCENT_YACC;
 
   {directive}             {
-    complain_at (*yylloc, _("invalid directive: %s"), quote (yytext));
-    YY_STEP;
+    complain_at (*loc, _("invalid directive: %s"), quote (yytext));
+    STEP;
   }
 
-  ^"#line "{int}" \""[^\"]*"\"\n"   handle_syncline (yytext + strlen ("#line "), yylloc); YY_STEP;
+  ^"#line "{int}" \"".*"\"\n" {
+    handle_syncline (yytext + sizeof "#line " - 1, loc);
+    STEP;
+  }
 
   "="                     return EQUAL;
   ":"                     rule_length = 0; return COLON;
   "|"                     rule_length = 0; return PIPE;
-  ","                     return COMMA;
   ";"                     return SEMICOLON;
 
-  [ \f\n\t\v]  YY_STEP;
+  [ \f\n\t\v]  STEP;
+
+  "," {
+    warn_at (*loc, _("stray `,' treated as white space"));
+    STEP;
+  }
 
   {id}        {
-    yylval->symbol = symbol_get (yytext, *yylloc);
+    val->symbol = symbol_get (yytext, *loc);
     rule_length++;
     return ID;
   }
@@ -274,34 +287,35 @@ splice     (\\[ \f\t\v]*\n)*
     num = strtoul (yytext, 0, 10);
     if (INT_MAX < num || errno)
       {
-       complain_at (*yylloc, _("integer out of range: %s"), quote (yytext));
+       complain_at (*loc, _("integer out of range: %s"), quote (yytext));
        num = INT_MAX;
       }
-    yylval->integer = num;
+    val->integer = num;
     return INT;
   }
 
   /* Characters.  We don't check there is only one.  */
-  "'"         YY_OBS_GROW; BEGIN SC_ESCAPED_CHARACTER;
+  "'"         STRING_GROW; BEGIN SC_ESCAPED_CHARACTER;
 
   /* Strings. */
-  "\""        YY_OBS_GROW; BEGIN SC_ESCAPED_STRING;
+  "\""        STRING_GROW; BEGIN SC_ESCAPED_STRING;
 
   /* Comments. */
   "/*"        BEGIN SC_YACC_COMMENT;
-  "//".*      YY_STEP;
+  "//".*      STEP;
 
   /* Prologue. */
   "%{"        BEGIN SC_PROLOGUE;
 
   /* Code in between braces.  */
-  "{"         YY_OBS_GROW; braces_level = 0; BEGIN SC_BRACED_CODE;
+  "{"         STRING_GROW; braces_level = 0; BEGIN SC_BRACED_CODE;
 
   /* A type. */
   "<"{tag}">" {
     obstack_grow (&string_obstack, yytext + 1, yyleng - 2);
-    YY_OBS_FINISH;
-    yylval->string = last_string;
+    STRING_FINISH;
+    val->struniq = struniq_new (last_string);
+    STRING_FREE;
     return TYPE;
   }
 
@@ -313,8 +327,8 @@ splice       (\\[ \f\t\v]*\n)*
   }
 
   . {
-    complain_at (*yylloc, _("invalid character: %s"), quote (yytext));
-    YY_STEP;
+    complain_at (*loc, _("invalid character: %s"), quote (yytext));
+    STEP;
   }
 }
 
@@ -326,12 +340,12 @@ splice     (\\[ \f\t\v]*\n)*
 <SC_YACC_COMMENT>
 {
   "*/" {
-    YY_STEP;
+    STEP;
     BEGIN INITIAL;
   }
 
   .|\n    ;
-  <<EOF>>  unexpected_end_of_file (*yylloc, "*/");
+  <<EOF>>  unexpected_end_of_file (loc, "*/");
 }
 
 
@@ -341,8 +355,8 @@ splice       (\\[ \f\t\v]*\n)*
 
 <SC_COMMENT>
 {
-  "*"{splice}"/"  YY_OBS_GROW; BEGIN c_context;
-  <<EOF>>        unexpected_end_of_file (*yylloc, "*/");
+  "*"{splice}"/"  STRING_GROW; BEGIN c_context;
+  <<EOF>>        unexpected_end_of_file (loc, "*/");
 }
 
 
@@ -352,8 +366,8 @@ splice       (\\[ \f\t\v]*\n)*
 
 <SC_LINE_COMMENT>
 {
-  "\n"          YY_OBS_GROW; BEGIN c_context;
-  {splice}      YY_OBS_GROW;
+  "\n"          STRING_GROW; BEGIN c_context;
+  {splice}      STRING_GROW;
   <<EOF>>       BEGIN c_context;
 }
 
@@ -366,16 +380,16 @@ splice     (\\[ \f\t\v]*\n)*
 <SC_ESCAPED_STRING>
 {
   "\"" {
-    YY_OBS_GROW;
-    YY_OBS_FINISH;
-    yylval->string = last_string;
+    STRING_GROW;
+    STRING_FINISH;
+    val->string = last_string;
     rule_length++;
     BEGIN INITIAL;
     return STRING;
   }
 
-  .|\n     YY_OBS_GROW;
-  <<EOF>>   unexpected_end_of_file (*yylloc, "\"");
+  .|\n     STRING_GROW;
+  <<EOF>>   unexpected_end_of_file (loc, "\"");
 }
 
   /*---------------------------------------------------------------.
@@ -386,20 +400,20 @@ splice     (\\[ \f\t\v]*\n)*
 <SC_ESCAPED_CHARACTER>
 {
   "'" {
-    YY_OBS_GROW;
-    YY_OBS_FINISH;
-    yylval->symbol = symbol_get (last_string, *yylloc);
-    symbol_class_set (yylval->symbol, token_sym, *yylloc);
-    symbol_user_token_number_set (yylval->symbol,
-                                 (unsigned char) last_string[1], *yylloc);
-    YY_OBS_FREE;
+    STRING_GROW;
+    STRING_FINISH;
+    val->symbol = symbol_get (last_string, *loc);
+    symbol_class_set (val->symbol, token_sym, *loc);
+    symbol_user_token_number_set (val->symbol,
+                                 (unsigned char) last_string[1], *loc);
+    STRING_FREE;
     rule_length++;
     BEGIN INITIAL;
     return ID;
   }
 
-  .|\n     YY_OBS_GROW;
-  <<EOF>>   unexpected_end_of_file (*yylloc, "'");
+  .|\n     STRING_GROW;
+  <<EOF>>   unexpected_end_of_file (loc, "'");
 }
 
 
@@ -413,23 +427,23 @@ splice     (\\[ \f\t\v]*\n)*
     unsigned long c = strtoul (yytext + 1, 0, 8);
     if (UCHAR_MAX < c)
       {
-       complain_at (*yylloc, _("invalid escape sequence: %s"),
+       complain_at (*loc, _("invalid escape sequence: %s"),
                     quote (yytext));
-       YY_STEP;
+       STEP;
       }
     else
       obstack_1grow (&string_obstack, c);
   }
 
-  \\x[0-9a-fA-F]+ {
+  \\x[0-9abcdefABCDEF]+ {
     unsigned long c;
     errno = 0;
     c = strtoul (yytext + 2, 0, 16);
     if (UCHAR_MAX < c || errno)
       {
-       complain_at (*yylloc, _("invalid escape sequence: %s"),
+       complain_at (*loc, _("invalid escape sequence: %s"),
                     quote (yytext));
-       YY_STEP;
+       STEP;
       }
     else
       obstack_1grow (&string_obstack, c);
@@ -442,22 +456,25 @@ splice     (\\[ \f\t\v]*\n)*
   \\r  obstack_1grow (&string_obstack, '\r');
   \\t  obstack_1grow (&string_obstack, '\t');
   \\v  obstack_1grow (&string_obstack, '\v');
-  \\[\"\'?\\]  obstack_1grow (&string_obstack, yytext[1]);
-  \\(u|U[0-9a-fA-F]{4})[0-9a-fA-F]{4} {
+
+  /* \\[\"\'?\\] would be shorter, but it confuses xgettext.  */
+  \\("\""|"'"|"?"|"\\")  obstack_1grow (&string_obstack, yytext[1]);
+
+  \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
     int c = convert_ucn_to_byte (yytext);
     if (c < 0)
       {
-       complain_at (*yylloc, _("invalid escape sequence: %s"),
+       complain_at (*loc, _("invalid escape sequence: %s"),
                     quote (yytext));
-       YY_STEP;
+       STEP;
       }
     else
       obstack_1grow (&string_obstack, c);
   }
   \\(.|\n)     {
-    complain_at (*yylloc, _("unrecognized escape sequence: %s"),
+    complain_at (*loc, _("unrecognized escape sequence: %s"),
                 quote (yytext));
-    YY_OBS_GROW;
+    STRING_GROW;
   }
 }
 
@@ -469,10 +486,9 @@ splice      (\\[ \f\t\v]*\n)*
 
 <SC_CHARACTER>
 {
-  "'"                 YY_OBS_GROW; BEGIN c_context;
-  \\{splice}[^\[\]]    YY_OBS_GROW;
-  {splice}            YY_OBS_GROW;
-  <<EOF>>             unexpected_end_of_file (*yylloc, "'");
+  "'"                  STRING_GROW; BEGIN c_context;
+  \\{splice}[^$@\[\]]  STRING_GROW;
+  <<EOF>>              unexpected_end_of_file (loc, "'");
 }
 
 
@@ -483,10 +499,9 @@ splice      (\\[ \f\t\v]*\n)*
 
 <SC_STRING>
 {
-  "\""                YY_OBS_GROW; BEGIN c_context;
-  \\{splice}[^\[\]]    YY_OBS_GROW;
-  {splice}            YY_OBS_GROW;
-  <<EOF>>             unexpected_end_of_file (*yylloc, "\"");
+  "\""                 STRING_GROW; BEGIN c_context;
+  \\{splice}[^$@\[\]]  STRING_GROW;
+  <<EOF>>              unexpected_end_of_file (loc, "\"");
 }
 
 
@@ -496,10 +511,10 @@ splice     (\\[ \f\t\v]*\n)*
 
 <SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
 {
-  "'"            YY_OBS_GROW; c_context = YY_START; BEGIN SC_CHARACTER;
-  "\""           YY_OBS_GROW; c_context = YY_START; BEGIN SC_STRING;
-  "/"{splice}"*"  YY_OBS_GROW; c_context = YY_START; BEGIN SC_COMMENT;
-  "/"{splice}"/"  YY_OBS_GROW; c_context = YY_START; BEGIN SC_LINE_COMMENT;
+  "'"            STRING_GROW; c_context = YY_START; BEGIN SC_CHARACTER;
+  "\""           STRING_GROW; c_context = YY_START; BEGIN SC_STRING;
+  "/"{splice}"*"  STRING_GROW; c_context = YY_START; BEGIN SC_COMMENT;
+  "/"{splice}"/"  STRING_GROW; c_context = YY_START; BEGIN SC_LINE_COMMENT;
 }
 
 
@@ -510,15 +525,15 @@ splice     (\\[ \f\t\v]*\n)*
 
 <SC_BRACED_CODE>
 {
-  "{"|"<"{splice}"%"  YY_OBS_GROW; braces_level++;
-  "%"{splice}">"      YY_OBS_GROW; braces_level--;
+  "{"|"<"{splice}"%"  STRING_GROW; braces_level++;
+  "%"{splice}">"      STRING_GROW; braces_level--;
   "}" {
-    YY_OBS_GROW;
+    STRING_GROW;
     braces_level--;
     if (braces_level < 0)
       {
-       YY_OBS_FINISH;
-       yylval->string = last_string;
+       STRING_FINISH;
+       val->string = last_string;
        rule_length++;
        BEGIN INITIAL;
        return BRACED_CODE;
@@ -527,14 +542,14 @@ splice     (\\[ \f\t\v]*\n)*
 
   /* Tokenize `<<%' correctly (as `<<' `%') rather than incorrrectly
      (as `<' `<%').  */
-  "<"{splice}"<"  YY_OBS_GROW;
+  "<"{splice}"<"  STRING_GROW;
 
   "$"("<"{tag}">")?(-?[0-9]+|"$") { handle_dollar (current_braced_code,
-                                                  yytext, *yylloc); }
+                                                  yytext, *loc); }
   "@"(-?[0-9]+|"$")               { handle_at (current_braced_code,
-                                              yytext, *yylloc); }
+                                              yytext, *loc); }
 
-  <<EOF>>  unexpected_end_of_file (*yylloc, "}");
+  <<EOF>>  unexpected_end_of_file (loc, "}");
 }
 
 
@@ -545,13 +560,13 @@ splice     (\\[ \f\t\v]*\n)*
 <SC_PROLOGUE>
 {
   "%}" {
-    YY_OBS_FINISH;
-    yylval->string = last_string;
+    STRING_FINISH;
+    val->string = last_string;
     BEGIN INITIAL;
     return PROLOGUE;
   }
 
-  <<EOF>>  unexpected_end_of_file (*yylloc, "%}");
+  <<EOF>>  unexpected_end_of_file (loc, "%}");
 }
 
 
@@ -563,8 +578,8 @@ splice       (\\[ \f\t\v]*\n)*
 <SC_EPILOGUE>
 {
   <<EOF>> {
-    YY_OBS_FINISH;
-    yylval->string = last_string;
+    STRING_FINISH;
+    val->string = last_string;
     BEGIN INITIAL;
     return EPILOGUE;
   }
@@ -578,9 +593,11 @@ splice      (\\[ \f\t\v]*\n)*
 
 <SC_COMMENT,SC_LINE_COMMENT,SC_STRING,SC_CHARACTER,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
 {
-  \[   obstack_sgrow (&string_obstack, "@<:@");
-  \]   obstack_sgrow (&string_obstack, "@:>@");
-  .|\n  YY_OBS_GROW;
+  \$   obstack_sgrow (&string_obstack, "$][");
+  \@   obstack_sgrow (&string_obstack, "@@");
+  \[   obstack_sgrow (&string_obstack, "@{");
+  \]   obstack_sgrow (&string_obstack, "@}");
+  .|\n  STRING_GROW;
 }
 
 
@@ -827,10 +844,8 @@ handle_syncline (char *args, location_t *location)
   const char *file = NULL;
   file = strchr (args, '"') + 1;
   *strchr (file, '"') = 0;
-  /* FIXME: Leaking...  Can't free, as some locations are still
-     pointing to the old file name.  */
-  infile = xstrdup (file);
-  location->file = infile;
+  current_file = xstrdup (file);
+  location->file = current_file;
   location->last_line = lineno;
 }
 
@@ -842,13 +857,18 @@ handle_syncline (char *args, location_t *location)
 `-------------------------------------------------------------*/
 
 static void
-unexpected_end_of_file (location_t loc, char const *token_end)
+unexpected_end_of_file (location_t *loc, char const *token_end)
 {
-  size_t i;
+  size_t i = strlen (token_end);
+
+  complain_at (*loc, _("missing `%s' at end of file"), token_end);
+
+  /* Adjust location's last column so that any later message does not
+     mention the characters just inserted.  */
+  loc->last_column -= i;
 
-  complain_at (loc, _("missing `%s' at end of file"), token_end);
-  for (i = strlen (token_end); i != 0; i--)
-    unput (token_end[i - 1]);
+  while (i != 0)
+    unput (token_end[--i]);
 }