]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
* src/parse-gram.y (grammar_declaration): Don't confuse Doxygen (at
[bison.git] / src / parse-gram.y
index f45b323ca5e18c9a8ee380bde2505d2011289185..bc012637d70367d3f260031ce1ac52f9cd2ec3d9 100644 (file)
@@ -23,6 +23,8 @@
 #include <config.h>
 #include "system.h"
 
 #include <config.h>
 #include "system.h"
 
+#include <strverscmp.h>
+
 #include "complain.h"
 #include "conflicts.h"
 #include "files.h"
 #include "complain.h"
 #include "conflicts.h"
 #include "files.h"
@@ -34,7 +36,6 @@
 #include "symlist.h"
 #include "scan-gram.h"
 #include "scan-code.h"
 #include "symlist.h"
 #include "scan-gram.h"
 #include "scan-code.h"
-#include "strverscmp.h"
 
 #define YYLLOC_DEFAULT(Current, Rhs, N)  (Current) = lloc_default (Rhs, N)
 static YYLTYPE lloc_default (YYLTYPE const *, int);
 
 #define YYLLOC_DEFAULT(Current, Rhs, N)  (Current) = lloc_default (Rhs, N)
 static YYLTYPE lloc_default (YYLTYPE const *, int);
@@ -53,26 +54,25 @@ static void gram_error (location const *, char const *);
 
 static char const *char_name (char);
 
 
 static char const *char_name (char);
 
-static void add_param (char const *, char *, location);
+/** Add a lex-param or a parse-param.
+ *
+ * \param type  \a lex_param or \a parse_param
+ * \param decl  the formal argument
+ * \param loc   the location in the source.
+ */
+static void add_param (char const *type, char *decl, location loc);
+
 
 static symbol_class current_class = unknown_sym;
 
 static symbol_class current_class = unknown_sym;
-static uniqstr current_type = 0;
+static uniqstr current_type = NULL;
 static symbol *current_lhs;
 static location current_lhs_location;
 static int current_prec = 0;
 
 static symbol *current_lhs;
 static location current_lhs_location;
 static int current_prec = 0;
 
-#ifdef UINT_FAST8_MAX
-# define YYTYPE_UINT8 uint_fast8_t
-#endif
-#ifdef INT_FAST8_MAX
-# define YYTYPE_INT8 int_fast8_t
-#endif
-#ifdef UINT_FAST16_MAX
-# define YYTYPE_UINT16 uint_fast16_t
-#endif
-#ifdef INT_FAST16_MAX
-# define YYTYPE_INT16 int_fast16_t
-#endif
+#define YYTYPE_INT16 int_fast16_t
+#define YYTYPE_INT8 int_fast8_t
+#define YYTYPE_UINT16 uint_fast16_t
+#define YYTYPE_UINT8 uint_fast8_t
 %}
 
 %debug
 %}
 
 %debug
@@ -88,8 +88,8 @@ static int current_prec = 0;
 {
   /* Bison's grammar can initial empty locations, hence a default
      location is needed. */
 {
   /* Bison's grammar can initial empty locations, hence a default
      location is needed. */
-  boundary_set (&@$.start, current_file, 1, 0);
-  boundary_set (&@$.end, current_file, 1, 0);
+  boundary_set (&@$.start, current_file, 1, 1);
+  boundary_set (&@$.end, current_file, 1, 1);
 }
 
 /* Only NUMBERS have a value.  */
 }
 
 /* Only NUMBERS have a value.  */
@@ -130,10 +130,13 @@ static int current_prec = 0;
 `----------------------*/
 
 %token
 `----------------------*/
 
 %token
+  PERCENT_AFTER_HEADER    "%after-header"
+  PERCENT_BEFORE_HEADER   "%before-header"
   PERCENT_DEBUG           "%debug"
   PERCENT_DEFAULT_PREC    "%default-prec"
   PERCENT_DEFINE          "%define"
   PERCENT_DEFINES         "%defines"
   PERCENT_DEBUG           "%debug"
   PERCENT_DEFAULT_PREC    "%default-prec"
   PERCENT_DEFINE          "%define"
   PERCENT_DEFINES         "%defines"
+  PERCENT_END_HEADER      "%end-header"
   PERCENT_ERROR_VERBOSE   "%error-verbose"
   PERCENT_EXPECT          "%expect"
   PERCENT_EXPECT_RR      "%expect-rr"
   PERCENT_ERROR_VERBOSE   "%error-verbose"
   PERCENT_EXPECT          "%expect"
   PERCENT_EXPECT_RR      "%expect-rr"
@@ -153,6 +156,7 @@ static int current_prec = 0;
   PERCENT_REQUIRE        "%require"
   PERCENT_SKELETON        "%skeleton"
   PERCENT_START           "%start"
   PERCENT_REQUIRE        "%require"
   PERCENT_SKELETON        "%skeleton"
   PERCENT_START           "%start"
+  PERCENT_START_HEADER    "%start-header"
   PERCENT_TOKEN_TABLE     "%token-table"
   PERCENT_VERBOSE         "%verbose"
   PERCENT_YACC            "%yacc"
   PERCENT_TOKEN_TABLE     "%token-table"
   PERCENT_VERBOSE         "%verbose"
   PERCENT_YACC            "%yacc"
@@ -173,10 +177,13 @@ static int current_prec = 0;
 %type <character> CHAR
 %printer { fputs (char_name ($$), stderr); } CHAR
 
 %type <character> CHAR
 %printer { fputs (char_name ($$), stderr); } CHAR
 
-%type <chars> STRING string_content "{...}" PROLOGUE EPILOGUE
+/* braceless is not to be used for rule or symbol actions, as it
+   calls translate_code. */
+%type <chars> STRING "{...}" "%{...%}" EPILOGUE braceless content content.opt
 %printer { fputs (quotearg_style (c_quoting_style, $$), stderr); }
 %printer { fputs (quotearg_style (c_quoting_style, $$), stderr); }
-         STRING string_content
-%printer { fprintf (stderr, "{\n%s\n}", $$); } "{...}" PROLOGUE EPILOGUE
+         STRING
+%printer { fprintf (stderr, "{\n%s\n}", $$); }
+         braceless content content.opt "{...}" "%{...%}" EPILOGUE
 
 %type <uniqstr> TYPE ID ID_COLON
 %printer { fprintf (stderr, "<%s>", $$); } TYPE
 
 %type <uniqstr> TYPE ID ID_COLON
 %printer { fprintf (stderr, "<%s>", $$); } TYPE
@@ -195,7 +202,7 @@ static int current_prec = 0;
 %%
 
 input:
 %%
 
 input:
-  declarations "%%" grammar epilogue.opt
+  prologue_declarations "%%" grammar epilogue.opt
 ;
 
 
 ;
 
 
@@ -203,27 +210,24 @@ input:
        | Declarations: before the first %%.  |
        `------------------------------------*/
 
        | Declarations: before the first %%.  |
        `------------------------------------*/
 
-declarations:
+prologue_declarations:
   /* Nothing */
   /* Nothing */
-| declarations declaration
+| prologue_declarations prologue_declaration
 ;
 
 ;
 
-declaration:
+prologue_declaration:
   grammar_declaration
   grammar_declaration
-| PROLOGUE                         { prologue_augment (translate_code ($1, @1),
-                                                      @1); }
-| "%debug"                                 { debug_flag = true; }
-| "%define" string_content
-    {
-      static char one[] = "1";
-      muscle_insert ($2, one);
-    }
-| "%define" string_content string_content  { muscle_insert ($2, $3); }
-| "%defines"                               { defines_flag = true; }
-| "%error-verbose"                         { error_verbose = true; }
-| "%expect" INT                            { expected_sr_conflicts = $2; }
-| "%expect-rr" INT                        { expected_rr_conflicts = $2; }
-| "%file-prefix" "=" string_content        { spec_file_prefix = $3; }
+| "%{...%}"     { prologue_augment (translate_code ($1, @1), @1, union_seen); }
+| "%after-header" braceless        { prologue_augment ($2, @2, true); }
+| "%before-header" braceless       { prologue_augment ($2, @2, false); }
+| "%debug"                         { debug_flag = true; }
+| "%define" STRING content.opt     { muscle_insert ($2, $3); }
+| "%defines"                       { defines_flag = true; }
+| "%end-header" braceless          { muscle_code_grow ("end_header", $2, @2); }
+| "%error-verbose"                 { error_verbose = true; }
+| "%expect" INT                    { expected_sr_conflicts = $2; }
+| "%expect-rr" INT                { expected_rr_conflicts = $2; }
+| "%file-prefix" "=" STRING        { spec_file_prefix = $3; }
 | "%glr-parser"
     {
       nondeterministic_parser = true;
 | "%glr-parser"
     {
       nondeterministic_parser = true;
@@ -233,19 +237,20 @@ declaration:
     {
       muscle_code_grow ("initial_action", translate_symbol_action ($2, @2), @2);
     }
     {
       muscle_code_grow ("initial_action", translate_symbol_action ($2, @2), @2);
     }
-| "%lex-param" "{...}"                    { add_param ("lex_param", $2, @2); }
-| "%locations"                             { locations_flag = true; }
-| "%name-prefix" "=" string_content        { spec_name_prefix = $3; }
-| "%no-lines"                              { no_lines_flag = true; }
-| "%nondeterministic-parser"              { nondeterministic_parser = true; }
-| "%output" "=" string_content             { spec_outfile = $3; }
-| "%parse-param" "{...}"                  { add_param ("parse_param", $2, @2); }
-| "%pure-parser"                           { pure_parser = true; }
-| "%require" string_content                { version_check (&@2, $2); }
-| "%skeleton" string_content               { skeleton = $2; }
-| "%token-table"                           { token_table_flag = true; }
-| "%verbose"                               { report_flag = report_states; }
-| "%yacc"                                  { yacc_flag = true; }
+| "%lex-param" "{...}"         { add_param ("lex_param", $2, @2); }
+| "%locations"                  { locations_flag = true; }
+| "%name-prefix" "=" STRING     { spec_name_prefix = $3; }
+| "%no-lines"                   { no_lines_flag = true; }
+| "%nondeterministic-parser"   { nondeterministic_parser = true; }
+| "%output" "=" STRING          { spec_outfile = $3; }
+| "%parse-param" "{...}"       { add_param ("parse_param", $2, @2); }
+| "%pure-parser"                { pure_parser = true; }
+| "%require" STRING             { version_check (&@2, $2); }
+| "%skeleton" STRING            { skeleton = $2; }
+| "%start-header" braceless     { muscle_code_grow ("start_header", $2, @2); }
+| "%token-table"                { token_table_flag = true; }
+| "%verbose"                    { report_flag = report_states; }
+| "%yacc"                       { yacc_flag = true; }
 | /*FIXME: Err?  What is this horror doing here? */ ";"
 ;
 
 | /*FIXME: Err?  What is this horror doing here? */ ";"
 ;
 
@@ -299,16 +304,22 @@ grammar_declaration:
     {
       char const *body = $3;
 
     {
       char const *body = $3;
 
-      if (typed)
+      /* Concatenate the %union bodies.  If this is the first %union, make sure
+        the synchronization line appears after the opening '{' so as not to
+        confuse Doxygen.  Otherwise, turn the previous %union's trailing '}'
+        into '\n', and omit the new %union's leading '{'.  */
+      if (!union_seen)
+       {
+         muscle_grow ("stype", "{", "");
+       }
+      else
        {
        {
-         /* Concatenate the union bodies, turning the first one's
-            trailing '}' into '\n', and omitting the second one's '{'.  */
          char *code = muscle_find ("stype");
          code[strlen (code) - 1] = '\n';
          char *code = muscle_find ("stype");
          code[strlen (code) - 1] = '\n';
-         body++;
        }
        }
+      body++;
 
 
-      typed = true;
+      union_seen = true;
       muscle_code_grow ("stype", body, @3);
     }
 ;
       muscle_code_grow ("stype", body, @3);
     }
 ;
@@ -329,6 +340,7 @@ symbol_declaration:
     }
 | "%type" TYPE symbols.1
     {
     }
 | "%type" TYPE symbols.1
     {
+      tag_seen = true;
       symbol_list *list;
       for (list = $3; list; list = list->next)
        symbol_type_set (list->sym, $2, @2);
       symbol_list *list;
       for (list = $3; list; list = list->next)
        symbol_type_set (list->sym, $2, @2);
@@ -359,7 +371,7 @@ precedence_declarator:
 
 type.opt:
   /* Nothing. */ { current_type = NULL; }
 
 type.opt:
   /* Nothing. */ { current_type = NULL; }
-| TYPE           { current_type = $1; }
+| TYPE           { current_type = $1; tag_seen = true; }
 ;
 
 /* One or more nonterminals to be %typed. */
 ;
 
 /* One or more nonterminals to be %typed. */
@@ -373,6 +385,7 @@ symbol_def:
   TYPE
      {
        current_type = $1;
   TYPE
      {
        current_type = $1;
+       tag_seen = true;
      }
 | id
      {
      }
 | id
      {
@@ -443,8 +456,7 @@ rhs:
 | rhs symbol
     { grammar_current_rule_symbol_append ($2, @2); }
 | rhs "{...}"
 | rhs symbol
     { grammar_current_rule_symbol_append ($2, @2); }
 | rhs "{...}"
-    { grammar_current_rule_action_append (gram_last_string,
-                                         gram_last_braced_code_loc); }
+    { grammar_current_rule_action_append ($2, @2); }
 | rhs "%prec" symbol
     { grammar_current_rule_prec_set ($3, @3); }
 | rhs "%dprec" INT
 | rhs "%prec" symbol
     { grammar_current_rule_prec_set ($3, @3); }
 | rhs "%dprec" INT
@@ -454,6 +466,35 @@ rhs:
 ;
 
 
 ;
 
 
+/*-----------*
+ | content.  |
+ *-----------*/
+
+content:
+  STRING
+| braceless
+;
+
+/* Some content or "1" by default. */
+content.opt:
+  /* Nothing. */
+    {
+      static char one[] = "1";
+      $$ = one;
+    }
+| content
+;
+
+
+braceless:
+  "{...}"
+    {
+      $1[strlen ($1) - 1] = '\n';
+      $$ = translate_code ($1 + 1, @1);
+    }
+;
+
+
 /*---------------*
  | Identifiers.  |
  *---------------*/
 /*---------------*
  | Identifiers.  |
  *---------------*/
@@ -463,7 +504,7 @@ rhs:
 
 id:
   ID
 
 id:
   ID
-    { $$ = symbol_get ($1, @1); }
+    { $$ = symbol_from_uniqstr ($1, @1); }
 | CHAR
     {
       $$ = symbol_get (char_name ($1), @1);
 | CHAR
     {
       $$ = symbol_get (char_name ($1), @1);
@@ -473,7 +514,7 @@ id:
 ;
 
 id_colon:
 ;
 
 id_colon:
-  ID_COLON { $$ = symbol_get ($1, @1); }
+  ID_COLON { $$ = symbol_from_uniqstr ($1, @1); }
 ;
 
 
 ;
 
 
@@ -491,13 +532,6 @@ string_as_id:
     }
 ;
 
     }
 ;
 
-/* A string used for its contents.  Don't quote it.  */
-string_content:
-  STRING
-    { $$ = $1; }
-;
-
-
 epilogue.opt:
   /* Nothing.  */
 | "%%" EPILOGUE
 epilogue.opt:
   /* Nothing.  */
 | "%%" EPILOGUE
@@ -591,6 +625,7 @@ add_param (char const *type, char *decl, location loc)
   gram_scanner_last_string_free ();
 }
 
   gram_scanner_last_string_free ();
 }
 
+
 static void
 version_check (location const *loc, char const *version)
 {
 static void
 version_check (location const *loc, char const *version)
 {