]> git.saurik.com Git - bison.git/blobdiff - src/scan-gram.l
Prototype support of %lex-param and %parse-param.
[bison.git] / src / scan-gram.l
index 462be239856b72db070276f9a42740f816b25b39..235272f1f90addccca08d84365d8f7dab039ec72 100644 (file)
 #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); lineno += yyleng;
-#define YY_STEP         LOCATION_STEP (*yylloc)
-
+#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
@@ -79,6 +79,14 @@ scanner_last_string_free (void)
 static int braces_level = 0;
 static int percent_percent_count = 0;
 
+/* 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
+   to the top of the stack.  It is not the same as the rule->length in
+   the case of mid rule actions.
+
+   Outside of well-formed rules, RULE_LENGTH has an undefined value.  */
+static int rule_length;
+
 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,
@@ -90,7 +98,7 @@ static void handle_at PARAMS ((braced_code_t code_kind,
 %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]+
@@ -99,18 +107,7 @@ blanks   [ \t\f]+
 %{
   /* At each yylex invocation, mark the current position as the
      start of the next token.  */
-#define TR_POS 0
-#if TR_POS
-  fprintf (stderr, "FOO1: %p: ", yylloc);
-  LOCATION_PRINT (stderr, *yylloc);
-  fprintf (stderr, "\n");
-#endif
   YY_STEP;
-#if TR_POS
-  fprintf (stderr, "BAR1: ");
-  LOCATION_PRINT (stderr, *yylloc);
-  fprintf (stderr, "\n");
-#endif
 %}
 
 
@@ -124,20 +121,26 @@ blanks   [ \t\f]+
   "%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;
+  "%parse-param"          return PERCENT_PARSE_PARAM;
+  "%prec"                 { rule_length--; return PERCENT_PREC; }
+  "%printer"              return PERCENT_PRINTER;
   "%pure"[-_]"parser"     return PERCENT_PURE_PARSER;
   "%right"                return PERCENT_RIGHT;
+  "%lex-param"            return PERCENT_LEX_PARAM;
   "%skeleton"             return PERCENT_SKELETON;
   "%start"                return PERCENT_START;
   "%term"                 return PERCENT_TOKEN;
@@ -149,24 +152,26 @@ blanks   [ \t\f]+
   "%yacc"                 return PERCENT_YACC;
 
   "="                     return EQUAL;
-  ":"                     return COLON;
-  "|"                     return PIPE;
+  ":"                     { rule_length = 0; return COLON; }
+  "|"                     { rule_length = 0; return PIPE; }
+  ","                     return COMMA;
   ";"                     return SEMICOLON;
 
   {eols}      YY_LINES; YY_STEP;
   {blanks}    YY_STEP;
   {id}        {
-    yylval->symbol = getsym (yytext, *yylloc);
+    yylval->symbol = symbol_get (yytext, *yylloc);
+    rule_length++;
     return ID;
   }
 
   {int}       yylval->integer = strtol (yytext, 0, 10); return INT;
 
   /* Characters.  We don't check there is only one.  */
-  \'          YY_OBS_GROW; yy_push_state (SC_ESCAPED_CHARACTER);
+  "'"         YY_OBS_GROW; yy_push_state (SC_ESCAPED_CHARACTER);
 
   /* Strings. */
-  \"          YY_OBS_GROW; yy_push_state (SC_ESCAPED_STRING);
+  "\""        YY_OBS_GROW; yy_push_state (SC_ESCAPED_STRING);
 
   /* Comments. */
   "/*"        yy_push_state (SC_COMMENT);
@@ -195,7 +200,7 @@ blanks   [ \t\f]+
 
   .           {
     LOCATION_PRINT (stderr, *yylloc);
-    fprintf (stderr, ": invalid character: `%c'\n", *yytext);
+    fprintf (stderr, _(": invalid character: `%c'\n"), *yytext);
     YY_STEP;
   }
 }
@@ -239,7 +244,7 @@ blanks   [ \t\f]+
 
   <<EOF>> {
     LOCATION_PRINT (stderr, *yylloc);
-    fprintf (stderr, ": unexpected end of file in a comment\n");
+    fprintf (stderr, _(": unexpected end of file in a comment\n"));
     yy_pop_state ();
   }
 }
@@ -252,12 +257,13 @@ blanks   [ \t\f]+
 
 <SC_ESCAPED_STRING>
 {
-  \" {
+  "\"" {
     assert (yy_top_state () == INITIAL);
     YY_OBS_GROW;
     YY_OBS_FINISH;
     yylval->string = last_string;
     yy_pop_state ();
+    rule_length++;
     return STRING;
   }
 
@@ -267,7 +273,7 @@ blanks   [ \t\f]+
 
   <<EOF>> {
     LOCATION_PRINT (stderr, *yylloc);
-    fprintf (stderr, ": unexpected end of file in a string\n");
+    fprintf (stderr, _(": unexpected end of file in a string\n"));
     assert (yy_top_state () == INITIAL);
     YY_OBS_FINISH;
     yylval->string = last_string;
@@ -283,27 +289,29 @@ blanks   [ \t\f]+
 
 <SC_ESCAPED_CHARACTER>
 {
-  \' {
+  "'" {
     YY_OBS_GROW;
     assert (yy_top_state () == INITIAL);
     {
       YY_OBS_FINISH;
-      yylval->symbol = getsym (last_string, *yylloc);
-      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 ();
+      rule_length++;
       return ID;
     }
   }
 
-  [^\'\n\r\\]      YY_OBS_GROW;
+  [^\n\r\\] YY_OBS_GROW;
 
   {eols}    obstack_1grow (&string_obstack, '\n'); YY_LINES;
 
   <<EOF>> {
     LOCATION_PRINT (stderr, *yylloc);
-    fprintf (stderr, ": unexpected end of file in a character\n");
+    fprintf (stderr, _(": unexpected end of file in a character\n"));
     assert (yy_top_state () == INITIAL);
     YY_OBS_FINISH;
     yylval->string = last_string;
@@ -324,7 +332,7 @@ blanks   [ \t\f]+
     if (c > 255)
       {
        LOCATION_PRINT (stderr, *yylloc);
-       fprintf (stderr, ": invalid escape: %s\n", quote (yytext));
+       fprintf (stderr, _(": invalid escape: %s\n"), quote (yytext));
        YY_STEP;
       }
     else
@@ -342,10 +350,10 @@ blanks   [ \t\f]+
   \\r  obstack_1grow (&string_obstack, '\r');
   \\t  obstack_1grow (&string_obstack, '\t');
   \\v  obstack_1grow (&string_obstack, '\v');
-  \\[\\""]   obstack_1grow (&string_obstack, yytext[1]);
+  \\[\\""'']   obstack_1grow (&string_obstack, yytext[1]);
   \\(.|\n)     {
     LOCATION_PRINT (stderr, *yylloc);
-    fprintf (stderr, ": unrecognized escape: %s\n", quote (yytext));
+    fprintf (stderr, _(": unrecognized escape: %s\n"), quote (yytext));
     YY_OBS_GROW;
   }
   /* FLex wants this rule, in case of a `\<<EOF>>'. */
@@ -360,7 +368,7 @@ blanks   [ \t\f]+
 
 <SC_CHARACTER>
 {
-  \' {
+  "'" {
     YY_OBS_GROW;
     assert (yy_top_state () != INITIAL);
     yy_pop_state ();
@@ -375,7 +383,7 @@ blanks   [ \t\f]+
 
   <<EOF>> {
     LOCATION_PRINT (stderr, *yylloc);
-    fprintf (stderr, ": unexpected end of file in a character\n");
+    fprintf (stderr, _(": unexpected end of file in a character\n"));
     assert (yy_top_state () != INITIAL);
     yy_pop_state ();
   }
@@ -389,7 +397,7 @@ blanks   [ \t\f]+
 
 <SC_STRING>
 {
-  \" {
+  "\"" {
     assert (yy_top_state () != INITIAL);
     YY_OBS_GROW;
     yy_pop_state ();
@@ -404,7 +412,7 @@ blanks   [ \t\f]+
 
   <<EOF>> {
     LOCATION_PRINT (stderr, *yylloc);
-    fprintf (stderr, ": unexpected end of file in a string\n");
+    fprintf (stderr, _(": unexpected end of file in a string\n"));
     assert (yy_top_state () != INITIAL);
     yy_pop_state ();
   }
@@ -418,10 +426,10 @@ blanks   [ \t\f]+
 <SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
 {
   /* Characters.  We don't check there is only one.  */
-  \'          YY_OBS_GROW; yy_push_state (SC_CHARACTER);
+  "'"         YY_OBS_GROW; yy_push_state (SC_CHARACTER);
 
   /* Strings. */
-  \"          YY_OBS_GROW; yy_push_state (SC_STRING);
+  "\""        YY_OBS_GROW; yy_push_state (SC_STRING);
 
   /* Comments. */
   "/*"        YY_OBS_GROW; yy_push_state (SC_COMMENT);
@@ -446,6 +454,7 @@ blanks   [ \t\f]+
        yy_pop_state ();
        YY_OBS_FINISH;
        yylval->string = last_string;
+       rule_length++;
        return BRACED_CODE;
       }
   }
@@ -465,7 +474,7 @@ blanks   [ \t\f]+
 
   <<EOF>> {
     LOCATION_PRINT (stderr, *yylloc);
-    fprintf (stderr, ": unexpected end of file in a braced code\n");
+    fprintf (stderr, _(": unexpected end of file in a braced code\n"));
     yy_pop_state ();
     YY_OBS_FINISH;
     yylval->string = last_string;
@@ -494,7 +503,7 @@ blanks   [ \t\f]+
 
   <<EOF>> {
     LOCATION_PRINT (stderr, *yylloc);
-    fprintf (stderr, ": unexpected end of file in a prologue\n");
+    fprintf (stderr, _(": unexpected end of file in a prologue\n"));
     yy_pop_state ();
     YY_OBS_FINISH;
     yylval->string = last_string;
@@ -524,7 +533,7 @@ 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)                         |
 |                                                                   |
@@ -532,11 +541,10 @@ blanks   [ \t\f]+
 `------------------------------------------------------------------*/
 
 static inline void
-handle_action_dollar (char *cp, location_t location)
+handle_action_dollar (char *text, location_t location)
 {
   const char *type_name = NULL;
-
-  ++cp;
+  char *cp = text + 1;
 
   /* Get the type name if explicit. */
   if (*cp == '<')
@@ -554,19 +562,14 @@ handle_action_dollar (char *cp, location_t location)
        type_name = symbol_list_n_type_name_get (current_rule, location, 0);
       if (!type_name && typed)
        complain_at (location, _("$$ of `%s' has no declared type"),
-                    symbol_tag_get (current_rule->sym));
+                    current_rule->sym->tag);
       if (!type_name)
        type_name = "";
       obstack_fgrow1 (&string_obstack,
                      "]b4_lhs_value([%s])[", type_name);
     }
-  else if (isdigit (*cp) || *cp == '-')
+  else if (('0' <= *cp && *cp <= '9') || *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)
@@ -578,7 +581,7 @@ handle_action_dollar (char *cp, location_t location)
                                                     n);
          if (!type_name && typed)
            complain_at (location, _("$%d of `%s' has no declared type"),
-                     n, symbol_tag_get (current_rule->sym));
+                     n, current_rule->sym->tag);
          if (!type_name)
            type_name = "";
          obstack_fgrow3 (&string_obstack,
@@ -588,31 +591,24 @@ handle_action_dollar (char *cp, location_t location)
     }
   else
     {
-      char buf[] = "$c";
-      buf[1] = *cp;
-      complain_at (location, _("%s is invalid"), quote (buf));
+      complain_at (location, _("%s is invalid"), quote (text));
     }
 }
 
 
-/*---------------------------------------.
-| CP is pointing to $$ in a destructor.  |
-`---------------------------------------*/
+/*---------------------------------------------------------------.
+| TEXT is expexted tp be $$ in some code associated to a symbol: |
+| destructor or printer.                                         |
+`---------------------------------------------------------------*/
 
 static inline void
-handle_destructor_dollar (char *cp, location_t location)
+handle_symbol_code_dollar (char *text, location_t location)
 {
-  ++cp;
+  char *cp = text + 1;
   if (*cp == '$')
-    {
-      obstack_sgrow (&string_obstack, "]b4_dollar_dollar[");
-    }
+    obstack_sgrow (&string_obstack, "]b4_dollar_dollar[");
   else
-    {
-      char buf[] = "$c";
-      buf[1] = *cp;
-      complain_at (location, _("%s is invalid"), quote (buf));
-    }
+    complain_at (location, _("%s is invalid"), quote (text));
 }
 
 
@@ -632,7 +628,8 @@ handle_dollar (braced_code_t braced_code_kind,
       break;
 
     case destructor_braced_code:
-      handle_destructor_dollar (text, location);
+    case printer_braced_code:
+      handle_symbol_code_dollar (text, location);
       break;
     }
 }
@@ -646,21 +643,16 @@ handle_dollar (braced_code_t braced_code_kind,
 static inline void
 handle_action_at (char *text, location_t location)
 {
+  char *cp = text + 1;
   locations_flag = 1;
-  ++text;
 
-  if (*text == '$')
+  if (*cp == '$')
     {
       obstack_sgrow (&string_obstack, "]b4_lhs_location[");
     }
-  else if (isdigit (*text) || *text == '-')
+  else if (('0' <= *cp && *cp <= '9') || *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 (text, &text, 10);
+      int n = strtol (cp, &cp, 10);
 
       if (n > rule_length)
        complain_at (location, _("invalid value: %s%d"), "@", n);
@@ -670,31 +662,24 @@ handle_action_at (char *text, location_t location)
     }
   else
     {
-      char buf[] = "@c";
-      buf[1] = *text;
-      complain_at (location, _("%s is invalid"), quote (buf));
+      complain_at (location, _("%s is invalid"), quote (text));
     }
 }
 
 
-/*--------------------------------------------.
-| TEXT is expexted tp be @$ in a destructor.  |
-`--------------------------------------------*/
+/*---------------------------------------------------------------.
+| TEXT is expexted tp be @$ in some code associated to a symbol: |
+| destructor or printer.                                         |
+`---------------------------------------------------------------*/
 
 static inline void
-handle_destructor_at (char *text, location_t location)
+handle_symbol_code_at (char *text, location_t location)
 {
-  ++text;
-  if (*text == '$')
-    {
-      obstack_sgrow (&string_obstack, "]b4_at_dollar[");
-    }
+  char *cp = text + 1;
+  if (*cp == '$')
+    obstack_sgrow (&string_obstack, "]b4_at_dollar[");
   else
-    {
-      char buf[] = "$c";
-      buf[1] = *text;
-      complain_at (location, _("%s is invalid"), quote (buf));
-    }
+    complain_at (location, _("%s is invalid"), quote (text));
 }
 
 
@@ -714,7 +699,8 @@ handle_at (braced_code_t braced_code_kind,
       break;
 
     case destructor_braced_code:
-      handle_destructor_at (text, location);
+    case printer_braced_code:
+      handle_symbol_code_at (text, location);
       break;
     }
 }
@@ -739,4 +725,6 @@ void
 scanner_free (void)
 {
   obstack_free (&string_obstack, 0);
+  /* Reclaim Flex's buffers.  */
+  yy_delete_buffer (YY_CURRENT_BUFFER);
 }