]> git.saurik.com Git - bison.git/blobdiff - src/scan-gram.l
Steal GCC's --time-report support.
[bison.git] / src / scan-gram.l
index a3f6a2f62b79bcdab6488ed5cbf6e529a5d431d6..d52984526e661fccb61eb9318f9c2871c0d3f15d 100644 (file)
 #include "reader.h"
 
 /* Each time we match a string, move the end cursor to its end. */
-#define YY_USER_ACTION  LOCATION_COLUMNS (*yylloc, yyleng)
-#define YY_LINES        LOCATION_LINES (*yylloc, yyleng); lineno += yyleng;
-#define YY_STEP         LOCATION_STEP (*yylloc)
-
+#define YY_USER_INIT                           \
+do {                                           \
+  LOCATION_RESET (*yylloc);                    \
+  yylloc->file = infile;                       \
+   /* This is only to avoid GCC warnings. */   \
+  if (yycontrol) {;};                          \
+} while (0)
+
+#define YY_USER_ACTION  LOCATION_COLUMNS (*yylloc, yyleng);
+#define YY_LINES        LOCATION_LINES (*yylloc, yyleng);
+#define YY_STEP         LOCATION_STEP (*yylloc);
 
 /* STRING_OBSTACK -- Used to store all the characters that we need to
    keep (to construct ID, STRINGS etc.).  Use the following macros to
    use it.
 
-   Use YY_OBS_INIT to initialize a new growing string, 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 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.  */
 
 static struct obstack string_obstack;
 char *last_string;
 
-#define YY_OBS_INIT   \
-  obstack_init (&string_obstack)
-
 #define YY_OBS_GROW   \
   obstack_grow (&string_obstack, yytext, yyleng)
 
@@ -73,15 +76,13 @@ scanner_last_string_free (void)
 }
 
 
-/* This is only to avoid GCC warnings. */
-#define YY_USER_INIT    if (yycontrol) {;};
-
-
 static int braces_level = 0;
 static int percent_percent_count = 0;
 
-static void handle_dollar PARAMS ((char *cp));
-static void handle_at PARAMS ((char *cp));
+static void handle_dollar PARAMS ((braced_code_t code_kind,
+                                  char *cp, location_t location));
+static void handle_at PARAMS ((braced_code_t code_kind,
+                              char *cp, location_t location));
 
 %}
 %x SC_COMMENT
@@ -89,7 +90,7 @@ static void handle_at PARAMS ((char *cp));
 %x SC_ESCAPED_STRING SC_ESCAPED_CHARACTER
 %x SC_BRACED_CODE SC_PROLOGUE SC_EPILOGUE
 
-id      [.a-zA-Z][.a-zA-Z_0-9]*
+id      [.a-zA-Z_][.a-zA-Z_0-9]*
 int     [0-9]+
 eols     (\n|\r|\n\r|\r\n)+
 blanks   [ \t\f]+
@@ -100,7 +101,7 @@ blanks   [ \t\f]+
      start of the next token.  */
 #define TR_POS 0
 #if TR_POS
-  fprintf (stderr, "FOO1: ");
+  fprintf (stderr, "FOO1: %p: ", yylloc);
   LOCATION_PRINT (stderr, *yylloc);
   fprintf (stderr, "\n");
 #endif
@@ -122,18 +123,23 @@ blanks   [ \t\f]+
   "%debug"                return PERCENT_DEBUG;
   "%define"               return PERCENT_DEFINE;
   "%defines"              return PERCENT_DEFINES;
+  "%destructor"           return PERCENT_DESTRUCTOR;
+  "%dprec"               return PERCENT_DPREC;
   "%error"[-_]"verbose"   return PERCENT_ERROR_VERBOSE;
   "%expect"               return PERCENT_EXPECT;
   "%file-prefix"          return PERCENT_FILE_PREFIX;
   "%fixed"[-_]"output"[-_]"files"   return PERCENT_YACC;
+  "%glr"[-_]"parser"     return PERCENT_GLR_PARSER;
   "%left"                 return PERCENT_LEFT;
   "%locations"            return PERCENT_LOCATIONS;
+  "%merge"               return PERCENT_MERGE;
   "%name"[-_]"prefix"     return PERCENT_NAME_PREFIX;
   "%no"[-_]"lines"        return PERCENT_NO_LINES;
   "%nonassoc"             return PERCENT_NONASSOC;
   "%nterm"                return PERCENT_NTERM;
   "%output"               return PERCENT_OUTPUT;
   "%prec"                 return PERCENT_PREC;
+  "%printer"              return PERCENT_PRINTER;
   "%pure"[-_]"parser"     return PERCENT_PURE_PARSER;
   "%right"                return PERCENT_RIGHT;
   "%skeleton"             return PERCENT_SKELETON;
@@ -154,31 +160,30 @@ blanks   [ \t\f]+
   {eols}      YY_LINES; YY_STEP;
   {blanks}    YY_STEP;
   {id}        {
-    yylval->symbol = getsym (yytext);
+    yylval->symbol = symbol_get (yytext, *yylloc);
     return ID;
   }
 
   {int}       yylval->integer = strtol (yytext, 0, 10); return INT;
 
   /* Characters.  We don't check there is only one.  */
-  \'          YY_OBS_INIT; YY_OBS_GROW; yy_push_state (SC_ESCAPED_CHARACTER);
+  \'          YY_OBS_GROW; yy_push_state (SC_ESCAPED_CHARACTER);
 
   /* Strings. */
-  \"          YY_OBS_INIT; YY_OBS_GROW; yy_push_state (SC_ESCAPED_STRING);
+  \"          YY_OBS_GROW; yy_push_state (SC_ESCAPED_STRING);
 
   /* Comments. */
   "/*"        yy_push_state (SC_COMMENT);
   "//".*      YY_STEP;
 
   /* Prologue. */
-  "%{"        YY_OBS_INIT; yy_push_state (SC_PROLOGUE);
+  "%{"        yy_push_state (SC_PROLOGUE);
 
   /* Code in between braces.  */
-  "{"         YY_OBS_INIT; YY_OBS_GROW; ++braces_level; yy_push_state (SC_BRACED_CODE);
+  "{"         YY_OBS_GROW; ++braces_level; yy_push_state (SC_BRACED_CODE);
 
   /* A type. */
   "<"[^>]+">" {
-    YY_OBS_INIT;
     obstack_grow (&string_obstack, yytext + 1, yyleng - 2);
     YY_OBS_FINISH;
     yylval->string = last_string;
@@ -208,8 +213,8 @@ blanks   [ \t\f]+
 
 <SC_COMMENT,SC_STRING,SC_CHARACTER,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
 {
-  \[          obstack_sgrow (&string_obstack, "@<:@");
-  \]          obstack_sgrow (&string_obstack, "@:>@");
+  \[          if (YY_START != SC_COMMENT) obstack_sgrow (&string_obstack, "@<:@");
+  \]          if (YY_START != SC_COMMENT) obstack_sgrow (&string_obstack, "@:>@");
 }
 
 
@@ -287,9 +292,10 @@ blanks   [ \t\f]+
     assert (yy_top_state () == INITIAL);
     {
       YY_OBS_FINISH;
-      yylval->symbol = getsym (last_string);
-      symbol_class_set (yylval->symbol, token_sym);
-      symbol_user_token_number_set (yylval->symbol, last_string[1]);
+      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;
       yy_pop_state ();
       return ID;
@@ -323,7 +329,7 @@ blanks   [ \t\f]+
     if (c > 255)
       {
        LOCATION_PRINT (stderr, *yylloc);
-       fprintf (stderr, ": invalid escape: %s\n", yytext);
+       fprintf (stderr, ": invalid escape: %s\n", quote (yytext));
        YY_STEP;
       }
     else
@@ -342,11 +348,13 @@ blanks   [ \t\f]+
   \\t  obstack_1grow (&string_obstack, '\t');
   \\v  obstack_1grow (&string_obstack, '\v');
   \\[\\""]   obstack_1grow (&string_obstack, yytext[1]);
-  \\.  {
+  \\(.|\n)     {
     LOCATION_PRINT (stderr, *yylloc);
-    fprintf (stderr, ": unrecognized escape: %s\n", yytext);
+    fprintf (stderr, ": unrecognized escape: %s\n", quote (yytext));
     YY_OBS_GROW;
   }
+  /* FLex wants this rule, in case of a `\<<EOF>>'. */
+  \\                   YY_OBS_GROW;
 }
 
 
@@ -363,8 +371,10 @@ blanks   [ \t\f]+
     yy_pop_state ();
   }
 
-  [^\[\]\'\n\r\\]      YY_OBS_GROW;
-  \\.                  YY_OBS_GROW;
+  [^\[\]\'\n\r\\]+     YY_OBS_GROW;
+  \\(.|\n)             YY_OBS_GROW;
+  /* FLex wants this rule, in case of a `\<<EOF>>'. */
+  \\                   YY_OBS_GROW;
 
   {eols}               YY_OBS_GROW; YY_LINES;
 
@@ -391,7 +401,9 @@ blanks   [ \t\f]+
   }
 
   [^\[\]\"\n\r\\]+      YY_OBS_GROW;
-  \\.                   YY_OBS_GROW;
+  \\(.|\n)              YY_OBS_GROW;
+  /* FLex wants this rule, in case of a `\<<EOF>>'. */
+  \\                   YY_OBS_GROW;
 
   {eols}                YY_OBS_GROW; YY_LINES;
 
@@ -419,6 +431,9 @@ blanks   [ \t\f]+
   /* Comments. */
   "/*"        YY_OBS_GROW; yy_push_state (SC_COMMENT);
   "//".*      YY_OBS_GROW;
+
+  /* Not comments. */
+  "/"         YY_OBS_GROW;
 }
 
 
@@ -442,10 +457,12 @@ blanks   [ \t\f]+
 
   "{"                  YY_OBS_GROW; braces_level++;
 
-  "$"("<".*">")?(-?[0-9]+|"$") { handle_dollar (yytext); }
-  "@"(-?[0-9]+|"$")            { handle_at (yytext); }
+  "$"("<"[^>]+">")?(-?[0-9]+|"$") { handle_dollar (current_braced_code,
+                                                  yytext, *yylloc); }
+  "@"(-?[0-9]+|"$")               { handle_at (current_braced_code,
+                                              yytext, *yylloc); }
 
-  [^\[\]$/\'\"@\{\}\n\r]+ YY_OBS_GROW;
+  [^$@\[\]/\'\"\{\}\n\r]+ YY_OBS_GROW;
   {eols}       YY_OBS_GROW; YY_LINES;
 
   /* A lose $, or /, or etc. */
@@ -476,9 +493,9 @@ blanks   [ \t\f]+
     return PROLOGUE;
   }
 
-  [^\[\]%\n\r]+          YY_OBS_GROW;
-  "%"+[^%\}\n\r]+ YY_OBS_GROW;
-  {eols}         YY_OBS_GROW; YY_LINES;
+  [^%\[\]/\'\"\n\r]+ YY_OBS_GROW;
+  "%"                YY_OBS_GROW;
+  {eols}            YY_OBS_GROW; YY_LINES;
 
   <<EOF>> {
     LOCATION_PRINT (stderr, *yylloc);
@@ -488,7 +505,6 @@ blanks   [ \t\f]+
     yylval->string = last_string;
     return PROLOGUE;
   }
-
 }
 
 
@@ -513,28 +529,18 @@ blanks   [ \t\f]+
 %%
 
 /*------------------------------------------------------------------.
-| CP is pointing to a wannabee semantic value (i.e., a `$').        |
+| TEXT is pointing to a wannabee semantic value (i.e., a `$').      |
 |                                                                   |
 | Possible inputs: $[<TYPENAME>]($|integer)                         |
 |                                                                   |
 | Output to the STRING_OBSTACK a reference to this semantic value.  |
 `------------------------------------------------------------------*/
 
-static void
-handle_dollar (char *cp)
+static inline void
+handle_action_dollar (char *text, location_t location)
 {
   const char *type_name = NULL;
-
-  /* RULE_LENGTH is the number of values in the current rule so far,
-     which says where to find `$0' with respect to the top of the
-     stack.  It is not the same as the rule->length in the case of mid
-     rule actions.  */
-  int rule_length = 0;
-  symbol_list *rhs;
-  for (rhs = current_rule->next; rhs; rhs = rhs->next)
-    ++rule_length;
-
-  ++cp;
+  char *cp = text + 1;
 
   /* Get the type name if explicit. */
   if (*cp == '<')
@@ -549,10 +555,10 @@ handle_dollar (char *cp)
   if (*cp == '$')
     {
       if (!type_name)
-       type_name = get_type_name (0, current_rule);
+       type_name = symbol_list_n_type_name_get (current_rule, location, 0);
       if (!type_name && typed)
-       complain (_("$$ of `%s' has no declared type"),
-                 current_rule->sym->tag);
+       complain_at (location, _("$$ of `%s' has no declared type"),
+                    current_rule->sym->tag);
       if (!type_name)
        type_name = "";
       obstack_fgrow1 (&string_obstack,
@@ -560,16 +566,22 @@ handle_dollar (char *cp)
     }
   else if (isdigit (*cp) || *cp == '-')
     {
+      /* RULE_LENGTH is the number of values in the current rule so
+        far, which says where to find `$0' with respect to the top of
+        the stack.  It is not the same as the rule->length in the
+        case of mid rule actions.  */
+      int rule_length = symbol_list_length (current_rule->next);
       int n = strtol (cp, &cp, 10);
 
       if (n > rule_length)
-       complain (_("invalid value: %s%d"), "$", n);
+       complain_at (location, _("invalid value: %s%d"), "$", n);
       else
        {
          if (!type_name && n > 0)
-           type_name = get_type_name (n, current_rule);
+           type_name = symbol_list_n_type_name_get (current_rule, location,
+                                                    n);
          if (!type_name && typed)
-           complain (_("$%d of `%s' has no declared type"),
+           complain_at (location, _("$%d of `%s' has no declared type"),
                      n, current_rule->sym->tag);
          if (!type_name)
            type_name = "";
@@ -580,31 +592,60 @@ handle_dollar (char *cp)
     }
   else
     {
-      char buf[] = "$c";
-      buf[1] = *cp;
-      complain (_("%s is invalid"), quote (buf));
+      complain_at (location, _("%s is invalid"), quote (text));
     }
 }
 
-/*-------------------------------------------------------.
-| CP is pointing to a location (i.e., a `@').  Output to |
-| STRING_OBSTACK a reference to this location.           |
-`-------------------------------------------------------*/
+
+/*---------------------------------------------------------------.
+| TEXT is expexted tp be $$ in some code associated to a symbol: |
+| destructor or printer.                                         |
+`---------------------------------------------------------------*/
+
+static inline void
+handle_symbol_code_dollar (char *text, location_t location)
+{
+  char *cp = text + 1;
+  if (*cp == '$')
+    obstack_sgrow (&string_obstack, "]b4_dollar_dollar[");
+  else
+    complain_at (location, _("%s is invalid"), quote (text));
+}
+
+
+/*-----------------------------------------------------------------.
+| Dispatch onto handle_action_dollar, or handle_destructor_dollar, |
+| depending upon CODE_KIND.                                        |
+`-----------------------------------------------------------------*/
 
 static void
-handle_at (char *cp)
+handle_dollar (braced_code_t braced_code_kind,
+              char *text, location_t location)
 {
-  /* RULE_LENGTH is the number of values in the current rule so far,
-     which says where to find `$0' with respect to the top of the
-     stack.  It is not the same as the rule->length in the case of mid
-     rule actions.  */
-  int rule_length = 0;
-  symbol_list *rhs;
-  for (rhs = current_rule->next; rhs; rhs = rhs->next)
-    ++rule_length;
+  switch (braced_code_kind)
+    {
+    case action_braced_code:
+      handle_action_dollar (text, location);
+      break;
+
+    case destructor_braced_code:
+    case printer_braced_code:
+      handle_symbol_code_dollar (text, location);
+      break;
+    }
+}
+
 
+/*------------------------------------------------------.
+| TEXT is a location token (i.e., a `@...').  Output to |
+| STRING_OBSTACK a reference to this location.          |
+`------------------------------------------------------*/
+
+static inline void
+handle_action_at (char *text, location_t location)
+{
+  char *cp = text + 1;
   locations_flag = 1;
-  ++cp;
 
   if (*cp == '$')
     {
@@ -612,23 +653,84 @@ handle_at (char *cp)
     }
   else if (isdigit (*cp) || *cp == '-')
     {
+      /* RULE_LENGTH is the number of values in the current rule so
+        far, which says where to find `$0' with respect to the top of
+        the stack.  It is not the same as the rule->length in the
+        case of mid rule actions.  */
+      int rule_length = symbol_list_length (current_rule->next);
       int n = strtol (cp, &cp, 10);
+
       if (n > rule_length)
-       complain (_("invalid value: %s%d"), "@", n);
+       complain_at (location, _("invalid value: %s%d"), "@", n);
       else
        obstack_fgrow2 (&string_obstack, "]b4_rhs_location([%d], [%d])[",
                        rule_length, n);
     }
   else
     {
-      char buf[] = "@c";
-      buf[1] = *cp;
-      complain (_("%s is invalid"), quote (buf));
+      complain_at (location, _("%s is invalid"), quote (text));
     }
 }
 
+
+/*---------------------------------------------------------------.
+| TEXT is expexted tp be @$ in some code associated to a symbol: |
+| destructor or printer.                                         |
+`---------------------------------------------------------------*/
+
+static inline void
+handle_symbol_code_at (char *text, location_t location)
+{
+  char *cp = text + 1;
+  if (*cp == '$')
+    obstack_sgrow (&string_obstack, "]b4_at_dollar[");
+  else
+    complain_at (location, _("%s is invalid"), quote (text));
+}
+
+
+/*-------------------------------------------------------------------.
+| Dispatch onto handle_action_at, or handle_destructor_at, depending |
+| upon CODE_KIND.                                                    |
+`-------------------------------------------------------------------*/
+
+static void
+handle_at (braced_code_t braced_code_kind,
+          char *text, location_t location)
+{
+  switch (braced_code_kind)
+    {
+    case action_braced_code:
+      handle_action_at (text, location);
+      break;
+
+    case destructor_braced_code:
+    case printer_braced_code:
+      handle_symbol_code_at (text, location);
+      break;
+    }
+}
+
+
+/*-------------------------.
+| Initialize the scanner.  |
+`-------------------------*/
+
+void
+scanner_initialize (void)
+{
+  obstack_init (&string_obstack);
+}
+
+
+/*-----------------------------------------------.
+| Free all the memory allocated to the scanner.  |
+`-----------------------------------------------*/
+
 void
 scanner_free (void)
 {
   obstack_free (&string_obstack, 0);
+  /* Reclaim Flex's buffers.  */
+  yy_delete_buffer (YY_CURRENT_BUFFER);
 }