]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
Provide an additional sub-message for clarity.
[bison.git] / src / parse-gram.y
index 683a05ff4556b5d2d742fe7deef10a3df4d5654e..487d11562a5177e5634c6d6e5b30970da558d6f2 100644 (file)
@@ -54,12 +54,12 @@ static char const *char_name (char);
 
 %code
 {
-  static symbol_class current_class = unknown_sym;
-  static uniqstr current_type = NULL;
-  static symbol *current_lhs;
+  static int current_prec = 0;
   static location current_lhs_location;
   static named_ref *current_lhs_named_ref;
-  static int current_prec = 0;
+  static symbol *current_lhs;
+  static symbol_class current_class = unknown_sym;
+  static uniqstr current_type = NULL;
 
   #define YYTYPE_INT16 int_fast16_t
   #define YYTYPE_INT8 int_fast8_t
@@ -203,6 +203,7 @@ static char const *char_name (char);
 #  define PARAM_TYPE
   typedef enum
   {
+    param_none   = 0,
     param_lex    = 1 << 0,
     param_parse  = 1 << 1,
     param_both   = param_lex | param_parse
@@ -218,6 +219,7 @@ static char const *char_name (char);
    * \param loc   the location in the source.
    */
   static void add_param (param_type type, char *decl, location loc);
+  static param_type current_param = param_none;
 };
 %union
 {
@@ -229,15 +231,19 @@ static char const *char_name (char);
   switch ($$)
     {
 #define CASE(In, Out)                                           \
-      case param_ ## In:   fputs ("%" #Out, stderr); break
-
+      case param_ ## In: fputs ("%" #Out, stderr); break
       CASE(lex,   lex-param);
       CASE(parse, parse-param);
       CASE(both,  param);
-    }
 #undef CASE
+      case param_none: aver (false); break;
+    }
 } <param>;
 
+
+                     /*==========\
+                     | Grammar.  |
+                     \==========*/
 %%
 
 input:
@@ -311,7 +317,7 @@ prologue_declaration:
 | "%nondeterministic-parser"   { nondeterministic_parser = true; }
 | "%output" STRING              { spec_outfile = $2; }
 | "%output" "=" STRING          { spec_outfile = $3; }  /* deprecated */
-| "%param" "{...}"             { add_param ($1, $2, @2); }
+| "%param" { current_param = $1; } params { current_param = param_none; }
 | "%require" STRING             { version_check (&@2, $2); }
 | "%skeleton" STRING
     {
@@ -343,6 +349,11 @@ prologue_declaration:
 | /*FIXME: Err?  What is this horror doing here? */ ";"
 ;
 
+params:
+   params "{...}"  { add_param (current_param, $2, @2); }
+| "{...}"          { add_param (current_param, $1, @1); }
+;
+
 
 /*----------------------.
 | grammar_declaration.  |
@@ -717,23 +728,25 @@ add_param (param_type type, char *decl, location loc)
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     "_"
     "0123456789";
+
   char const *name_start = NULL;
-  char *p;
-
-  /* Stop on last actual character.  */
-  for (p = decl; p[1]; p++)
-    if ((p == decl
-        || ! memchr (alphanum, p[-1], sizeof alphanum))
-       && memchr (alphanum, p[0], sizeof alphanum - 10))
-      name_start = p;
-
-  /* Strip the surrounding '{' and '}', and any blanks just inside
-     the braces.  */
-  while (*--p == ' ' || *p == '\t')
-    continue;
-  p[1] = '\0';
-  while (*++decl == ' ' || *decl == '\t')
-    continue;
+  {
+    char *p;
+    /* Stop on last actual character.  */
+    for (p = decl; p[1]; p++)
+      if ((p == decl
+           || ! memchr (alphanum, p[-1], sizeof alphanum))
+          && memchr (alphanum, p[0], sizeof alphanum - 10))
+        name_start = p;
+
+    /* Strip the surrounding '{' and '}', and any blanks just inside
+       the braces.  */
+    while (*--p == ' ' || *p == '\t')
+      continue;
+    p[1] = '\0';
+    while (*++decl == ' ' || *decl == '\t')
+      continue;
+  }
 
   if (! name_start)
     complain_at (loc, _("missing identifier in parameter declaration"));