+
+
+/* Return the location of the left-hand side of a rule whose
+ right-hand side is RHS[1] ... RHS[N]. Ignore empty nonterminals in
+ the right-hand side, and return an empty location equal to the end
+ boundary of RHS[0] if the right-hand side is empty. */
+
+static YYLTYPE
+lloc_default (YYLTYPE const *rhs, int n)
+{
+ int i;
+ int j;
+ YYLTYPE r;
+ r.start = r.end = rhs[n].end;
+
+ for (i = 1; i <= n; i++)
+ if (! equal_boundaries (rhs[i].start, rhs[i].end))
+ {
+ r.start = rhs[i].start;
+
+ for (j = n; i < j; j--)
+ if (! equal_boundaries (rhs[j].start, rhs[j].end))
+ break;
+ r.end = rhs[j].end;
+
+ break;
+ }
+
+ return r;
+}
+
+
+/* Add a lex-param or a parse-param (depending on TYPE) with
+ declaration DECL and location LOC. */
+
+static void
+add_param (char const *type, char const *decl, location loc)
+{
+ static char const alphanum[] =
+ "0123456789"
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "_";
+ char const *alpha = alphanum + 10;
+ char const *name_start = NULL;
+ char const *p;
+
+ for (p = decl; *p; p++)
+ if ((p == decl || ! strchr (alphanum, p[-1])) && strchr (alpha, p[0]))
+ name_start = p;
+
+ if (! name_start)
+ complain_at (loc, _("missing identifier in parameter declaration"));
+ else
+ {
+ char *name;
+ size_t name_len;
+
+ for (name_len = 1;
+ name_start[name_len] && strchr (alphanum, name_start[name_len]);
+ name_len++)
+ continue;
+
+ name = xmalloc (name_len + 1);
+ memcpy (name, name_start, name_len);
+ name[name_len] = '\0';
+ muscle_pair_list_grow (type, decl, name);
+ free (name);
+ }
+
+ scanner_last_string_free ();
+}
+