]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
* tests/actions.at (Actions after errors): New test case.
[bison.git] / src / parse-gram.y
index 06a32c31da51c1ab14623b41e030c59d3b4c0b22..8af3e88501c802e8b7f8b0569a9666712eee3ac3 100644 (file)
@@ -30,6 +30,7 @@
 
 %{
 #include "system.h"
 
 %{
 #include "system.h"
+#include "complain.h"
 #include "muscle_tab.h"
 #include "files.h"
 #include "getargs.h"
 #include "muscle_tab.h"
 #include "files.h"
 #include "getargs.h"
@@ -39,7 +40,7 @@
 #include "reader.h"
 #include "conflicts.h"
 
 #include "reader.h"
 #include "conflicts.h"
 
-/* Produce verbose parse errors.  */
+/* Produce verbose syntax errors.  */
 #define YYERROR_VERBOSE 1
 #define YYLLOC_DEFAULT(Current, Rhs, N)                        \
 do {                                                   \
 #define YYERROR_VERBOSE 1
 #define YYLLOC_DEFAULT(Current, Rhs, N)                        \
 do {                                                   \
@@ -63,24 +64,21 @@ do {                                                        \
    correctly typed access to it.  */
 #define yycontrol ((gram_control_t *) gram_control)
 
    correctly typed access to it.  */
 #define yycontrol ((gram_control_t *) gram_control)
 
-/* Request detailed parse error messages, and pass them to
-   GRAM_ERROR. */
+/* Request detailed syntax error messages, and pass them to GRAM_ERROR.
+   FIXME: depends on the undocumented availability of YYLLOC.t */
 #undef  yyerror
 #define yyerror(Msg) \
 #undef  yyerror
 #define yyerror(Msg) \
-        gram_error (yycontrol, &yylloc, Msg)
+        gram_error (&yylloc, Msg)
 
 
-/* When debugging our pure parser, we want to see values and locations
-   of the tokens.  */
 #define YYPRINT(File, Type, Value) \
 #define YYPRINT(File, Type, Value) \
-        yyprint (File, &yylloc, Type, &Value)
-static void yyprint (FILE *file, const location_t *loc,
-                     int type, const yystype *value);
+        yyprint (File, Type, &Value)
+static void yyprint (FILE *file, int type, const yystype *value);
 
 symbol_class current_class = unknown_sym;
 
 symbol_class current_class = unknown_sym;
-char *current_type = 0;
+struniq_t current_type = 0;
 symbol_t *current_lhs;
 location_t current_lhs_location;
 symbol_t *current_lhs;
 location_t current_lhs_location;
-associativity current_assoc;
+assoc_t current_assoc;
 int current_prec = 0;
 braced_code_t current_braced_code = action_braced_code;
 %}
 int current_prec = 0;
 braced_code_t current_braced_code = action_braced_code;
 %}
@@ -93,13 +91,14 @@ braced_code_t current_braced_code = action_braced_code;
   symbol_list_t *list;
   int integer;
   char *string;
   symbol_list_t *list;
   int integer;
   char *string;
-  associativity assoc;
+  assoc_t assoc;
+  struniq_t struniq;
 };
 
 };
 
-/* Define the tokens together with there human representation. */
-%token GRAM_EOF 0 "end of string"
-%token STRING CHARACTER
-%token INT
+/* Define the tokens together with their human representation.  */
+%token GRAM_EOF 0 "end of file"
+%token STRING     "string"
+%token INT        "integer"
 
 %token PERCENT_TOKEN       "%token"
 %token PERCENT_NTERM       "%nterm"
 
 %token PERCENT_TOKEN       "%token"
 %token PERCENT_NTERM       "%nterm"
@@ -114,41 +113,54 @@ braced_code_t current_braced_code = action_braced_code;
 %token PERCENT_RIGHT       "%right"
 %token PERCENT_NONASSOC    "%nonassoc"
 
 %token PERCENT_RIGHT       "%right"
 %token PERCENT_NONASSOC    "%nonassoc"
 
-%token PERCENT_EXPECT "%expect"
-%token PERCENT_START "%start"
-%token PERCENT_PREC     "%prec"
-%token PERCENT_VERBOSE  "%verbose"
-%token PERCENT_ERROR_VERBOSE "%error-verbose"
-
-%token PERCENT_OUTPUT "%output"
-%token PERCENT_FILE_PREFIX "%file-prefix"
-%token PERCENT_NAME_PREFIX "%name-prefix"
-
-%token PERCENT_DEFINE "%define"
-%token PERCENT_PURE_PARSER "%pure-parser"
-
-%token PERCENT_DEFINES "%defines"
-
-%token PERCENT_YACC "%yacc"
-
-%token PERCENT_DEBUG "%debug"
-%token PERCENT_LOCATIONS "%locations"
-%token PERCENT_NO_LINES "%no-lines"
-%token PERCENT_SKELETON "%skeleton"
-%token PERCENT_TOKEN_TABLE "%token-table"
+%token PERCENT_PREC          "%prec"
+%token PERCENT_DPREC         "%dprec"
+%token PERCENT_MERGE         "%merge"
+
+
+/*----------------------.
+| Global Declarations.  |
+`----------------------*/
+
+%token
+  PERCENT_DEBUG         "%debug"
+  PERCENT_DEFINE        "%define"
+  PERCENT_DEFINES       "%defines"
+  PERCENT_ERROR_VERBOSE "%error-verbose"
+  PERCENT_EXPECT        "%expect"
+  PERCENT_FILE_PREFIX   "%file-prefix"
+  PERCENT_GLR_PARSER    "%glr-parser"
+  PERCENT_LEX_PARAM     "%lex-param"
+  PERCENT_LOCATIONS     "%locations"
+  PERCENT_NAME_PREFIX   "%name-prefix"
+  PERCENT_NO_LINES      "%no-lines"
+  PERCENT_OUTPUT        "%output"
+  PERCENT_PARSE_PARAM   "%parse-param"
+  PERCENT_PURE_PARSER   "%pure-parser"
+  PERCENT_SKELETON      "%skeleton"
+  PERCENT_START         "%start"
+  PERCENT_TOKEN_TABLE   "%token-table"
+  PERCENT_VERBOSE       "%verbose"
+  PERCENT_YACC          "%yacc"
+;
 
 
-%token TYPE
-%token EQUAL "="
-%token SEMICOLON ";"
-%token COLON ":"
-%token PIPE "|"
-%token ID "identifier"
+%token TYPE            "type"
+%token EQUAL           "="
+%token SEMICOLON       ";"
+%token COLON           ":"
+%token COMMA           ","
+%token PIPE            "|"
+%token ID              "identifier"
 %token PERCENT_PERCENT "%%"
 %token PERCENT_PERCENT "%%"
-%token PROLOGUE EPILOGUE
-%token BRACED_CODE
+%token PROLOGUE        "%{...%}"
+%token EPILOGUE        "epilogue"
+%token BRACED_CODE     "{...}"
 
 
-%type <string> CHARACTER TYPE STRING string_content
-               BRACED_CODE PROLOGUE EPILOGUE epilogue.opt action
+
+%type <string> STRING string_content
+               BRACED_CODE code_content action
+               PROLOGUE EPILOGUE
+%type <struniq> TYPE
 %type <integer> INT
 %type <symbol> ID symbol string_as_id
 %type <assoc> precedence_declarator
 %type <integer> INT
 %type <symbol> ID symbol string_as_id
 %type <assoc> precedence_declarator
@@ -159,7 +171,6 @@ input:
   declarations "%%" grammar epilogue.opt
     {
       yycontrol->errcode = 0;
   declarations "%%" grammar epilogue.opt
     {
       yycontrol->errcode = 0;
-      epilogue_set ($4, @4);
     }
 ;
 
     }
 ;
 
@@ -182,10 +193,21 @@ declaration:
 | "%error-verbose"                         { error_verbose = 1; }
 | "%expect" INT                            { expected_conflicts = $2; }
 | "%file-prefix" "=" string_content        { spec_file_prefix = $3; }
 | "%error-verbose"                         { error_verbose = 1; }
 | "%expect" INT                            { expected_conflicts = $2; }
 | "%file-prefix" "=" string_content        { spec_file_prefix = $3; }
+| "%glr-parser"                           { glr_parser = 1; }
+| "%lex-param" code_content "," code_content
+                           {
+                            muscle_pair_list_grow ("lex_param", $2, $4);
+                            scanner_last_string_free ();
+                          }
 | "%locations"                             { locations_flag = 1; }
 | "%name-prefix" "=" string_content        { spec_name_prefix = $3; }
 | "%no-lines"                              { no_lines_flag = 1; }
 | "%output" "=" string_content             { spec_outfile = $3; }
 | "%locations"                             { locations_flag = 1; }
 | "%name-prefix" "=" string_content        { spec_name_prefix = $3; }
 | "%no-lines"                              { no_lines_flag = 1; }
 | "%output" "=" string_content             { spec_outfile = $3; }
+| "%parse-param" code_content "," code_content
+                           {
+                            muscle_pair_list_grow ("parse_param", $2, $4);
+                            scanner_last_string_free ();
+                          }
 | "%pure-parser"                           { pure_parser = 1; }
 | "%skeleton" string_content               { skeleton = $2; }
 | "%token-table"                           { token_table_flag = 1; }
 | "%pure-parser"                           { pure_parser = 1; }
 | "%skeleton" string_content               { skeleton = $2; }
 | "%token-table"                           { token_table_flag = 1; }
@@ -212,7 +234,7 @@ grammar_declaration:
     {
       symbol_list_t *list;
       for (list = $4; list; list = list->next)
     {
       symbol_list_t *list;
       for (list = $4; list; list = list->next)
-       symbol_destructor_set (list->sym, list->location, $3);
+       symbol_destructor_set (list->sym, $3, @3);
       symbol_list_free ($4);
       current_braced_code = action_braced_code;
     }
       symbol_list_free ($4);
       current_braced_code = action_braced_code;
     }
@@ -243,7 +265,7 @@ symbol_declaration:
     {
       symbol_list_t *list;
       for (list = $3; list; list = list->next)
     {
       symbol_list_t *list;
       for (list = $3; list; list = list->next)
-       symbol_type_set (list->sym, list->location, $2);
+       symbol_type_set (list->sym, $2, @2);
       symbol_list_free ($3);
     }
 ;
       symbol_list_free ($3);
     }
 ;
@@ -255,8 +277,8 @@ precedence_declaration:
       ++current_prec;
       for (list = $3; list; list = list->next)
        {
       ++current_prec;
       for (list = $3; list; list = list->next)
        {
-         symbol_type_set (list->sym, list->location, current_type);
-         symbol_precedence_set (list->sym, list->location, current_prec, $1);
+         symbol_type_set (list->sym, current_type, @2);
+         symbol_precedence_set (list->sym, current_prec, $1, @1);
        }
       symbol_list_free ($3);
       current_type = NULL;
        }
       symbol_list_free ($3);
       current_type = NULL;
@@ -270,7 +292,7 @@ precedence_declarator:
 ;
 
 type.opt:
 ;
 
 type.opt:
-  /* Nothing. */ { current_type = NULL;}
+  /* Nothing. */ { current_type = NULL; }
 | TYPE           { current_type = $1; }
 ;
 
 | TYPE           { current_type = $1; }
 ;
 
@@ -289,27 +311,27 @@ symbol_def:
      }
 | ID
      {
      }
 | ID
      {
-       symbol_class_set ($1, current_class);
-       symbol_type_set ($1, @1, current_type);
+       symbol_class_set ($1, current_class, @1);
+       symbol_type_set ($1, current_type, @1);
      }
 | ID INT
     {
      }
 | ID INT
     {
-      symbol_class_set ($1, current_class);
-      symbol_type_set ($1, @1, current_type);
-      symbol_user_token_number_set ($1, $2);
+      symbol_class_set ($1, current_class, @1);
+      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);
-      symbol_type_set ($1, @1, current_type);
-      symbol_make_alias ($1, $2);
+      symbol_class_set ($1, current_class, @1);
+      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);
-      symbol_type_set ($1, @1, current_type);
-      symbol_user_token_number_set ($1, $2);
-      symbol_make_alias ($1, $3);
+      symbol_class_set ($1, current_class, @1);
+      symbol_type_set ($1, current_type, @1);
+      symbol_user_token_number_set ($1, $2, @2);
+      symbol_make_alias ($1, $3, @$);
     }
 ;
 
     }
 ;
 
@@ -337,6 +359,14 @@ grammar:
 rules_or_grammar_declaration:
   rules
 | grammar_declaration ";"
 rules_or_grammar_declaration:
   rules
 | grammar_declaration ";"
+    {
+      if (yacc_flag)
+       complain_at (@$, _("POSIX forbids declarations in the grammar"));
+    }
+| error ";"
+    {
+      yyerrok;
+    }
 ;
 
 rules:
 ;
 
 rules:
@@ -357,13 +387,16 @@ rhs:
 | rhs action
     { grammar_current_rule_action_append ($2, @2); }
 | rhs "%prec" symbol
 | rhs action
     { grammar_current_rule_action_append ($2, @2); }
 | rhs "%prec" symbol
-    { grammar_current_rule_prec_set ($3); }
+    { grammar_current_rule_prec_set ($3, @3); }
+| rhs "%dprec" INT
+    { grammar_current_rule_dprec_set ($3, @3); }
+| rhs "%merge" TYPE
+    { grammar_current_rule_merge_set ($3, @3); }
 ;
 
 symbol:
   ID              { $$ = $1; }
 | string_as_id    { $$ = $1; }
 ;
 
 symbol:
   ID              { $$ = $1; }
 | string_as_id    { $$ = $1; }
-| CHARACTER       { $$ = getsym ($1, @1); }
 ;
 
 action:
 ;
 
 action:
@@ -375,8 +408,8 @@ action:
 string_as_id:
   STRING
     {
 string_as_id:
   STRING
     {
-      $$ = getsym ($1, @1);
-      symbol_class_set ($$, token_sym);
+      $$ = symbol_get ($1, @1);
+      symbol_class_set ($$, token_sym, @1);
     }
 ;
 
     }
 ;
 
@@ -389,14 +422,21 @@ string_content:
     };
 
 
     };
 
 
+/* A BRACED_CODE used for its contents.  Strip the braces. */
+code_content:
+  BRACED_CODE
+    {
+      $$ = $1 + 1;
+      $$[strlen ($$) - 1] = '\0';
+    };
+
+
 epilogue.opt:
   /* Nothing.  */
 epilogue.opt:
   /* Nothing.  */
-    {
-      $$ = xstrdup ("");
-    }
 | "%%" EPILOGUE
     {
 | "%%" EPILOGUE
     {
-      $$ = $2;
+      epilogue_augment ($2, @2);
+      scanner_last_string_free ();
     }
 ;
 
     }
 ;
 
@@ -411,17 +451,11 @@ semi_colon.opt:
 
 static void
 yyprint (FILE *file,
 
 static void
 yyprint (FILE *file,
-         const location_t *loc, int type, const yystype *value)
+         int type, const yystype *value)
 {
 {
-  fputs (" (", file);
-  LOCATION_PRINT (file, *loc);
-  fputs (")", file);
+  fputc (' ', file);
   switch (type)
     {
   switch (type)
     {
-    case CHARACTER:
-      fprintf (file, " = '%s'", value->string);
-      break;
-
     case ID:
       fprintf (file, " = %s", value->symbol->tag);
       break;
     case ID:
       fprintf (file, " = %s", value->symbol->tag);
       break;
@@ -435,7 +469,7 @@ yyprint (FILE *file,
       break;
 
     case TYPE:
       break;
 
     case TYPE:
-      fprintf (file, " = <%s>", value->string);
+      fprintf (file, " = <%s>", value->struniq);
       break;
 
     case BRACED_CODE:
       break;
 
     case BRACED_CODE:
@@ -443,13 +477,15 @@ yyprint (FILE *file,
     case EPILOGUE:
       fprintf (file, " = {{ %s }}", value->string);
       break;
     case EPILOGUE:
       fprintf (file, " = {{ %s }}", value->string);
       break;
+
+    default:
+      fprintf (file, "unknown token type");
+      break;
     }
 }
 
 void
     }
 }
 
 void
-gram_error (gram_control_t *control ATTRIBUTE_UNUSED,
-           location_t *yylloc, const char *msg)
+gram_error (location_t *yylloc, const char *msg)
 {
 {
-  LOCATION_PRINT (stderr, *yylloc);
-  fprintf (stderr, ": %s\n", msg);
+  complain_at (*yylloc, "%s", msg);
 }
 }