]> git.saurik.com Git - bison.git/blobdiff - src/parse-gram.y
* tests/Makefile.am ($(srcdir)/package.m4): Bison now ships
[bison.git] / src / parse-gram.y
index ca344d1cb47e1cb009c7b3fc0636915689a143e4..6e9faa743d6da5d99a6a4e2dc76b59e525a4d365 100644 (file)
 
 %{
 #include "system.h"
 
 %{
 #include "system.h"
+#include "complain.h"
 #include "muscle_tab.h"
 #include "files.h"
 #include "getargs.h"
 #include "output.h"
 #include "muscle_tab.h"
 #include "files.h"
 #include "getargs.h"
 #include "output.h"
+#include "symlist.h"
 #include "gram.h"
 #include "reader.h"
 #include "conflicts.h"
 #include "gram.h"
 #include "reader.h"
 #include "conflicts.h"
@@ -62,25 +64,23 @@ 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 parse 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;
 char *current_type = 0;
 symbol_t *current_lhs;
 location_t current_lhs_location;
 
 symbol_class current_class = unknown_sym;
 char *current_type = 0;
 symbol_t *current_lhs;
 location_t current_lhs_location;
-associativity current_assoc;
+assoc_t current_assoc;
 int current_prec = 0;
 int current_prec = 0;
+braced_code_t current_braced_code = action_braced_code;
 %}
 
 
 %}
 
 
@@ -88,23 +88,35 @@ int current_prec = 0;
 %union
 {
   symbol_t *symbol;
 %union
 {
   symbol_t *symbol;
+  symbol_list_t *list;
   int integer;
   char *string;
   int integer;
   char *string;
-  associativity assoc;
+  assoc_t assoc;
 };
 
 };
 
-/* Define the tokens together with there human representation. */
+/* Define the tokens together with their human representation.  */
 %token GRAM_EOF 0 "end of string"
 %token STRING CHARACTER
 %token INT
 
 %token GRAM_EOF 0 "end of string"
 %token STRING CHARACTER
 %token INT
 
-%token PERCENT_TOKEN "%token"
-%token PERCENT_NTERM "%nterm"
-%token PERCENT_TYPE  "%type"
-%token PERCENT_UNION "%union"
+%token PERCENT_TOKEN       "%token"
+%token PERCENT_NTERM       "%nterm"
+
+%token PERCENT_TYPE        "%type"
+%token PERCENT_DESTRUCTOR  "%destructor"
+%token PERCENT_PRINTER     "%printer"
+
+%token PERCENT_UNION       "%union"
+
+%token PERCENT_LEFT        "%left"
+%token PERCENT_RIGHT       "%right"
+%token PERCENT_NONASSOC    "%nonassoc"
+
 %token PERCENT_EXPECT "%expect"
 %token PERCENT_START "%start"
 %token PERCENT_PREC     "%prec"
 %token PERCENT_EXPECT "%expect"
 %token PERCENT_START "%start"
 %token PERCENT_PREC     "%prec"
+%token PERCENT_DPREC    "%dprec"
+%token PERCENT_MERGE    "%merge"
 %token PERCENT_VERBOSE  "%verbose"
 %token PERCENT_ERROR_VERBOSE "%error-verbose"
 
 %token PERCENT_VERBOSE  "%verbose"
 %token PERCENT_ERROR_VERBOSE "%error-verbose"
 
@@ -114,6 +126,7 @@ int current_prec = 0;
 
 %token PERCENT_DEFINE "%define"
 %token PERCENT_PURE_PARSER "%pure-parser"
 
 %token PERCENT_DEFINE "%define"
 %token PERCENT_PURE_PARSER "%pure-parser"
+%token PERCENT_GLR_PARSER "%glr-parser"
 
 %token PERCENT_DEFINES "%defines"
 
 
 %token PERCENT_DEFINES "%defines"
 
@@ -140,7 +153,7 @@ int current_prec = 0;
 %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
-
+%type <list>  symbols.1
 %%
 
 input:
 %%
 
 input:
@@ -175,6 +188,7 @@ declaration:
 | "%no-lines"                              { no_lines_flag = 1; }
 | "%output" "=" string_content             { spec_outfile = $3; }
 | "%pure-parser"                           { pure_parser = 1; }
 | "%no-lines"                              { no_lines_flag = 1; }
 | "%output" "=" string_content             { spec_outfile = $3; }
 | "%pure-parser"                           { pure_parser = 1; }
+| "%glr-parser"                           { glr_parser = 1; }
 | "%skeleton" string_content               { skeleton = $2; }
 | "%token-table"                           { token_table_flag = 1; }
 | "%verbose"                               { report_flag = 1; }
 | "%skeleton" string_content               { skeleton = $2; }
 | "%token-table"                           { token_table_flag = 1; }
 | "%verbose"                               { report_flag = 1; }
@@ -194,6 +208,26 @@ grammar_declaration:
       MUSCLE_INSERT_INT ("stype_line", @2.first_line);
       muscle_insert ("stype", $2);
     }
       MUSCLE_INSERT_INT ("stype_line", @2.first_line);
       muscle_insert ("stype", $2);
     }
+| "%destructor"
+    { current_braced_code = destructor_braced_code; }
+  BRACED_CODE symbols.1
+    {
+      symbol_list_t *list;
+      for (list = $4; list; list = list->next)
+       symbol_destructor_set (list->sym, $3, @3);
+      symbol_list_free ($4);
+      current_braced_code = action_braced_code;
+    }
+| "%printer"
+    { current_braced_code = printer_braced_code; }
+  BRACED_CODE symbols.1
+    {
+      symbol_list_t *list;
+      for (list = $4; list; list = list->next)
+       symbol_printer_set (list->sym, $3, list->location);
+      symbol_list_free ($4);
+      current_braced_code = action_braced_code;
+    }
 ;
 
 symbol_declaration:
 ;
 
 symbol_declaration:
@@ -207,22 +241,30 @@ symbol_declaration:
       current_class = unknown_sym;
       current_type = NULL;
     }
       current_class = unknown_sym;
       current_type = NULL;
     }
-| "%type" TYPE {current_type = $2; } nterms_to_type.1
+| "%type" TYPE symbols.1
     {
     {
-      current_type = NULL;
+      symbol_list_t *list;
+      for (list = $3; list; list = list->next)
+       symbol_type_set (list->sym, $2, @2);
+      symbol_list_free ($3);
     }
 ;
 
 precedence_declaration:
     }
 ;
 
 precedence_declaration:
-  precedence_declarator type.opt
-    { current_assoc = $1; ++current_prec; }
-  terms_to_prec.1
-    { current_assoc = non_assoc; current_type = NULL; }
+  precedence_declarator type.opt symbols.1
+    {
+      symbol_list_t *list;
+      ++current_prec;
+      for (list = $3; list; list = list->next)
+       {
+         symbol_type_set (list->sym, current_type, @2);
+         symbol_precedence_set (list->sym, current_prec, $1, @1);
+       }
+      symbol_list_free ($3);
+      current_type = NULL;
+    }
 ;
 
 ;
 
-%token PERCENT_LEFT     "%left";
-%token PERCENT_RIGHT    "%right";
-%token PERCENT_NONASSOC "%nonassoc";
 precedence_declarator:
   "%left"     { $$ = left_assoc; }
 | "%right"    { $$ = right_assoc; }
 precedence_declarator:
   "%left"     { $$ = left_assoc; }
 | "%right"    { $$ = right_assoc; }
@@ -235,23 +277,10 @@ type.opt:
 ;
 
 /* One or more nonterminals to be %typed. */
 ;
 
 /* One or more nonterminals to be %typed. */
-nterms_to_type.1:
-  ID                   { symbol_type_set ($1, current_type); }
-| nterms_to_type.1 ID  { symbol_type_set ($2, current_type); }
-;
 
 
-/* One or more symbols to be given a precedence/associativity.  */
-terms_to_prec.1:
-  symbol
-    {
-      symbol_type_set ($1, current_type);
-      symbol_precedence_set ($1, current_prec, current_assoc);
-    }
-| terms_to_prec.1 symbol
-    {
-      symbol_type_set ($2, current_type);
-      symbol_precedence_set ($2, current_prec, current_assoc);
-    }
+symbols.1:
+  symbol            { $$ = symbol_list_new ($1, @1); }
+| symbols.1 symbol  { $$ = symbol_list_prepend ($1, $2, @2); }
 ;
 
 /* One token definition.  */
 ;
 
 /* One token definition.  */
@@ -262,27 +291,27 @@ symbol_def:
      }
 | ID
      {
      }
 | ID
      {
-       symbol_class_set ($1, current_class);
-       symbol_type_set ($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, 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, 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, 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, @$);
     }
 ;
 
     }
 ;
 
@@ -310,6 +339,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:
@@ -330,13 +367,17 @@ 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); }
+| CHARACTER       { $$ = symbol_get ($1, @1); }
 ;
 
 action:
 ;
 
 action:
@@ -348,8 +389,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);
     }
 ;
 
     }
 ;
 
@@ -384,11 +425,9 @@ 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)
     {
     case CHARACTER:
   switch (type)
     {
     case CHARACTER:
@@ -420,9 +459,7 @@ yyprint (FILE *file,
 }
 
 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);
 }
 }