]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
lalr1.cc: don't discard non-existent lookahead on syntax error.
[bison.git] / src / parse-gram.y
index 683a05ff4556b5d2d742fe7deef10a3df4d5654e..4d48d7adfcb111f92fdeba634fb8e5f61efccf37 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
@@ -151,6 +151,7 @@ static char const *char_name (char);
 ;
 
 %token BRACED_CODE     "{...}"
+%token BRACKETED_ID    "[identifier]"
 %token CHAR            "char"
 %token EPILOGUE        "epilogue"
 %token EQUAL           "="
@@ -163,7 +164,6 @@ static char const *char_name (char);
 %token TAG             "<tag>"
 %token TAG_ANY         "<*>"
 %token TAG_NONE        "<>"
-%token BRACKETED_ID    "[identifier]"
 
 %type <character> CHAR
 %printer { fputs (char_name ($$), stderr); } CHAR
@@ -177,22 +177,23 @@ static char const *char_name (char);
 %printer { fprintf (stderr, "{\n%s\n}", $$); }
         braceless content.opt "{...}" "%{...%}" EPILOGUE
 
-%type <uniqstr> TAG ID ID_COLON BRACKETED_ID PERCENT_FLAG variable
-%type <named_ref> named_ref.opt
-%printer { fputs ($$, stderr); } ID variable
+%type <uniqstr> BRACKETED_ID ID ID_COLON PERCENT_FLAG TAG variable
+%printer { fputs ($$, stderr); } <uniqstr>
+%printer { fprintf (stderr, "[%s]", $$); } BRACKETED_ID
 %printer { fprintf (stderr, "%s:", $$); } ID_COLON
 %printer { fprintf (stderr, "%%%s", $$); } PERCENT_FLAG
 %printer { fprintf (stderr, "<%s>", $$); } TAG
 
 %type <integer> INT
-%printer { fprintf (stderr, "%d", $$); } INT
+%printer { fprintf (stderr, "%d", $$); } <integer>
 
-%type <symbol> id id_colon symbol symbol.prec string_as_id
-%printer { fprintf (stderr, "%s", $$->tag); } id symbol string_as_id
+%type <symbol> id id_colon string_as_id symbol symbol.prec
+%printer { fprintf (stderr, "%s", $$->tag); } <symbol>
 %printer { fprintf (stderr, "%s:", $$->tag); } id_colon
 
 %type <assoc> precedence_declarator
 %type <list>  symbols.1 symbols.prec generic_symlist generic_symlist_item
+%type <named_ref> named_ref.opt
 
 /*---------.
 | %param.  |
@@ -203,6 +204,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 +220,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 +232,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 +318,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 +350,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 +729,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"));