]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
doc: prefer "token" to TOKEN
[bison.git] / src / parse-gram.y
index b60446880ceb4c51e0c8e2d46f2ece513c9a9553..5f77a5bd08abd0355531dadbbebe53503442c77a 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.
 
 #include <config.h>
 #include "system.h"
 
+#include "c-ctype.h"
 #include "complain.h"
 #include "conflicts.h"
 #include "files.h"
 #include "getargs.h"
 #include "gram.h"
-#include "muscle_tab.h"
+#include "muscle-tab.h"
 #include "named-ref.h"
 #include "quotearg.h"
 #include "reader.h"
 #include "symlist.h"
 #include "scan-gram.h"
 #include "scan-code.h"
+#include "xmemdup0.h"
 
 #define YYLLOC_DEFAULT(Current, Rhs, N)  (Current) = lloc_default (Rhs, N)
 static YYLTYPE lloc_default (YYLTYPE const *, int);
@@ -62,11 +63,30 @@ static void add_param (char const *type, char *decl, location loc);
 
 static symbol_class current_class = unknown_sym;
 static uniqstr current_type = NULL;
-static symbol *current_lhs;
+static symbol *current_lhs_symbol;
 static location current_lhs_location;
 static named_ref *current_lhs_named_ref;
 static int current_prec = 0;
 
+/** 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
 #define YYTYPE_UINT16 uint_fast16_t
@@ -74,13 +94,14 @@ static int current_prec = 0;
 %}
 
 %debug
-%verbose
+%define api.prefix "gram_"
+%define api.pure
+%define parse.lac full
 %defines
-%locations
-%pure-parser
 %error-verbose
-%name-prefix="gram_"
 %expect 0
+%locations
+%verbose
 
 %initial-action
 {
@@ -160,6 +181,7 @@ static int current_prec = 0;
 ;
 
 %token BRACED_CODE     "{...}"
+%token BRACKETED_ID    "[identifier]"
 %token CHAR            "char"
 %token EPILOGUE        "epilogue"
 %token EQUAL           "="
@@ -172,7 +194,6 @@ static int current_prec = 0;
 %token TYPE            "type"
 %token TYPE_TAG_ANY    "<*>"
 %token TYPE_TAG_NONE   "<>"
-%token BRACKETED_ID    "[identifier]"
 
 %type <character> CHAR
 %printer { fputs (char_name ($$), stderr); } CHAR
@@ -186,21 +207,23 @@ static int current_prec = 0;
 %printer { fprintf (stderr, "{\n%s\n}", $$); }
         braceless content.opt "{...}" "%{...%}" EPILOGUE
 
-%type <uniqstr> TYPE ID ID_COLON BRACKETED_ID variable
-%type <named_ref> named_ref.opt
-%printer { fprintf (stderr, "<%s>", $$); } TYPE
-%printer { fputs ($$, stderr); } ID variable
+%type <uniqstr> BRACKETED_ID ID ID_COLON TYPE variable
+%printer { fputs ($$, stderr); } <uniqstr>
+%printer { fprintf (stderr, "[%s]", $$); } BRACKETED_ID
 %printer { fprintf (stderr, "%s:", $$); } ID_COLON
+%printer { fprintf (stderr, "<%s>", $$); } TYPE
 
 %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
+
 %%
 
 input:
@@ -229,7 +252,7 @@ prologue_declaration:
                         plain_code.code, @1);
       code_scanner_last_string_free ();
     }
-| "%debug"                         { debug_flag = true; }
+| "%debug"                         { debug = true; }
 | "%define" variable content.opt
     {
       muscle_percent_define_insert ($2, @2, $3,
@@ -289,7 +312,7 @@ prologue_declaration:
 | "%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;
@@ -301,7 +324,7 @@ prologue_declaration:
             xmalloc (dir_length + 1 + strlen (skeleton_user) + 1);
           if (dir_length > 0)
             {
-              strncpy (skeleton_build, current_file, dir_length);
+              memcpy (skeleton_build, current_file, dir_length);
               skeleton_build[dir_length++] = '/';
             }
           strcpy (skeleton_build + dir_length, skeleton_user);
@@ -325,17 +348,27 @@ grammar_declaration:
     }
 | "%destructor" "{...}" generic_symlist
     {
-      symbol_list *list;
-      for (list = $3; list; list = list->next)
-       symbol_list_destructor_set (list, $2, @2);
-      symbol_list_free ($3);
+      code_props code;
+      code_props_symbol_action_init (&code, $2, @2);
+      code_props_translate_code (&code);
+      {
+        symbol_list *list;
+        for (list = $3; list; list = list->next)
+          symbol_list_destructor_set (list, &code);
+        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_free ($3);
+      code_props code;
+      code_props_symbol_action_init (&code, $2, @2);
+      code_props_translate_code (&code);
+      {
+        symbol_list *list;
+        for (list = $3; list; list = list->next)
+          symbol_list_printer_set (list, &code);
+        symbol_list_free ($3);
+      }
     }
 | "%default-prec"
     {
@@ -524,8 +557,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:
@@ -536,7 +572,7 @@ rhses.1:
 
 rhs:
   /* Nothing.  */
-    { grammar_current_rule_begin (current_lhs, current_lhs_location,
+    { 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); }
@@ -662,7 +698,7 @@ 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++)
@@ -699,27 +735,19 @@ add_param (char const *type, char *decl, location loc)
 
   /* Strip the surrounding '{' and '}', and any blanks just inside
      the braces.  */
-  while (*--p == ' ' || *p == '\t')
-    continue;
+  --p;
+  while (c_isspace ((unsigned char) *p))
+    --p;
   p[1] = '\0';
-  while (*++decl == ' ' || *decl == '\t')
-    continue;
+  ++decl;
+  while (c_isspace ((unsigned char) *decl))
+    ++decl;
 
   if (! name_start)
     complain_at (loc, _("missing identifier in parameter declaration"));
   else
     {
-      char *name;
-      size_t name_len;
-
-      for (name_len = 1;
-          memchr (alphanum, name_start[name_len], sizeof alphanum);
-          name_len++)
-       continue;
-
-      name = xmalloc (name_len + 1);
-      memcpy (name, name_start, name_len);
-      name[name_len] = '\0';
+      char *name = xmemdup0 (name_start, strspn (name_start, alphanum));
       muscle_pair_list_grow (type, decl, name);
       free (name);
     }
@@ -734,8 +762,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);
     }
 }