]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
glr.c: formatting changes.
[bison.git] / src / parse-gram.y
index 683a05ff4556b5d2d742fe7deef10a3df4d5654e..532349bbe40230c346b85986efd8acffe4abe397 100644 (file)
@@ -1,7 +1,6 @@
 %{/* Bison Grammar Parser                             -*- C -*-
 
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-   Foundation, Inc.
+   Copyright (C) 2002-2012 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
@@ -38,7 +37,7 @@
 static YYLTYPE lloc_default (YYLTYPE const *, int);
 
 #define YY_LOCATION_PRINT(File, Loc) \
-         location_print (File, Loc)
+          location_print (File, Loc)
 
 static void version_check (location const *loc, char const *version);
 
@@ -46,7 +45,7 @@ static void version_check (location const *loc, char const *version);
    FIXME: depends on the undocumented availability of YYLLOC.  */
 #undef  yyerror
 #define yyerror(Msg) \
-       gram_error (&yylloc, Msg)
+        gram_error (&yylloc, Msg)
 static void gram_error (location const *, char const *);
 
 static char const *char_name (char);
@@ -54,12 +53,30 @@ 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_symbol;
+  static symbol_class current_class = unknown_sym;
+  static uniqstr current_type = NULL;
+
+  /** Set the new current left-hand side symbol, possibly common
+   * to several right-hand side parts of rule.
+   */
+  static
+  void
+  current_lhs(symbol *sym, location loc, named_ref *ref)
+  {
+    current_lhs_symbol = sym;
+    current_lhs_location = loc;
+    /* In order to simplify memory management, named references for lhs
+       are always assigned by deep copy into the current symbol_list
+       node.  This is because a single named-ref in the grammar may
+       result in several uses when the user factors lhs between several
+       rules using "|".  Therefore free the parser's original copy.  */
+    free (current_lhs_named_ref);
+    current_lhs_named_ref = ref;
+  }
 
   #define YYTYPE_INT16 int_fast16_t
   #define YYTYPE_INT8 int_fast8_t
@@ -73,6 +90,7 @@ static char const *char_name (char);
 %locations
 %pure-parser
 %define parse.error "verbose"
+%define parse.lac full
 %name-prefix="gram_"
 %expect 0
 
@@ -118,7 +136,6 @@ static char const *char_name (char);
 %token PERCENT_DPREC         "%dprec"
 %token PERCENT_MERGE         "%merge"
 
-
 /*----------------------.
 | Global Declarations.  |
 `----------------------*/
@@ -151,6 +168,8 @@ static char const *char_name (char);
 ;
 
 %token BRACED_CODE     "{...}"
+%token BRACED_PREDICATE "%?{...}"
+%token BRACKETED_ID    "[identifier]"
 %token CHAR            "char"
 %token EPILOGUE        "epilogue"
 %token EQUAL           "="
@@ -163,7 +182,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
@@ -171,28 +189,29 @@ static char const *char_name (char);
 /* braceless is not to be used for rule or symbol actions, as it
    calls code_props_plain_init.  */
 %type <chars> STRING "%{...%}" EPILOGUE braceless content.opt
-%type <code> "{...}"
+%type <code> "{...}" "%?{...}"
 %printer { fputs (quotearg_style (c_quoting_style, $$), stderr); }
-        STRING
+         STRING
 %printer { fprintf (stderr, "{\n%s\n}", $$); }
-        braceless content.opt "{...}" "%{...%}" EPILOGUE
+         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 +222,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 +238,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 +250,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:
@@ -245,9 +270,9 @@ input:
 ;
 
 
-       /*------------------------------------.
-       | Declarations: before the first %%.  |
-       `------------------------------------*/
+        /*------------------------------------.
+        | Declarations: before the first %%.  |
+        `------------------------------------*/
 
 prologue_declarations:
   /* Nothing */
@@ -287,7 +312,7 @@ prologue_declaration:
                                     MUSCLE_PERCENT_DEFINE_GRAMMAR_FILE);
     }
 | "%expect" INT                    { expected_sr_conflicts = $2; }
-| "%expect-rr" INT                { expected_rr_conflicts = $2; }
+| "%expect-rr" INT                 { expected_rr_conflicts = $2; }
 | "%file-prefix" STRING            { spec_file_prefix = $2; }
 | "%file-prefix" "=" STRING        { spec_file_prefix = $3; } /* deprecated */
 | "%glr-parser"
@@ -304,19 +329,19 @@ prologue_declaration:
       muscle_code_grow ("initial_action", action.code, @2);
       code_scanner_last_string_free ();
     }
-| "%language" STRING           { language_argmatch ($2, grammar_prio, @1); }
+| "%language" STRING            { language_argmatch ($2, grammar_prio, @1); }
 | "%name-prefix" STRING         { spec_name_prefix = $2; }
 | "%name-prefix" "=" STRING     { spec_name_prefix = $3; } /* deprecated */
 | "%no-lines"                   { no_lines_flag = true; }
-| "%nondeterministic-parser"   { nondeterministic_parser = true; }
+| "%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
     {
       char const *skeleton_user = $2;
-      if (strchr (skeleton_user, '/'))
+      if (mbschr (skeleton_user, '/'))
         {
           size_t dir_length = strlen (current_file);
           char *skeleton_build;
@@ -343,6 +368,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.  |
@@ -359,14 +389,14 @@ grammar_declaration:
     {
       symbol_list *list;
       for (list = $3; list; list = list->next)
-       symbol_list_destructor_set (list, $2, @2);
+        symbol_list_destructor_set (list, $2, @2);
       symbol_list_free ($3);
     }
 | "%printer" "{...}" generic_symlist
     {
       symbol_list *list;
       for (list = $3; list; list = list->next)
-       symbol_list_printer_set (list, $2, @2);
+        symbol_list_printer_set (list, $2, @2);
       symbol_list_free ($3);
     }
 | "%default-prec"
@@ -431,7 +461,7 @@ symbol_declaration:
       symbol_list *list;
       tag_seen = true;
       for (list = $3; list; list = list->next)
-       symbol_type_set (list->content.sym, $2, @2);
+        symbol_type_set (list->content.sym, $2, @2);
       symbol_list_free ($3);
     }
 ;
@@ -442,10 +472,10 @@ precedence_declaration:
       symbol_list *list;
       ++current_prec;
       for (list = $3; list; list = list->next)
-       {
-         symbol_type_set (list->content.sym, current_type, @2);
-         symbol_precedence_set (list->content.sym, current_prec, $1, @1);
-       }
+        {
+          symbol_type_set (list->content.sym, current_type, @2);
+          symbol_precedence_set (list->content.sym, current_prec, $1, @1);
+        }
       symbol_list_free ($3);
       current_type = NULL;
     }
@@ -536,9 +566,9 @@ symbol_defs.1:
 ;
 
 
-       /*------------------------------------------.
-       | The grammar section: between the two %%.  |
-       `------------------------------------------*/
+        /*------------------------------------------.
+        | The grammar section: between the two %%.  |
+        `------------------------------------------*/
 
 grammar:
   rules_or_grammar_declaration
@@ -557,8 +587,11 @@ rules_or_grammar_declaration:
 ;
 
 rules:
-  id_colon named_ref.opt { current_lhs = $1; current_lhs_location = @1;
-    current_lhs_named_ref = $2; } rhses.1
+  id_colon named_ref.opt { current_lhs ($1, @1, $2); } rhses.1
+  {
+    /* Free the current lhs. */
+    current_lhs (0, @1, 0);
+  }
 ;
 
 rhses.1:
@@ -569,12 +602,14 @@ rhses.1:
 
 rhs:
   /* Nothing.  */
-    { grammar_current_rule_begin (current_lhs, current_lhs_location,
-                                 current_lhs_named_ref); }
+    { grammar_current_rule_begin (current_lhs_symbol, current_lhs_location,
+                                  current_lhs_named_ref); }
 | rhs symbol named_ref.opt
     { grammar_current_rule_symbol_append ($2, @2, $3); }
 | rhs "{...}" named_ref.opt
-    { grammar_current_rule_action_append ($2, @2, $3); }
+    { grammar_current_rule_action_append ($2, @2, $3, false); }
+| rhs "%?{...}"
+    { grammar_current_rule_action_append ($2, @2, NULL, true); }
 | rhs "%prec" symbol
     { grammar_current_rule_prec_set ($3, @3); }
 | rhs "%dprec" INT
@@ -589,7 +624,6 @@ named_ref.opt:
   BRACKETED_ID   { $$ = named_ref_new($1, @1); }
 ;
 
-
 /*---------------------------.
 | variable and content.opt.  |
 `---------------------------*/
@@ -695,14 +729,14 @@ lloc_default (YYLTYPE const *rhs, int n)
   loc.start = rhs[n].end;
   loc.end = rhs[n].end;
 
-  /* Ignore empty nonterminals the start of the the right-hand side.
+  /* Ignore empty nonterminals the start of the right-hand side.
      Do not bother to ignore them at the end of the right-hand side,
      since empty nonterminals have the same end as their predecessors.  */
   for (i = 1; i <= n; i++)
     if (! equal_boundaries (rhs[i].start, rhs[i].end))
       {
-       loc.start = rhs[i].start;
-       break;
+        loc.start = rhs[i].start;
+        break;
       }
 
   return loc;
@@ -717,23 +751,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"));
@@ -743,9 +779,9 @@ add_param (param_type type, char *decl, location loc)
       size_t name_len;
 
       for (name_len = 1;
-          memchr (alphanum, name_start[name_len], sizeof alphanum);
-          name_len++)
-       continue;
+           memchr (alphanum, name_start[name_len], sizeof alphanum);
+           name_len++)
+        continue;
 
       name = xmalloc (name_len + 1);
       memcpy (name, name_start, name_len);
@@ -767,8 +803,8 @@ version_check (location const *loc, char const *version)
   if (strverscmp (version, PACKAGE_VERSION) > 0)
     {
       complain_at (*loc, "require bison %s, but have %s",
-                  version, PACKAGE_VERSION);
-      exit (63);
+                   version, PACKAGE_VERSION);
+      exit (EX_MISMATCH);
     }
 }