]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
Fix code formatting.
[bison.git] / src / parse-gram.y
index e189e1434611b97b87d868a3d8b7477ae8b88a93..ae9eb535682e889ea203d8697f5c083cf5fa500e 100644 (file)
@@ -32,6 +32,8 @@
 #include "quotearg.h"
 #include "reader.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)
@@ -49,6 +51,8 @@ static void version_check (location const *loc, char const *version);
        gram_error (&yylloc, Msg)
 static void gram_error (location const *, char const *);
 
+static char const *char_name (char);
+
 static void add_param (char const *, char *, location);
 
 static symbol_class current_class = unknown_sym;
@@ -84,9 +88,8 @@ static int current_prec = 0;
 {
   /* Bison's grammar can initial empty locations, hence a default
      location is needed. */
-  @$.start.file   = @$.end.file   = current_file;
-  @$.start.line   = @$.end.line   = 1;
-  @$.start.column = @$.end.column = 0;
+  boundary_set (&@$.start, current_file, 1, 0);
+  boundary_set (&@$.end, current_file, 1, 0);
 }
 
 /* Only NUMBERS have a value.  */
@@ -98,6 +101,7 @@ static int current_prec = 0;
   char *chars;
   assoc assoc;
   uniqstr uniqstr;
+  unsigned char character;
 };
 
 /* Define the tokens together with their human representation.  */
@@ -109,10 +113,8 @@ static int current_prec = 0;
 %token PERCENT_NTERM       "%nterm"
 
 %token PERCENT_TYPE        "%type"
-%token PERCENT_DESTRUCTOR  "%destructor {...}"
-%token PERCENT_PRINTER     "%printer {...}"
-
-%token PERCENT_UNION       "%union {...}"
+%token PERCENT_DESTRUCTOR  "%destructor"
+%token PERCENT_PRINTER     "%printer"
 
 %token PERCENT_LEFT        "%left"
 %token PERCENT_RIGHT       "%right"
@@ -128,17 +130,20 @@ static int current_prec = 0;
 `----------------------*/
 
 %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_END_HEADER      "%end-header"
   PERCENT_ERROR_VERBOSE   "%error-verbose"
   PERCENT_EXPECT          "%expect"
   PERCENT_EXPECT_RR      "%expect-rr"
   PERCENT_FILE_PREFIX     "%file-prefix"
   PERCENT_GLR_PARSER      "%glr-parser"
-  PERCENT_INITIAL_ACTION  "%initial-action {...}"
-  PERCENT_LEX_PARAM       "%lex-param {...}"
+  PERCENT_INITIAL_ACTION  "%initial-action"
+  PERCENT_LEX_PARAM       "%lex-param"
   PERCENT_LOCATIONS       "%locations"
   PERCENT_NAME_PREFIX     "%name-prefix"
   PERCENT_NO_DEFAULT_PREC "%no-default-prec"
@@ -146,54 +151,49 @@ static int current_prec = 0;
   PERCENT_NONDETERMINISTIC_PARSER
                          "%nondeterministic-parser"
   PERCENT_OUTPUT          "%output"
-  PERCENT_PARSE_PARAM     "%parse-param {...}"
+  PERCENT_PARSE_PARAM     "%parse-param"
   PERCENT_PURE_PARSER     "%pure-parser"
   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"
 ;
 
-%token TYPE            "type"
+%token BRACED_CODE     "{...}"
+%token CHAR            "char"
+%token EPILOGUE        "epilogue"
 %token EQUAL           "="
-%token SEMICOLON       ";"
-%token PIPE            "|"
 %token ID              "identifier"
 %token ID_COLON        "identifier:"
 %token PERCENT_PERCENT "%%"
+%token PIPE            "|"
 %token PROLOGUE        "%{...%}"
-%token EPILOGUE        "epilogue"
-%token BRACED_CODE     "{...}"
+%token SEMICOLON       ";"
+%token TYPE            "type"
+
+%type <character> CHAR
+%printer { fputs (char_name ($$), stderr); } CHAR
 
+%type <chars> STRING string_content "{...}" PROLOGUE EPILOGUE
+%printer { fputs (quotearg_style (c_quoting_style, $$), stderr); }
+         STRING string_content
+%printer { fprintf (stderr, "{\n%s\n}", $$); } "{...}" PROLOGUE EPILOGUE
 
-%type <chars> STRING string_content
-             "%destructor {...}"
-             "%initial-action {...}"
-             "%lex-param {...}"
-             "%parse-param {...}"
-             "%printer {...}"
-             "%union {...}"
-             PROLOGUE EPILOGUE
-%printer { fprintf (stderr, "\"%s\"", $$); }
-             STRING string_content
-%printer { fprintf (stderr, "{\n%s\n}", $$); }
-             "%destructor {...}"
-             "%initial-action {...}"
-             "%lex-param {...}"
-             "%parse-param {...}"
-             "%printer {...}"
-             "%union {...}"
-             PROLOGUE EPILOGUE
-%type <uniqstr> TYPE
+%type <uniqstr> TYPE ID ID_COLON
 %printer { fprintf (stderr, "<%s>", $$); } TYPE
+%printer { fputs ($$, stderr); } ID
+%printer { fprintf (stderr, "%s:", $$); } ID_COLON
+
 %type <integer> INT
 %printer { fprintf (stderr, "%d", $$); } INT
-%type <symbol> ID symbol string_as_id
-%printer { fprintf (stderr, "%s", $$->tag); } ID symbol string_as_id
-%type <symbol> ID_COLON
-%printer { fprintf (stderr, "%s:", $$->tag); } ID_COLON
+
+%type <symbol> id id_colon symbol string_as_id
+%printer { fprintf (stderr, "%s", $$->tag); } id symbol string_as_id
+%printer { fprintf (stderr, "%s:", $$->tag); } id_colon
+
 %type <assoc> precedence_declarator
 %type <list>  symbols.1
 %%
@@ -214,7 +214,22 @@ declarations:
 
 declaration:
   grammar_declaration
-| PROLOGUE                                 { prologue_augment ($1, @1); }
+| PROLOGUE
+    {
+      prologue_augment (translate_code ($1, @1), @1, typed);
+    }
+| "%after-header" "{...}"
+    {
+      /* Remove the '{', and replace the '}' with '\n'.  */
+      $2[strlen ($2) - 1] = '\n';
+      prologue_augment (translate_code ($2+1, @2), @2, true);
+    }
+| "%before-header" "{...}"
+    {
+      /* Remove the '{', and replace the '}' with '\n'.  */
+      $2[strlen ($2) - 1] = '\n';
+      prologue_augment (translate_code ($2+1, @2), @2, false);
+    }
 | "%debug"                                 { debug_flag = true; }
 | "%define" string_content
     {
@@ -223,6 +238,12 @@ declaration:
     }
 | "%define" string_content string_content  { muscle_insert ($2, $3); }
 | "%defines"                               { defines_flag = true; }
+| "%end-header" "{...}"
+    {
+      /* Remove the '{', and replace the '}' with '\n'.  */
+      $2[strlen ($2) - 1] = '\n';
+      muscle_code_grow ("end_header", translate_code ($2+1, @2), @2);
+    }
 | "%error-verbose"                         { error_verbose = true; }
 | "%expect" INT                            { expected_sr_conflicts = $2; }
 | "%expect-rr" INT                        { expected_rr_conflicts = $2; }
@@ -232,20 +253,26 @@ declaration:
       nondeterministic_parser = true;
       glr_parser = true;
     }
-| "%initial-action {...}"
+| "%initial-action" "{...}"
     {
-      muscle_code_grow ("initial_action", $1, @1);
+      muscle_code_grow ("initial_action", translate_symbol_action ($2, @2), @2);
     }
-| "%lex-param {...}"                      { add_param ("lex_param", $1, @1); }
+| "%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", $1, @1); }
+| "%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; }
+| "%start-header" "{...}"
+    {
+      /* Remove the '{', and replace the '}' with '\n'.  */
+      $2[strlen ($2) - 1] = '\n';
+      muscle_code_grow ("start_header", translate_code ($2+1, @2), @2);
+    }
 | "%token-table"                           { token_table_flag = true; }
 | "%verbose"                               { report_flag = report_states; }
 | "%yacc"                                  { yacc_flag = true; }
@@ -259,35 +286,21 @@ grammar_declaration:
     {
       grammar_start_symbol_set ($2, @2);
     }
-| "%union {...}"
-    {
-      char const *body = $1;
-
-      if (typed)
-       {
-         /* 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';
-         body++;
-       }
-
-      typed = true;
-      muscle_code_grow ("stype", body, @1);
-    }
-| "%destructor {...}" symbols.1
+| "%destructor" "{...}" symbols.1
     {
       symbol_list *list;
-      for (list = $2; list; list = list->next)
-       symbol_destructor_set (list->sym, $1, @1);
-      symbol_list_free ($2);
+      const char *action = translate_symbol_action ($2, @2);
+      for (list = $3; list; list = list->next)
+       symbol_destructor_set (list->sym, action, @2);
+      symbol_list_free ($3);
     }
-| "%printer {...}" symbols.1
+| "%printer" "{...}" symbols.1
     {
       symbol_list *list;
-      for (list = $2; list; list = list->next)
-       symbol_printer_set (list->sym, $1, @1);
-      symbol_list_free ($2);
+      const char *action = translate_symbol_action ($2, @2);
+      for (list = $3; list; list = list->next)
+       symbol_printer_set (list->sym, action, @2);
+      symbol_list_free ($3);
     }
 | "%default-prec"
     {
@@ -299,6 +312,40 @@ grammar_declaration:
     }
 ;
 
+
+/*----------*
+ | %union.  |
+ *----------*/
+
+%token PERCENT_UNION "%union";
+
+union_name:
+  /* Nothing. */ {}
+| ID             { muscle_code_grow ("union_name", $1, @1); }
+;
+
+grammar_declaration:
+  "%union" union_name "{...}"
+    {
+      char const *body = $3;
+
+      if (typed)
+       {
+         /* 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';
+         body++;
+       }
+
+      typed = true;
+      muscle_code_grow ("stype", body, @3);
+    }
+;
+
+
+
+
 symbol_declaration:
   "%nterm" { current_class = nterm_sym; } symbol_defs.1
     {
@@ -346,7 +393,6 @@ type.opt:
 ;
 
 /* One or more nonterminals to be %typed. */
-
 symbols.1:
   symbol            { $$ = symbol_list_new ($1, @1); }
 | symbols.1 symbol  { $$ = symbol_list_prepend ($1, $2, @2); }
@@ -358,24 +404,24 @@ symbol_def:
      {
        current_type = $1;
      }
-| ID
+| id
      {
        symbol_class_set ($1, current_class, @1, true);
        symbol_type_set ($1, current_type, @1);
      }
-| ID INT
+| id INT
     {
       symbol_class_set ($1, current_class, @1, true);
       symbol_type_set ($1, current_type, @1);
       symbol_user_token_number_set ($1, $2, @2);
     }
-| ID string_as_id
+| id string_as_id
     {
       symbol_class_set ($1, current_class, @1, true);
       symbol_type_set ($1, current_type, @1);
       symbol_make_alias ($1, $2, @$);
     }
-| ID INT string_as_id
+| id INT string_as_id
     {
       symbol_class_set ($1, current_class, @1, true);
       symbol_type_set ($1, current_type, @1);
@@ -412,7 +458,7 @@ rules_or_grammar_declaration:
 ;
 
 rules:
-  ID_COLON { current_lhs = $1; current_lhs_location = @1; } rhses.1
+  id_colon { current_lhs = $1; current_lhs_location = @1; } rhses.1
 ;
 
 rhses.1:
@@ -426,7 +472,8 @@ rhs:
     { grammar_current_rule_begin (current_lhs, current_lhs_location); }
 | rhs symbol
     { grammar_current_rule_symbol_append ($2, @2); }
-| rhs action
+| rhs "{...}"
+    { grammar_current_rule_action_append ($2, @2); }
 | rhs "%prec" symbol
     { grammar_current_rule_prec_set ($3, @3); }
 | rhs "%dprec" INT
@@ -435,26 +482,33 @@ rhs:
     { grammar_current_rule_merge_set ($3, @3); }
 ;
 
-symbol:
-  ID              { $$ = $1; }
-| string_as_id    { $$ = $1; }
+
+/*---------------*
+ | Identifiers.  |
+ *---------------*/
+
+/* Identifiers are returned as uniqstr values by the scanner.
+   Depending on their use, we may need to make them genuine symbols.  */
+
+id:
+  ID
+    { $$ = symbol_from_uniqstr ($1, @1); }
+| CHAR
+    {
+      $$ = symbol_get (char_name ($1), @1);
+      symbol_class_set ($$, token_sym, @1, false);
+      symbol_user_token_number_set ($$, $1, @1);
+    }
 ;
 
-/* Handle the semantics of an action specially, with a mid-rule
-   action, so that grammar_current_rule_action_append is invoked
-   immediately after the braced code is read by the scanner.
-
-   This implementation relies on the LALR(1) parsing algorithm.
-   If grammar_current_rule_action_append were executed in a normal
-   action for this rule, then when the input grammar contains two
-   successive actions, the scanner would have to read both actions
-   before reducing this rule.  That wouldn't work, since the scanner
-   relies on all preceding input actions being processed by
-   grammar_current_rule_action_append before it scans the next
-   action.  */
-action:
-    { grammar_current_rule_action_append (last_string, last_braced_code_loc); }
-  BRACED_CODE
+id_colon:
+  ID_COLON { $$ = symbol_from_uniqstr ($1, @1); }
+;
+
+
+symbol:
+  id
+| string_as_id
 ;
 
 /* A string used as an ID: quote it.  */
@@ -477,8 +531,8 @@ epilogue.opt:
   /* Nothing.  */
 | "%%" EPILOGUE
     {
-      muscle_code_grow ("epilogue", $2, @2);
-      scanner_last_string_free ();
+      muscle_code_grow ("epilogue", translate_code ($2, @2), @2);
+      gram_scanner_last_string_free ();
     }
 ;
 
@@ -563,7 +617,7 @@ add_param (char const *type, char *decl, location loc)
       free (name);
     }
 
-  scanner_last_string_free ();
+  gram_scanner_last_string_free ();
 }
 
 static void
@@ -588,3 +642,16 @@ token_name (int type)
 {
   return yytname[YYTRANSLATE (type)];
 }
+
+static char const *
+char_name (char c)
+{
+  if (c == '\'')
+    return "'\\''";
+  else
+    {
+      char buf[4];
+      buf[0] = '\''; buf[1] = c; buf[2] = '\''; buf[3] = '\0';
+      return quotearg_style (escape_quoting_style, buf);
+    }
+}