* data/m4sugar/m4sugar.m4 (m4_map): Recognize when the list of
authorAkim Demaille <akim@epita.fr>
Mon, 17 Jun 2002 08:43:12 +0000 (08:43 +0000)
committerAkim Demaille <akim@epita.fr>
Mon, 17 Jun 2002 08:43:12 +0000 (08:43 +0000)
arguments is really empty, not only equal to `[]'.
* src/symtab.h, src/symtab.c (symbol_t): `destructor' is a new
member.
(symbol_destructor_set): New.
* src/output.c (symbol_destructors_output): New.
* src/reader.h (brace_code_t, current_braced_code): New.
* src/scan-gram.l (BRACED_CODE): Use it to branch on...
(handle_dollar): Rename as...
(handle_action_dollar): this.
(handle_destructor_dollar): New.
* src/parse-gram.y (PERCENT_DESTRUCTOR): New.
(grammar_declaration): Use it.
* data/bison.simple (yystos): Is always defined.
(yydestructor): New.
* tests/actions.at (Destructors): New.
* tests/calc.at (_AT_CHECK_CALC_ERROR): Don't rely on egrep.

15 files changed:
ChangeLog
data/bison.simple
data/m4sugar/m4sugar.m4
src/output.c
src/parse-gram.c
src/parse-gram.h
src/parse-gram.y
src/reader.h
src/scan-gram.c
src/scan-gram.l
src/symlist.c
src/symtab.c
src/symtab.h
tests/actions.at
tests/calc.at

index 3d181d2..e83fe2a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
 2002-06-17  Akim Demaille  <akim@epita.fr>
 
+       * data/m4sugar/m4sugar.m4 (m4_map): Recognize when the list of
+       arguments is really empty, not only equal to `[]'.
+       * src/symtab.h, src/symtab.c (symbol_t): `destructor' is a new
+       member.
+       (symbol_destructor_set): New.
+       * src/output.c (symbol_destructors_output): New.
+       * src/reader.h (brace_code_t, current_braced_code): New.
+       * src/scan-gram.l (BRACED_CODE): Use it to branch on...
+       (handle_dollar): Rename as...
+       (handle_action_dollar): this.
+       (handle_destructor_dollar): New.
+       * src/parse-gram.y (PERCENT_DESTRUCTOR): New.
+       (grammar_declaration): Use it.
+       * data/bison.simple (yystos): Is always defined.
+       (yydestructor): New.
+       * tests/actions.at (Destructors): New.
+       * tests/calc.at (_AT_CHECK_CALC_ERROR): Don't rely on egrep.
+
+2002-06-17  Akim Demaille  <akim@epita.fr>
+
        * src/symlist.h, src/symlist.c (symbol_list_length): New.
        * src/scan-gram.l (handle_dollar, handle_at): Compute the
        rule_length only when needed.
@@ -9,7 +29,6 @@
        symbol_tag_get.
        * src/parse-gram.y: Use symbol_list_free.
 
-       
 2002-06-17  Akim Demaille  <akim@epita.fr>
 
        * src/reader.h, src/reader.c (symbol_list, symbol_list_new)
@@ -21,7 +40,6 @@
        * src/scan-gram.l (handle_dollar): Takes a location.
        * tests/input.at (Invalid $n): Adjust.
 
-       
 2002-06-17  Akim Demaille  <akim@epita.fr>
 
        * src/reader.h, src/reader.c (symbol_list_new): Export it.
index 2996235..80314c0 100644 (file)
@@ -68,6 +68,10 @@ m4_define_default([b4_header_guard],
                                 [[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]], [_])])
 
 
+## ------------------------- ##
+## Assigning token numbers.  ##
+## ------------------------- ##
+
 # b4_token_define(TOKEN-NAME, TOKEN-NUMBER)
 # -----------------------------------------
 # Output the definition of this token as #define.
@@ -432,14 +436,12 @@ static const short yycheck[[]] =
   b4_check
 };
 
-#if YYDEBUG
 /* YYSTOS[[STATE-NUM]] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const b4_uint_type(b4_stos_max) yystos[[]] =
 {
   b4_stos
 };
-#endif
 
 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
 # define YYSIZE_T __SIZE_TYPE__
@@ -649,6 +651,7 @@ int yyparse (void *);
 int yyparse (void);
 # endif
 #endif
+static void yydestructor (int symbol_type, YYSTYPE symbol_value);
 
 /* YY_DECL_VARIABLES -- depending whether we use a pure parser,
    variables are global, or local to YYPARSE.  */
@@ -1123,6 +1126,7 @@ yyerrlab1:
        YYABORT;
       YYDPRINTF ((stderr, "Discarding token %d (%s).\n",
                  yychar, yytname[yychar1]));
+      yydestructor (yychar1, yylval);
       yychar = YYEMPTY;
     }
 
@@ -1169,6 +1173,7 @@ yyerrlab1:
        }
 #endif
 
+      yydestructor (yystos[yystate], *yyvsp);
       yyvsp--;
       yystate = *--yyssp;
 #if YYLSP_NEEDED
@@ -1231,6 +1236,39 @@ yyreturn:
   return yyresult;
 ]}
 
+/* Release the memory associated to SYMBOL-NUMBER. */
+m4_divert_push([KILL])# M4 code.
+# b4_eval
+# -------
+# FIXME: This is really wrong, we no longer guarantee we don't evaluate
+# the user's input.  This demonstrates that decoding actions (BRACED_CODE)
+# ought to be done when output, not when read.
+m4_define([b4_eval],
+[$*])
+
+# b4_symbol_destructor(SYMBOL-NUMBER, DESTRUCTOR, TYPE-NAME)
+# ----------------------------------------------------------
+m4_define([b4_symbol_destructor],
+[m4_pushdef([b4_dollar_dollar], [symbol_value.$3])dnl
+      case $1:
+        b4_eval($2);
+        break;
+m4_popdef([b4_dollar_dollar])])
+
+m4_divert_pop([KILL])dnl# End of M4 code.
+static void
+yydestructor (int symbol_type, YYSTYPE symbol_value)
+{
+  switch (symbol_type)
+    {
+m4_map([b4_symbol_destructor], m4_defn([b4_symbol_destructors]))dnl
+      default:
+        YYDPRINTF ((stderr, "yydestructor: unknown symbol type: %s\n",
+                   yytname[[symbol_type]]));
+        break;
+    }
+}
+
 b4_epilogue
 m4_if(b4_defines_flag, 0, [],
 [#output "b4_output_header_name"
index c2d3f7a..e2eced2 100644 (file)
@@ -432,7 +432,8 @@ m4_define([m4_bmatch],
 # of LIST (which can be lists themselves, for multiple arguments MACROs).
 m4_define([m4_fst], [$1])
 m4_define([m4_map],
-[m4_if([$2], [[]], [],
+[m4_if([$2], [], [],
+       [$2], [[]], [],
        [$1(m4_fst($2))[]dnl
 m4_map([$1], m4_cdr($2))])])
 
index 237e48a..78113fd 100644 (file)
@@ -606,6 +606,33 @@ token_definitions_output (FILE *out)
 }
 
 
+/*----------------------------------------.
+| Output the symbol destructors to OOUT.  |
+`----------------------------------------*/
+
+static void
+symbol_destructors_output (FILE *out)
+{
+  int i;
+  int first = 1;
+
+  fputs ("m4_define([b4_symbol_destructors], \n[", out);
+  for (i = 0; i < nsyms; ++i)
+    if (symbols[i]->destructor)
+      {
+       symbol_t *symbol = symbols[i];
+
+       /* Symbol-number, destructor. */
+       fprintf (out, "%s[[[%d]], [[%s]], [[%s]]]",
+                first ? "" : ",\n",
+                symbol->number, symbol->destructor, symbol->type_name);
+
+       first = 0;
+      }
+  fputs ("])\n\n", out);
+}
+
+
 static void
 save_column (int symbol, int default_state)
 {
@@ -1019,6 +1046,7 @@ output_skeleton (void)
 
   actions_output (out);
   token_definitions_output (out);
+  symbol_destructors_output (out);
 
   muscles_m4_output (out);
 
index 001187a..d2f1e84 100644 (file)
@@ -116,6 +116,7 @@ symbol_t *current_lhs;
 location_t current_lhs_location;
 associativity current_assoc;
 int current_prec = 0;
+braced_code_t current_braced_code = action_braced_code;
 
 
 /* Tokens.  */
@@ -131,37 +132,38 @@ int current_prec = 0;
      PERCENT_TOKEN = 261,
      PERCENT_NTERM = 262,
      PERCENT_TYPE = 263,
-     PERCENT_UNION = 264,
-     PERCENT_LEFT = 265,
-     PERCENT_RIGHT = 266,
-     PERCENT_NONASSOC = 267,
-     PERCENT_EXPECT = 268,
-     PERCENT_START = 269,
-     PERCENT_PREC = 270,
-     PERCENT_VERBOSE = 271,
-     PERCENT_ERROR_VERBOSE = 272,
-     PERCENT_OUTPUT = 273,
-     PERCENT_FILE_PREFIX = 274,
-     PERCENT_NAME_PREFIX = 275,
-     PERCENT_DEFINE = 276,
-     PERCENT_PURE_PARSER = 277,
-     PERCENT_DEFINES = 278,
-     PERCENT_YACC = 279,
-     PERCENT_DEBUG = 280,
-     PERCENT_LOCATIONS = 281,
-     PERCENT_NO_LINES = 282,
-     PERCENT_SKELETON = 283,
-     PERCENT_TOKEN_TABLE = 284,
-     TYPE = 285,
-     EQUAL = 286,
-     SEMICOLON = 287,
-     COLON = 288,
-     PIPE = 289,
-     ID = 290,
-     PERCENT_PERCENT = 291,
-     PROLOGUE = 292,
-     EPILOGUE = 293,
-     BRACED_CODE = 294
+     PERCENT_DESTRUCTOR = 264,
+     PERCENT_UNION = 265,
+     PERCENT_LEFT = 266,
+     PERCENT_RIGHT = 267,
+     PERCENT_NONASSOC = 268,
+     PERCENT_EXPECT = 269,
+     PERCENT_START = 270,
+     PERCENT_PREC = 271,
+     PERCENT_VERBOSE = 272,
+     PERCENT_ERROR_VERBOSE = 273,
+     PERCENT_OUTPUT = 274,
+     PERCENT_FILE_PREFIX = 275,
+     PERCENT_NAME_PREFIX = 276,
+     PERCENT_DEFINE = 277,
+     PERCENT_PURE_PARSER = 278,
+     PERCENT_DEFINES = 279,
+     PERCENT_YACC = 280,
+     PERCENT_DEBUG = 281,
+     PERCENT_LOCATIONS = 282,
+     PERCENT_NO_LINES = 283,
+     PERCENT_SKELETON = 284,
+     PERCENT_TOKEN_TABLE = 285,
+     TYPE = 286,
+     EQUAL = 287,
+     SEMICOLON = 288,
+     COLON = 289,
+     PIPE = 290,
+     ID = 291,
+     PERCENT_PERCENT = 292,
+     PROLOGUE = 293,
+     EPILOGUE = 294,
+     BRACED_CODE = 295
    };
 # endif
   /* POSIX requires `int' for tokens in interfaces.  */
@@ -174,37 +176,38 @@ int current_prec = 0;
 #define PERCENT_TOKEN 261
 #define PERCENT_NTERM 262
 #define PERCENT_TYPE 263
-#define PERCENT_UNION 264
-#define PERCENT_LEFT 265
-#define PERCENT_RIGHT 266
-#define PERCENT_NONASSOC 267
-#define PERCENT_EXPECT 268
-#define PERCENT_START 269
-#define PERCENT_PREC 270
-#define PERCENT_VERBOSE 271
-#define PERCENT_ERROR_VERBOSE 272
-#define PERCENT_OUTPUT 273
-#define PERCENT_FILE_PREFIX 274
-#define PERCENT_NAME_PREFIX 275
-#define PERCENT_DEFINE 276
-#define PERCENT_PURE_PARSER 277
-#define PERCENT_DEFINES 278
-#define PERCENT_YACC 279
-#define PERCENT_DEBUG 280
-#define PERCENT_LOCATIONS 281
-#define PERCENT_NO_LINES 282
-#define PERCENT_SKELETON 283
-#define PERCENT_TOKEN_TABLE 284
-#define TYPE 285
-#define EQUAL 286
-#define SEMICOLON 287
-#define COLON 288
-#define PIPE 289
-#define ID 290
-#define PERCENT_PERCENT 291
-#define PROLOGUE 292
-#define EPILOGUE 293
-#define BRACED_CODE 294
+#define PERCENT_DESTRUCTOR 264
+#define PERCENT_UNION 265
+#define PERCENT_LEFT 266
+#define PERCENT_RIGHT 267
+#define PERCENT_NONASSOC 268
+#define PERCENT_EXPECT 269
+#define PERCENT_START 270
+#define PERCENT_PREC 271
+#define PERCENT_VERBOSE 272
+#define PERCENT_ERROR_VERBOSE 273
+#define PERCENT_OUTPUT 274
+#define PERCENT_FILE_PREFIX 275
+#define PERCENT_NAME_PREFIX 276
+#define PERCENT_DEFINE 277
+#define PERCENT_PURE_PARSER 278
+#define PERCENT_DEFINES 279
+#define PERCENT_YACC 280
+#define PERCENT_DEBUG 281
+#define PERCENT_LOCATIONS 282
+#define PERCENT_NO_LINES 283
+#define PERCENT_SKELETON 284
+#define PERCENT_TOKEN_TABLE 285
+#define TYPE 286
+#define EQUAL 287
+#define SEMICOLON 288
+#define COLON 289
+#define PIPE 290
+#define ID 291
+#define PERCENT_PERCENT 292
+#define PROLOGUE 293
+#define EPILOGUE 294
+#define BRACED_CODE 295
 
 
 
@@ -223,7 +226,7 @@ int current_prec = 0;
 #endif
 
 #ifndef YYSTYPE
-#line 90 "parse-gram.y"
+#line 91 "parse-gram.y"
 typedef union {
   symbol_t *symbol;
   symbol_list_t *list;
@@ -232,7 +235,7 @@ typedef union {
   associativity assoc;
 } yystype;
 /* Line 199 of /usr/local/share/bison/bison.simple.  */
-#line 236 "parse-gram.c"
+#line 239 "parse-gram.c"
 # define YYSTYPE yystype
 # define YYSTYPE_IS_TRIVIAL 1
 #endif
@@ -253,7 +256,7 @@ typedef struct yyltype
 
 
 /* Line 219 of /usr/local/share/bison/bison.simple.  */
-#line 257 "parse-gram.c"
+#line 260 "parse-gram.c"
 
 #if ! defined (yyoverflow) || YYERROR_VERBOSE
 
@@ -355,20 +358,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state. */
 #define YYFINAL  3
 #define YYFLAG  -32768
-#define YYLAST   111
+#define YYLAST   115
 
 /* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS  40
+#define YYNTOKENS  41
 /* YYNNTS -- Number of nonterminals. */
-#define YYNNTS  26
+#define YYNNTS  27
 /* YYNRULES -- Number of rules. */
-#define YYNRULES  67
+#define YYNRULES  69
 /* YYNRULES -- Number of states. */
-#define YYNSTATES  93
+#define YYNSTATES  97
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   294
+#define YYMAXUTOK   295
 
 #define YYTRANSLATE(X) \
   ((unsigned)(X) <= YYMAXUTOK ? yytranslate[X] : YYUNDEFTOK)
@@ -405,7 +408,7 @@ static const unsigned char yytranslate[] =
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
       25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
-      35,    36,    37,    38,    39
+      35,    36,    37,    38,    39,    40
 };
 
 #if YYDEBUG
@@ -415,46 +418,46 @@ static const unsigned char yyprhs[] =
 {
        0,     0,     3,     8,     9,    13,    15,    17,    19,    23,
       25,    27,    30,    34,    36,    40,    42,    46,    48,    51,
-      53,    55,    57,    59,    61,    64,    67,    68,    72,    73,
-      77,    81,    85,    87,    89,    91,    92,    94,    96,    99,
-     101,   103,   106,   109,   113,   115,   118,   120,   123,   125,
-     128,   129,   135,   137,   141,   142,   145,   148,   152,   154,
-     156,   158,   160,   162,   164,   165,   168,   169
+      53,    55,    57,    59,    61,    64,    67,    68,    73,    74,
+      78,    79,    83,    87,    91,    93,    95,    97,    98,   100,
+     102,   105,   107,   109,   112,   115,   119,   121,   124,   126,
+     129,   131,   134,   135,   141,   143,   147,   148,   151,   154,
+     158,   160,   162,   164,   166,   168,   170,   171,   174,   175
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
 static const signed char yyrhs[] =
 {
-      41,     0,    -1,    42,    36,    54,    64,    -1,    -1,    42,
-      43,    65,    -1,    44,    -1,    37,    -1,    25,    -1,    21,
-      63,    63,    -1,    23,    -1,    17,    -1,    13,     5,    -1,
-      19,    31,    63,    -1,    26,    -1,    20,    31,    63,    -1,
-      27,    -1,    18,    31,    63,    -1,    22,    -1,    28,    63,
-      -1,    29,    -1,    16,    -1,    24,    -1,    48,    -1,    45,
-      -1,    14,    60,    -1,     9,    39,    -1,    -1,     7,    46,
-      53,    -1,    -1,     6,    47,    53,    -1,     8,    30,    51,
-      -1,    49,    50,    51,    -1,    10,    -1,    11,    -1,    12,
-      -1,    -1,    30,    -1,    60,    -1,    51,    60,    -1,    30,
-      -1,    35,    -1,    35,     5,    -1,    35,    62,    -1,    35,
-       5,    62,    -1,    52,    -1,    53,    52,    -1,    55,    -1,
-      54,    55,    -1,    56,    -1,    44,    32,    -1,    -1,    35,
-      33,    57,    58,    32,    -1,    59,    -1,    58,    34,    59,
-      -1,    -1,    59,    60,    -1,    59,    61,    -1,    59,    15,
-      60,    -1,    35,    -1,    62,    -1,     4,    -1,    39,    -1,
-       3,    -1,     3,    -1,    -1,    36,    38,    -1,    -1,    32,
-      -1
+      42,     0,    -1,    43,    37,    56,    66,    -1,    -1,    43,
+      44,    67,    -1,    45,    -1,    38,    -1,    26,    -1,    22,
+      65,    65,    -1,    24,    -1,    18,    -1,    14,     5,    -1,
+      20,    32,    65,    -1,    27,    -1,    21,    32,    65,    -1,
+      28,    -1,    19,    32,    65,    -1,    23,    -1,    29,    65,
+      -1,    30,    -1,    17,    -1,    25,    -1,    50,    -1,    47,
+      -1,    15,    62,    -1,    10,    40,    -1,    -1,     9,    46,
+      40,    53,    -1,    -1,     7,    48,    55,    -1,    -1,     6,
+      49,    55,    -1,     8,    31,    53,    -1,    51,    52,    53,
+      -1,    11,    -1,    12,    -1,    13,    -1,    -1,    31,    -1,
+      62,    -1,    53,    62,    -1,    31,    -1,    36,    -1,    36,
+       5,    -1,    36,    64,    -1,    36,     5,    64,    -1,    54,
+      -1,    55,    54,    -1,    57,    -1,    56,    57,    -1,    58,
+      -1,    45,    33,    -1,    -1,    36,    34,    59,    60,    33,
+      -1,    61,    -1,    60,    35,    61,    -1,    -1,    61,    62,
+      -1,    61,    63,    -1,    61,    16,    62,    -1,    36,    -1,
+      64,    -1,     4,    -1,    40,    -1,     3,    -1,     3,    -1,
+      -1,    37,    39,    -1,    -1,    33,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const unsigned short yyrline[] =
 {
-       0,   152,   152,   165,   167,   170,   172,   173,   174,   175,
-     176,   177,   178,   179,   180,   181,   182,   183,   184,   185,
-     186,   187,   190,   192,   193,   197,   205,   205,   211,   211,
-     216,   225,   240,   242,   243,   246,   248,   253,   255,   259,
-     264,   269,   275,   281,   291,   294,   303,   305,   311,   313,
-     316,   316,   321,   323,   326,   329,   331,   333,   337,   339,
-     340,   343,   349,   358,   366,   371,   377,   379
+       0,   154,   154,   167,   169,   172,   174,   175,   176,   177,
+     178,   179,   180,   181,   182,   183,   184,   185,   186,   187,
+     188,   189,   192,   194,   195,   199,   205,   205,   217,   217,
+     223,   223,   228,   237,   252,   254,   255,   258,   260,   265,
+     267,   271,   276,   281,   287,   293,   303,   306,   315,   317,
+     323,   325,   328,   328,   333,   335,   338,   341,   343,   345,
+     349,   351,   352,   355,   361,   370,   378,   383,   389,   391
 };
 #endif
 
@@ -464,20 +467,20 @@ static const unsigned short yyrline[] =
 static const char *const yytname[] =
 {
   "\"end of string\"", "error", "$undefined.", "STRING", "CHARACTER", "INT", 
-  "\"%token\"", "\"%nterm\"", "\"%type\"", "\"%union\"", "\"%left\"", 
-  "\"%right\"", "\"%nonassoc\"", "\"%expect\"", "\"%start\"", "\"%prec\"", 
-  "\"%verbose\"", "\"%error-verbose\"", "\"%output\"", "\"%file-prefix\"", 
-  "\"%name-prefix\"", "\"%define\"", "\"%pure-parser\"", "\"%defines\"", 
-  "\"%yacc\"", "\"%debug\"", "\"%locations\"", "\"%no-lines\"", 
-  "\"%skeleton\"", "\"%token-table\"", "TYPE", "\"=\"", "\";\"", "\":\"", 
-  "\"|\"", "\"identifier\"", "\"%%\"", "PROLOGUE", "EPILOGUE", 
-  "BRACED_CODE", "$axiom", "input", "declarations", "declaration", 
-  "grammar_declaration", "symbol_declaration", "@1", "@2", 
-  "precedence_declaration", "precedence_declarator", "type.opt", 
-  "symbols.1", "symbol_def", "symbol_defs.1", "grammar", 
-  "rules_or_grammar_declaration", "rules", "@3", "rhses.1", "rhs", 
-  "symbol", "action", "string_as_id", "string_content", "epilogue.opt", 
-  "semi_colon.opt", 0
+  "\"%token\"", "\"%nterm\"", "\"%type\"", "\"%destructor\"", 
+  "\"%union\"", "\"%left\"", "\"%right\"", "\"%nonassoc\"", "\"%expect\"", 
+  "\"%start\"", "\"%prec\"", "\"%verbose\"", "\"%error-verbose\"", 
+  "\"%output\"", "\"%file-prefix\"", "\"%name-prefix\"", "\"%define\"", 
+  "\"%pure-parser\"", "\"%defines\"", "\"%yacc\"", "\"%debug\"", 
+  "\"%locations\"", "\"%no-lines\"", "\"%skeleton\"", "\"%token-table\"", 
+  "TYPE", "\"=\"", "\";\"", "\":\"", "\"|\"", "\"identifier\"", "\"%%\"", 
+  "PROLOGUE", "EPILOGUE", "BRACED_CODE", "$axiom", "input", 
+  "declarations", "declaration", "grammar_declaration", "@1", 
+  "symbol_declaration", "@2", "@3", "precedence_declaration", 
+  "precedence_declarator", "type.opt", "symbols.1", "symbol_def", 
+  "symbol_defs.1", "grammar", "rules_or_grammar_declaration", "rules", 
+  "@4", "rhses.1", "rhs", "symbol", "action", "string_as_id", 
+  "string_content", "epilogue.opt", "semi_colon.opt", 0
 };
 #endif
 
@@ -489,19 +492,19 @@ static const short yytoknum[] =
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
      275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
      285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
-      -1
+     295,    -1
 };
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const unsigned char yyr1[] =
 {
-       0,    40,    41,    42,    42,    43,    43,    43,    43,    43,
-      43,    43,    43,    43,    43,    43,    43,    43,    43,    43,
-      43,    43,    44,    44,    44,    44,    46,    45,    47,    45,
-      45,    48,    49,    49,    49,    50,    50,    51,    51,    52,
-      52,    52,    52,    52,    53,    53,    54,    54,    55,    55,
-      57,    56,    58,    58,    59,    59,    59,    59,    60,    60,
-      60,    61,    62,    63,    64,    64,    65,    65
+       0,    41,    42,    43,    43,    44,    44,    44,    44,    44,
+      44,    44,    44,    44,    44,    44,    44,    44,    44,    44,
+      44,    44,    45,    45,    45,    45,    46,    45,    48,    47,
+      49,    47,    47,    50,    51,    51,    51,    52,    52,    53,
+      53,    54,    54,    54,    54,    54,    55,    55,    56,    56,
+      57,    57,    59,    58,    60,    60,    61,    61,    61,    61,
+      62,    62,    62,    63,    64,    65,    66,    66,    67,    67
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -509,11 +512,11 @@ static const unsigned char yyr2[] =
 {
        0,     2,     4,     0,     3,     1,     1,     1,     3,     1,
        1,     2,     3,     1,     3,     1,     3,     1,     2,     1,
-       1,     1,     1,     1,     2,     2,     0,     3,     0,     3,
-       3,     3,     1,     1,     1,     0,     1,     1,     2,     1,
-       1,     2,     2,     3,     1,     2,     1,     2,     1,     2,
-       0,     5,     1,     3,     0,     2,     2,     3,     1,     1,
-       1,     1,     1,     1,     0,     2,     0,     1
+       1,     1,     1,     1,     2,     2,     0,     4,     0,     3,
+       0,     3,     3,     3,     1,     1,     1,     0,     1,     1,
+       2,     1,     1,     2,     2,     3,     1,     2,     1,     2,
+       1,     2,     0,     5,     1,     3,     0,     2,     2,     3,
+       1,     1,     1,     1,     1,     1,     0,     2,     0,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -521,48 +524,48 @@ static const unsigned char yyr2[] =
    means the default is an error.  */
 static const short yydefact[] =
 {
-       3,     0,     0,     0,    28,    26,     0,     0,    32,    33,
-      34,     0,     0,    20,    10,     0,     0,     0,     0,    17,
-       9,    21,     7,    13,    15,     0,    19,     0,     6,    66,
-       5,    23,    22,    35,     0,     0,     0,    25,    11,    62,
-      60,    58,    24,    59,     0,     0,     0,    63,     0,    18,
-       0,     0,    64,    46,    48,    67,     4,    36,     0,    39,
-      40,    44,    29,    27,    30,    37,    16,    12,    14,     8,
-      50,    49,     0,    47,     2,    31,    41,    42,    45,    38,
-      54,    65,    43,     0,    52,    51,    54,     0,    61,    55,
-      56,    53,    57
+       3,     0,     0,     0,    30,    28,     0,    26,     0,    34,
+      35,    36,     0,     0,    20,    10,     0,     0,     0,     0,
+      17,     9,    21,     7,    13,    15,     0,    19,     0,     6,
+      68,     5,    23,    22,    37,     0,     0,     0,     0,    25,
+      11,    64,    62,    60,    24,    61,     0,     0,     0,    65,
+       0,    18,     0,     0,    66,    48,    50,    69,     4,    38,
+       0,    41,    42,    46,    31,    29,    32,    39,     0,    16,
+      12,    14,     8,    52,    51,     0,    49,     2,    33,    43,
+      44,    47,    40,    27,    56,    67,    45,     0,    54,    53,
+      56,     0,    63,    57,    58,    55,    59
 };
 
 /* YYPGOTO[NTERM-NUM]. */
 static const short yydefgoto[] =
 {
-      -1,     1,     2,    29,    51,    31,    35,    34,    32,    33,
-      58,    64,    61,    62,    52,    53,    54,    80,    83,    84,
-      65,    90,    43,    48,    74,    56
+      -1,     1,     2,    30,    53,    38,    32,    36,    35,    33,
+      34,    60,    66,    63,    64,    54,    55,    56,    84,    87,
+      88,    67,    94,    45,    50,    77,    58
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
 static const short yypact[] =
 {
-  -32768,    23,    74,-32768,-32768,-32768,     1,   -31,-32768,-32768,
-  -32768,    29,     0,-32768,-32768,     7,    10,    14,    39,-32768,
-  -32768,-32768,-32768,-32768,-32768,    39,-32768,    18,-32768,    15,
-  -32768,-32768,-32768,    16,   -24,   -24,     0,-32768,-32768,-32768,
-  -32768,-32768,-32768,-32768,    39,    39,    39,-32768,    39,-32768,
-      17,    19,     8,-32768,-32768,-32768,-32768,-32768,     0,-32768,
-       4,-32768,   -24,   -24,     0,-32768,-32768,-32768,-32768,-32768,
-  -32768,-32768,    20,-32768,-32768,     0,    45,-32768,-32768,-32768,
-  -32768,-32768,-32768,   -22,    -2,-32768,-32768,     0,-32768,-32768,
-  -32768,    -2,-32768
+  -32768,    25,    77,-32768,-32768,-32768,   -20,-32768,   -31,-32768,
+  -32768,-32768,    35,     0,-32768,-32768,    12,    15,    16,    46,
+  -32768,-32768,-32768,-32768,-32768,-32768,    46,-32768,    20,-32768,
+      17,-32768,-32768,-32768,    21,   -24,   -24,     0,    14,-32768,
+  -32768,-32768,-32768,-32768,-32768,-32768,    46,    46,    46,-32768,
+      46,-32768,    26,    18,     9,-32768,-32768,-32768,-32768,-32768,
+       0,-32768,     5,-32768,   -24,   -24,     0,-32768,     0,-32768,
+  -32768,-32768,-32768,-32768,-32768,    23,-32768,-32768,     0,    52,
+  -32768,-32768,-32768,     0,-32768,-32768,-32768,     6,    -2,-32768,
+  -32768,     0,-32768,-32768,-32768,    -2,-32768
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const short yypgoto[] =
 {
-  -32768,-32768,-32768,-32768,    47,-32768,-32768,-32768,-32768,-32768,
-  -32768,    -4,   -23,    25,-32768,     9,-32768,-32768,-32768,   -21,
-     -12,-32768,   -55,    11,-32768,-32768
+  -32768,-32768,-32768,-32768,    61,-32768,-32768,-32768,-32768,-32768,
+  -32768,-32768,   -55,   -22,    28,-32768,    13,-32768,-32768,-32768,
+     -21,   -13,-32768,   -56,    11,-32768,-32768
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
@@ -570,34 +573,34 @@ static const short yypgoto[] =
    number is the opposite.  If zero, do what YYDEFACT says.  */
 static const short yytable[] =
 {
-      42,    39,    40,    39,    40,    77,    59,    39,    37,    76,
-      85,    60,    86,    87,     4,     5,     6,     7,     8,     9,
-      10,    82,    12,     3,     4,     5,     6,     7,     8,     9,
-      10,    36,    12,    41,    38,    41,    49,    88,    44,    78,
-      78,    45,    47,    50,    72,    46,    57,    55,    39,    30,
-      70,    71,    79,    50,    75,    66,    67,    68,    81,    69,
-      63,    73,     0,    79,     0,    91,     0,     0,     0,     0,
-       0,     0,    89,     0,     0,    92,     0,     0,     0,    89,
-       4,     5,     6,     7,     8,     9,    10,    11,    12,     0,
-      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,
-      23,    24,    25,    26,     0,     0,     0,     0,     0,     0,
-      27,    28
+      44,    41,    42,    41,    42,    78,    80,    61,    41,    39,
+      79,    37,    62,    83,    91,     4,     5,     6,     7,     8,
+       9,    10,    11,    86,    13,     3,     4,     5,     6,     7,
+       8,     9,    10,    11,    43,    13,    43,    51,    92,    89,
+      40,    90,    81,    81,    46,    52,    75,    47,    48,    49,
+      57,    74,    59,    82,    68,    41,    52,    69,    70,    71,
+      73,    72,    85,    31,    65,    82,     0,    76,     0,    95,
+      82,     0,     0,     0,     0,    93,     0,     0,    96,     0,
+       0,     0,    93,     4,     5,     6,     7,     8,     9,    10,
+      11,    12,    13,     0,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,    23,    24,    25,    26,    27,     0,     0,
+       0,     0,     0,     0,    28,    29
 };
 
 static const short yycheck[] =
 {
-      12,     3,     4,     3,     4,    60,    30,     3,    39,     5,
-      32,    35,    34,    15,     6,     7,     8,     9,    10,    11,
-      12,    76,    14,     0,     6,     7,     8,     9,    10,    11,
-      12,    30,    14,    35,     5,    35,    25,    39,    31,    62,
-      63,    31,     3,    35,    36,    31,    30,    32,     3,     2,
-      33,    32,    64,    35,    58,    44,    45,    46,    38,    48,
-      35,    52,    -1,    75,    -1,    86,    -1,    -1,    -1,    -1,
-      -1,    -1,    84,    -1,    -1,    87,    -1,    -1,    -1,    91,
-       6,     7,     8,     9,    10,    11,    12,    13,    14,    -1,
-      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
-      26,    27,    28,    29,    -1,    -1,    -1,    -1,    -1,    -1,
-      36,    37
+      13,     3,     4,     3,     4,    60,    62,    31,     3,    40,
+       5,    31,    36,    68,    16,     6,     7,     8,     9,    10,
+      11,    12,    13,    79,    15,     0,     6,     7,     8,     9,
+      10,    11,    12,    13,    36,    15,    36,    26,    40,    33,
+       5,    35,    64,    65,    32,    36,    37,    32,    32,     3,
+      33,    33,    31,    66,    40,     3,    36,    46,    47,    48,
+      34,    50,    39,     2,    36,    78,    -1,    54,    -1,    90,
+      83,    -1,    -1,    -1,    -1,    88,    -1,    -1,    91,    -1,
+      -1,    -1,    95,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    -1,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    -1,    -1,
+      -1,    -1,    -1,    -1,    37,    38
 };
 
 #if YYDEBUG
@@ -605,16 +608,16 @@ static const short yycheck[] =
    symbol of state STATE-NUM.  */
 static const unsigned char yystos[] =
 {
-       0,    41,    42,     0,     6,     7,     8,     9,    10,    11,
-      12,    13,    14,    16,    17,    18,    19,    20,    21,    22,
-      23,    24,    25,    26,    27,    28,    29,    36,    37,    43,
-      44,    45,    48,    49,    47,    46,    30,    39,     5,     3,
-       4,    35,    60,    62,    31,    31,    31,     3,    63,    63,
-      35,    44,    54,    55,    56,    32,    65,    30,    50,    30,
-      35,    52,    53,    53,    51,    60,    63,    63,    63,    63,
-      33,    32,    36,    55,    64,    51,     5,    62,    52,    60,
-      57,    38,    62,    58,    59,    32,    34,    15,    39,    60,
-      61,    59,    60
+       0,    42,    43,     0,     6,     7,     8,     9,    10,    11,
+      12,    13,    14,    15,    17,    18,    19,    20,    21,    22,
+      23,    24,    25,    26,    27,    28,    29,    30,    37,    38,
+      44,    45,    47,    50,    51,    49,    48,    31,    46,    40,
+       5,     3,     4,    36,    62,    64,    32,    32,    32,     3,
+      65,    65,    36,    45,    56,    57,    58,    33,    67,    31,
+      52,    31,    36,    54,    55,    55,    53,    62,    40,    65,
+      65,    65,    65,    34,    33,    37,    57,    66,    53,     5,
+      64,    54,    62,    53,    59,    39,    64,    60,    61,    33,
+      35,    16,    40,    62,    63,    61,    62
 };
 #endif
 
@@ -1184,7 +1187,7 @@ yyreduce:
   switch (yyn)
     {
         case 2:
-#line 154 "parse-gram.y"
+#line 156 "parse-gram.y"
     {
       yycontrol->errcode = 0;
       epilogue_set (yyvsp[0].string, yylsp[0]);
@@ -1192,94 +1195,94 @@ yyreduce:
     break;
 
   case 6:
-#line 172 "parse-gram.y"
+#line 174 "parse-gram.y"
     { prologue_augment (yyvsp[0].string, yylsp[0]); }
     break;
 
   case 7:
-#line 173 "parse-gram.y"
+#line 175 "parse-gram.y"
     { debug_flag = 1; }
     break;
 
   case 8:
-#line 174 "parse-gram.y"
+#line 176 "parse-gram.y"
     { muscle_insert (yyvsp[-1].string, yyvsp[0].string); }
     break;
 
   case 9:
-#line 175 "parse-gram.y"
+#line 177 "parse-gram.y"
     { defines_flag = 1; }
     break;
 
   case 10:
-#line 176 "parse-gram.y"
+#line 178 "parse-gram.y"
     { error_verbose = 1; }
     break;
 
   case 11:
-#line 177 "parse-gram.y"
+#line 179 "parse-gram.y"
     { expected_conflicts = yyvsp[0].integer; }
     break;
 
   case 12:
-#line 178 "parse-gram.y"
+#line 180 "parse-gram.y"
     { spec_file_prefix = yyvsp[0].string; }
     break;
 
   case 13:
-#line 179 "parse-gram.y"
+#line 181 "parse-gram.y"
     { locations_flag = 1; }
     break;
 
   case 14:
-#line 180 "parse-gram.y"
+#line 182 "parse-gram.y"
     { spec_name_prefix = yyvsp[0].string; }
     break;
 
   case 15:
-#line 181 "parse-gram.y"
+#line 183 "parse-gram.y"
     { no_lines_flag = 1; }
     break;
 
   case 16:
-#line 182 "parse-gram.y"
+#line 184 "parse-gram.y"
     { spec_outfile = yyvsp[0].string; }
     break;
 
   case 17:
-#line 183 "parse-gram.y"
+#line 185 "parse-gram.y"
     { pure_parser = 1; }
     break;
 
   case 18:
-#line 184 "parse-gram.y"
+#line 186 "parse-gram.y"
     { skeleton = yyvsp[0].string; }
     break;
 
   case 19:
-#line 185 "parse-gram.y"
+#line 187 "parse-gram.y"
     { token_table_flag = 1; }
     break;
 
   case 20:
-#line 186 "parse-gram.y"
+#line 188 "parse-gram.y"
     { report_flag = 1; }
     break;
 
   case 21:
-#line 187 "parse-gram.y"
+#line 189 "parse-gram.y"
     { yacc_flag = 1; }
     break;
 
   case 24:
-#line 194 "parse-gram.y"
+#line 196 "parse-gram.y"
     {
       grammar_start_symbol_set (yyvsp[0].symbol, yylsp[0]);
     }
     break;
 
   case 25:
-#line 198 "parse-gram.y"
+#line 200 "parse-gram.y"
     {
       typed = 1;
       MUSCLE_INSERT_INT ("stype_line", yylsp[0].first_line);
@@ -1289,24 +1292,27 @@ yyreduce:
 
   case 26:
 #line 206 "parse-gram.y"
-    { current_class = nterm_sym; }
+    { current_braced_code = destructor_braced_code; }
     break;
 
   case 27:
-#line 207 "parse-gram.y"
+#line 208 "parse-gram.y"
     {
-      current_class = unknown_sym;
-      current_type = NULL;
+      symbol_list_t *list;
+      for (list = yyvsp[0].list; list; list = list->next)
+       symbol_destructor_set (list->sym, list->location, yyvsp[-1].string);
+      symbol_list_free (yyvsp[0].list);
+      current_braced_code = action_braced_code;
     }
     break;
 
   case 28:
-#line 211 "parse-gram.y"
-    { current_class = token_sym; }
+#line 218 "parse-gram.y"
+    { current_class = nterm_sym; }
     break;
 
   case 29:
-#line 212 "parse-gram.y"
+#line 219 "parse-gram.y"
     {
       current_class = unknown_sym;
       current_type = NULL;
@@ -1314,7 +1320,20 @@ yyreduce:
     break;
 
   case 30:
-#line 217 "parse-gram.y"
+#line 223 "parse-gram.y"
+    { current_class = token_sym; }
+    break;
+
+  case 31:
+#line 224 "parse-gram.y"
+    {
+      current_class = unknown_sym;
+      current_type = NULL;
+    }
+    break;
+
+  case 32:
+#line 229 "parse-gram.y"
     {
       symbol_list_t *list;
       for (list = yyvsp[0].list; list; list = list->next)
@@ -1323,8 +1342,8 @@ yyreduce:
     }
     break;
 
-  case 31:
-#line 227 "parse-gram.y"
+  case 33:
+#line 239 "parse-gram.y"
     {
       symbol_list_t *list;
       ++current_prec;
@@ -1338,58 +1357,58 @@ yyreduce:
     }
     break;
 
-  case 32:
-#line 241 "parse-gram.y"
+  case 34:
+#line 253 "parse-gram.y"
     { yyval.assoc = left_assoc; }
     break;
 
-  case 33:
-#line 242 "parse-gram.y"
+  case 35:
+#line 254 "parse-gram.y"
     { yyval.assoc = right_assoc; }
     break;
 
-  case 34:
-#line 243 "parse-gram.y"
+  case 36:
+#line 255 "parse-gram.y"
     { yyval.assoc = non_assoc; }
     break;
 
-  case 35:
-#line 247 "parse-gram.y"
+  case 37:
+#line 259 "parse-gram.y"
     { current_type = NULL;}
     break;
 
-  case 36:
-#line 248 "parse-gram.y"
+  case 38:
+#line 260 "parse-gram.y"
     { current_type = yyvsp[0].string; }
     break;
 
-  case 37:
-#line 254 "parse-gram.y"
+  case 39:
+#line 266 "parse-gram.y"
     { yyval.list = symbol_list_new (yyvsp[0].symbol, yylsp[0]); }
     break;
 
-  case 38:
-#line 255 "parse-gram.y"
+  case 40:
+#line 267 "parse-gram.y"
     { yyval.list = symbol_list_prepend (yyvsp[-1].list, yyvsp[0].symbol, yylsp[0]); }
     break;
 
-  case 39:
-#line 261 "parse-gram.y"
+  case 41:
+#line 273 "parse-gram.y"
     {
        current_type = yyvsp[0].string;
      }
     break;
 
-  case 40:
-#line 265 "parse-gram.y"
+  case 42:
+#line 277 "parse-gram.y"
     {
        symbol_class_set (yyvsp[0].symbol, current_class);
        symbol_type_set (yyvsp[0].symbol, yylsp[0], current_type);
      }
     break;
 
-  case 41:
-#line 270 "parse-gram.y"
+  case 43:
+#line 282 "parse-gram.y"
     {
       symbol_class_set (yyvsp[-1].symbol, current_class);
       symbol_type_set (yyvsp[-1].symbol, yylsp[-1], current_type);
@@ -1397,8 +1416,8 @@ yyreduce:
     }
     break;
 
-  case 42:
-#line 276 "parse-gram.y"
+  case 44:
+#line 288 "parse-gram.y"
     {
       symbol_class_set (yyvsp[-1].symbol, current_class);
       symbol_type_set (yyvsp[-1].symbol, yylsp[-1], current_type);
@@ -1406,8 +1425,8 @@ yyreduce:
     }
     break;
 
-  case 43:
-#line 282 "parse-gram.y"
+  case 45:
+#line 294 "parse-gram.y"
     {
       symbol_class_set (yyvsp[-2].symbol, current_class);
       symbol_type_set (yyvsp[-2].symbol, yylsp[-2], current_type);
@@ -1416,101 +1435,101 @@ yyreduce:
     }
     break;
 
-  case 44:
-#line 293 "parse-gram.y"
+  case 46:
+#line 305 "parse-gram.y"
     {;}
     break;
 
-  case 45:
-#line 295 "parse-gram.y"
+  case 47:
+#line 307 "parse-gram.y"
     {;}
     break;
 
-  case 50:
-#line 317 "parse-gram.y"
+  case 52:
+#line 329 "parse-gram.y"
     { current_lhs = yyvsp[-1].symbol; current_lhs_location = yylsp[-1]; }
     break;
 
-  case 51:
-#line 318 "parse-gram.y"
+  case 53:
+#line 330 "parse-gram.y"
     {;}
     break;
 
-  case 52:
-#line 322 "parse-gram.y"
+  case 54:
+#line 334 "parse-gram.y"
     { grammar_rule_end (yylsp[0]); }
     break;
 
-  case 53:
-#line 323 "parse-gram.y"
+  case 55:
+#line 335 "parse-gram.y"
     { grammar_rule_end (yylsp[0]); }
     break;
 
-  case 54:
-#line 328 "parse-gram.y"
+  case 56:
+#line 340 "parse-gram.y"
     { grammar_rule_begin (current_lhs, current_lhs_location); }
     break;
 
-  case 55:
-#line 330 "parse-gram.y"
+  case 57:
+#line 342 "parse-gram.y"
     { grammar_current_rule_symbol_append (yyvsp[0].symbol, yylsp[0]); }
     break;
 
-  case 56:
-#line 332 "parse-gram.y"
+  case 58:
+#line 344 "parse-gram.y"
     { grammar_current_rule_action_append (yyvsp[0].string, yylsp[0]); }
     break;
 
-  case 57:
-#line 334 "parse-gram.y"
+  case 59:
+#line 346 "parse-gram.y"
     { grammar_current_rule_prec_set (yyvsp[0].symbol); }
     break;
 
-  case 58:
-#line 338 "parse-gram.y"
+  case 60:
+#line 350 "parse-gram.y"
     { yyval.symbol = yyvsp[0].symbol; }
     break;
 
-  case 59:
-#line 339 "parse-gram.y"
+  case 61:
+#line 351 "parse-gram.y"
     { yyval.symbol = yyvsp[0].symbol; }
     break;
 
-  case 60:
-#line 340 "parse-gram.y"
+  case 62:
+#line 352 "parse-gram.y"
     { yyval.symbol = getsym (yyvsp[0].string, yylsp[0]); }
     break;
 
-  case 61:
-#line 345 "parse-gram.y"
+  case 63:
+#line 357 "parse-gram.y"
     { yyval.string = yyvsp[0].string; }
     break;
 
-  case 62:
-#line 351 "parse-gram.y"
+  case 64:
+#line 363 "parse-gram.y"
     {
       yyval.symbol = getsym (yyvsp[0].string, yylsp[0]);
       symbol_class_set (yyval.symbol, token_sym);
     }
     break;
 
-  case 63:
-#line 360 "parse-gram.y"
+  case 65:
+#line 372 "parse-gram.y"
     {
       yyval.string = yyvsp[0].string + 1;
       yyval.string[strlen (yyval.string) - 1] = '\0';
     }
     break;
 
-  case 64:
-#line 368 "parse-gram.y"
+  case 66:
+#line 380 "parse-gram.y"
     {
       yyval.string = xstrdup ("");
     }
     break;
 
-  case 65:
-#line 372 "parse-gram.y"
+  case 67:
+#line 384 "parse-gram.y"
     {
       yyval.string = yyvsp[0].string;
     }
@@ -1520,7 +1539,7 @@ yyreduce:
     }
 
 /* Line 1012 of /usr/local/share/bison/bison.simple.  */
-#line 1524 "parse-gram.c"
+#line 1543 "parse-gram.c"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -1741,7 +1760,7 @@ yyreturn:
   return yyresult;
 }
 
-#line 381 "parse-gram.y"
+#line 393 "parse-gram.y"
 
 /*------------------------------------------------------------------.
 | When debugging the parser, display tokens' locations and values.  |
index 543c70c..8b76eb4 100644 (file)
      PERCENT_TOKEN = 261,
      PERCENT_NTERM = 262,
      PERCENT_TYPE = 263,
-     PERCENT_UNION = 264,
-     PERCENT_LEFT = 265,
-     PERCENT_RIGHT = 266,
-     PERCENT_NONASSOC = 267,
-     PERCENT_EXPECT = 268,
-     PERCENT_START = 269,
-     PERCENT_PREC = 270,
-     PERCENT_VERBOSE = 271,
-     PERCENT_ERROR_VERBOSE = 272,
-     PERCENT_OUTPUT = 273,
-     PERCENT_FILE_PREFIX = 274,
-     PERCENT_NAME_PREFIX = 275,
-     PERCENT_DEFINE = 276,
-     PERCENT_PURE_PARSER = 277,
-     PERCENT_DEFINES = 278,
-     PERCENT_YACC = 279,
-     PERCENT_DEBUG = 280,
-     PERCENT_LOCATIONS = 281,
-     PERCENT_NO_LINES = 282,
-     PERCENT_SKELETON = 283,
-     PERCENT_TOKEN_TABLE = 284,
-     TYPE = 285,
-     EQUAL = 286,
-     SEMICOLON = 287,
-     COLON = 288,
-     PIPE = 289,
-     ID = 290,
-     PERCENT_PERCENT = 291,
-     PROLOGUE = 292,
-     EPILOGUE = 293,
-     BRACED_CODE = 294
+     PERCENT_DESTRUCTOR = 264,
+     PERCENT_UNION = 265,
+     PERCENT_LEFT = 266,
+     PERCENT_RIGHT = 267,
+     PERCENT_NONASSOC = 268,
+     PERCENT_EXPECT = 269,
+     PERCENT_START = 270,
+     PERCENT_PREC = 271,
+     PERCENT_VERBOSE = 272,
+     PERCENT_ERROR_VERBOSE = 273,
+     PERCENT_OUTPUT = 274,
+     PERCENT_FILE_PREFIX = 275,
+     PERCENT_NAME_PREFIX = 276,
+     PERCENT_DEFINE = 277,
+     PERCENT_PURE_PARSER = 278,
+     PERCENT_DEFINES = 279,
+     PERCENT_YACC = 280,
+     PERCENT_DEBUG = 281,
+     PERCENT_LOCATIONS = 282,
+     PERCENT_NO_LINES = 283,
+     PERCENT_SKELETON = 284,
+     PERCENT_TOKEN_TABLE = 285,
+     TYPE = 286,
+     EQUAL = 287,
+     SEMICOLON = 288,
+     COLON = 289,
+     PIPE = 290,
+     ID = 291,
+     PERCENT_PERCENT = 292,
+     PROLOGUE = 293,
+     EPILOGUE = 294,
+     BRACED_CODE = 295
    };
 # endif
   /* POSIX requires `int' for tokens in interfaces.  */
 #define PERCENT_TOKEN 261
 #define PERCENT_NTERM 262
 #define PERCENT_TYPE 263
-#define PERCENT_UNION 264
-#define PERCENT_LEFT 265
-#define PERCENT_RIGHT 266
-#define PERCENT_NONASSOC 267
-#define PERCENT_EXPECT 268
-#define PERCENT_START 269
-#define PERCENT_PREC 270
-#define PERCENT_VERBOSE 271
-#define PERCENT_ERROR_VERBOSE 272
-#define PERCENT_OUTPUT 273
-#define PERCENT_FILE_PREFIX 274
-#define PERCENT_NAME_PREFIX 275
-#define PERCENT_DEFINE 276
-#define PERCENT_PURE_PARSER 277
-#define PERCENT_DEFINES 278
-#define PERCENT_YACC 279
-#define PERCENT_DEBUG 280
-#define PERCENT_LOCATIONS 281
-#define PERCENT_NO_LINES 282
-#define PERCENT_SKELETON 283
-#define PERCENT_TOKEN_TABLE 284
-#define TYPE 285
-#define EQUAL 286
-#define SEMICOLON 287
-#define COLON 288
-#define PIPE 289
-#define ID 290
-#define PERCENT_PERCENT 291
-#define PROLOGUE 292
-#define EPILOGUE 293
-#define BRACED_CODE 294
+#define PERCENT_DESTRUCTOR 264
+#define PERCENT_UNION 265
+#define PERCENT_LEFT 266
+#define PERCENT_RIGHT 267
+#define PERCENT_NONASSOC 268
+#define PERCENT_EXPECT 269
+#define PERCENT_START 270
+#define PERCENT_PREC 271
+#define PERCENT_VERBOSE 272
+#define PERCENT_ERROR_VERBOSE 273
+#define PERCENT_OUTPUT 274
+#define PERCENT_FILE_PREFIX 275
+#define PERCENT_NAME_PREFIX 276
+#define PERCENT_DEFINE 277
+#define PERCENT_PURE_PARSER 278
+#define PERCENT_DEFINES 279
+#define PERCENT_YACC 280
+#define PERCENT_DEBUG 281
+#define PERCENT_LOCATIONS 282
+#define PERCENT_NO_LINES 283
+#define PERCENT_SKELETON 284
+#define PERCENT_TOKEN_TABLE 285
+#define TYPE 286
+#define EQUAL 287
+#define SEMICOLON 288
+#define COLON 289
+#define PIPE 290
+#define ID 291
+#define PERCENT_PERCENT 292
+#define PROLOGUE 293
+#define EPILOGUE 294
+#define BRACED_CODE 295
 
 
 
 
 #ifndef YYSTYPE
-#line 90 "parse-gram.y"
+#line 91 "parse-gram.y"
 typedef union {
   symbol_t *symbol;
   symbol_list_t *list;
@@ -102,7 +104,7 @@ typedef union {
   associativity assoc;
 } yystype;
 /* Line 1271 of /usr/local/share/bison/bison.simple.  */
-#line 106 "y.tab.h"
+#line 108 "y.tab.h"
 # define YYSTYPE yystype
 #endif
 
index 4eaecb3..c3250cc 100644 (file)
@@ -82,6 +82,7 @@ symbol_t *current_lhs;
 location_t current_lhs_location;
 associativity current_assoc;
 int current_prec = 0;
+braced_code_t current_braced_code = action_braced_code;
 %}
 
 
@@ -100,13 +101,14 @@ int current_prec = 0;
 %token STRING CHARACTER
 %token INT
 
-%token PERCENT_TOKEN "%token"
-%token PERCENT_NTERM "%nterm"
-%token PERCENT_TYPE  "%type"
-%token PERCENT_UNION "%union"
-%token PERCENT_LEFT     "%left"
-%token PERCENT_RIGHT    "%right"
-%token PERCENT_NONASSOC "%nonassoc"
+%token PERCENT_TOKEN       "%token"
+%token PERCENT_NTERM       "%nterm"
+%token PERCENT_TYPE        "%type"
+%token PERCENT_DESTRUCTOR  "%destructor"
+%token PERCENT_UNION       "%union"
+%token PERCENT_LEFT        "%left"
+%token PERCENT_RIGHT       "%right"
+%token PERCENT_NONASSOC    "%nonassoc"
 
 %token PERCENT_EXPECT "%expect"
 %token PERCENT_START "%start"
@@ -200,6 +202,16 @@ grammar_declaration:
       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, list->location, $3);
+      symbol_list_free ($4);
+      current_braced_code = action_braced_code;
+    }
 ;
 
 symbol_declaration:
index b5b0ae3..e40cafc 100644 (file)
@@ -48,7 +48,16 @@ void gram_error (gram_control_t *control,
                 location_t *loc, const char *msg);
 int gram_parse (void *control);
 
-extern int typed;
+/* The sort of braced code we are in.  */
+typedef enum braced_code_e
+  {
+    action_braced_code,
+    destructor_braced_code
+  } braced_code_t;
+/* FIXME: This is really a dirty hack which demonstrates that we
+   should probably not try to parse the actions now.  */
+extern braced_code_t current_braced_code;
+
 
 /* From reader.c. */
 void grammar_start_symbol_set PARAMS ((symbol_t *s, location_t l));
@@ -65,5 +74,6 @@ void grammar_current_rule_action_append PARAMS ((const char *action,
                                                 location_t l));
 extern symbol_list_t *current_rule;
 void reader PARAMS ((void));
+extern int typed;
 
 #endif /* !READER_H_ */
index ca22f0d..4d9aaa1 100644 (file)
@@ -309,48 +309,49 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
        *yy_cp = '\0'; \
        yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 92
-#define YY_END_OF_BUFFER 93
-static yyconst short int yy_accept[349] =
+#define YY_NUM_RULES 93
+#define YY_END_OF_BUFFER 94
+static yyconst short int yy_accept[357] =
     {   0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,   93,   44,
-       33,   32,   32,   37,   44,   36,   34,   44,   35,   29,
-       31,   44,   28,   41,   30,   48,   49,   49,   50,   45,
-       46,   73,   75,   75,   72,   45,   92,   46,   69,   71,
-       71,   68,   92,   52,   53,   53,   51,   92,   55,   56,
-       56,   54,   84,   85,   85,   77,   86,   76,   86,   86,
-       45,   46,   81,   80,   88,   90,   90,   77,   92,   76,
-       92,   91,   91,   91,   77,   76,   91,   33,   32,   32,
-       32,   32,   43,    0,    0,    0,    0,    0,    0,    0,
-
-        0,    0,    0,    0,    0,    0,    0,   40,   34,   38,
-       39,   35,    0,   48,   49,   49,   49,   49,   47,   73,
-       75,   75,   75,   75,   74,   71,   71,   71,   71,   70,
-       52,   53,   53,   53,   53,   67,   66,   67,   59,   60,
-       61,   62,   63,   64,   65,   67,   56,   56,   56,   56,
-       84,   85,   85,   85,   85,   82,    0,   82,    0,   78,
-       79,   83,    0,   83,   88,   90,   90,   90,   90,   89,
-        0,   87,   91,   91,   91,   91,   91,   78,   79,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   94,   45,
+       34,   33,   33,   38,   45,   37,   35,   45,   36,   30,
+       32,   45,   29,   42,   31,   49,   50,   50,   51,   46,
+       47,   74,   76,   76,   73,   46,   93,   47,   70,   72,
+       72,   69,   93,   53,   54,   54,   52,   93,   56,   57,
+       57,   55,   85,   86,   86,   78,   87,   77,   87,   87,
+       46,   47,   82,   81,   89,   91,   91,   78,   93,   77,
+       93,   92,   92,   92,   78,   77,   92,   34,   33,   33,
+       33,   33,   44,    0,    0,    0,    0,    0,    0,    0,
+
+        0,    0,    0,    0,    0,    0,    0,   41,   35,   39,
+       40,   36,    0,   49,   50,   50,   50,   50,   48,   74,
+       76,   76,   76,   76,   75,   72,   72,   72,   72,   71,
+       53,   54,   54,   54,   54,   68,   67,   68,   60,   61,
+       62,   63,   64,   65,   66,   68,   57,   57,   57,   57,
+       85,   86,   86,   86,   86,   83,    0,   83,    0,   79,
+       80,   84,    0,   84,   89,   91,   91,   91,   91,   90,
+        0,   88,   92,   92,   92,   92,   92,   79,   80,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 
-        0,   39,   42,    0,    0,    0,   79,   79,   79,    0,
+        0,   40,   43,    0,    0,    0,   80,   80,   80,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,   57,   58,    0,    0,    0,    0,
-        0,    0,    0,    0,    9,    0,    0,    0,    0,    0,
-        0,   16,    0,    0,    0,    0,   21,    0,   24,    0,
-        0,   27,    0,    2,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,   14,    0,    0,   18,    0,   20,   22,
-       25,    0,    1,    3,    0,    6,    0,    0,    0,    0,
-        0,    0,   15,    0,    0,    0,    0,    4,    0,    0,
-
-        0,    0,    0,    0,    0,    0,    0,    0,   26,    0,
-        0,    0,    0,    0,   12,   13,    0,   19,    0,    0,
-        0,    0,   10,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    7,    0,   11,   17,   23,    0,    0,
-        5,    0,    0,    0,    0,    0,    8,    0
+        0,    0,    0,    0,    0,   58,   59,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,   10,    0,    0,    0,
+        0,    0,    0,   17,    0,    0,    0,    0,   22,    0,
+       25,    0,    0,   28,    0,    2,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,   15,    0,    0,   19,
+        0,   21,   23,   26,    0,    1,    3,    0,    0,    7,
+        0,    0,    0,    0,    0,    0,   16,    0,    0,    0,
+
+        0,    4,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,   27,    0,    0,    0,    0,    0,    0,
+       13,   14,    0,   20,    0,    0,    0,    0,    0,   11,
+        0,    0,    0,    5,    0,    0,    0,    0,    0,    0,
+        0,    8,    0,   12,   18,   24,    0,    0,    6,    0,
+        0,    0,    0,    0,    9,    0
     } ;
 
 static yyconst int yy_ec[256] =
@@ -394,97 +395,99 @@ static yyconst int yy_meta[51] =
         9,    9,    9,    9,    9,    9,    9,    5,    1,    5
     } ;
 
-static yyconst short int yy_base[375] =
+static yyconst short int yy_base[383] =
     {   0,
         0,    0,   48,   51,   58,   61,   83,   86,   73,   94,
-      108,  110,  131,  179,  227,  249,  116,  142,  790,  791,
-      787,   55,   64,  791,  267,  791,    0,   44,   79,  791,
-      791,    0,  791,  791,  791,    0,   97,   99,  776,  791,
-      791,    0,  119,  122,  791,  791,    0,  791,  791,  126,
-      138,  791,    0,    0,  145,  153,  791,  311,  791,  155,
-      157,  791,    0,  159,  164,  791,  159,  791,   62,  164,
-      791,  791,  791,  791,    0,  185,  189,  791,  125,  791,
-      185,  192,  201,  203,  205,  207,  209,  785,  211,  213,
-      216,  219,  791,  752,  755,  187,  750,   49,  198,  739,
-
-      199,  748,  109,  208,  743,  750,  753,  791,    0,  791,
-        0,  212,  759,    0,  241,  255,  259,  261,  791,    0,
-      263,  265,  272,  274,  791,  276,  278,  280,  282,  791,
-        0,  284,  286,  288,  296,  791,  791,  764,  791,  791,
-      791,  791,  791,  791,  791,    0,  298,  314,  316,  318,
-        0,  322,  324,  326,  328,  791,  322,  326,    0,  791,
-        0,  791,  330,  332,    0,  344,  347,  355,  357,  243,
-      263,  791,  359,  361,  363,  365,  367,  369,  371,  738,
-      159,  734,  734,  200,  742,  744,  734,  366,  740,  726,
-      738,  726,  734,  735,  738,  722,  727,  721,  726,  718,
-
-      730,    0,  791,  744,    0,  737,    0,  374,  377,  729,
-      710,  719,  713,  721,  720,  719,  705,  721,  716,  709,
-      718,  702,  702,  713,  710,  706,  702,  696,  699,  705,
-      704,  694,  705,  703,  791,  791,  373,  689,  697,  690,
-      686,  698,  715,  695,  791,  680,  372,  688,  679,  683,
-      675,  791,  375,  675,  687,  673,  791,  677,  791,  676,
-      674,  791,  665,  791,  681,  378,  667,  669,  380,  674,
-      643,  641,  615,  791,  611,  592,  791,  588,  791,  382,
-      791,  586,  791,  581,  577,  791,  579,  580,  579,  574,
-      580,  569,  791,  581,  567,  562,  562,  791,  552,  551,
-
-      536,  529,  524,  503,  516,  502,  502,  510,  791,  490,
-      499,  483,  366,  375,  791,  791,  360,  791,  362,  357,
-      321,  313,  791,  307,  303,  287,  265,  249,  228,  214,
-      207,  212,  160,  791,  157,  791,  791,  791,  168,  384,
-      791,  149,  137,   91,   85,   62,  791,  791,  409,  422,
-      435,  448,  461,  474,  487,  500,  505,  515,  528,  541,
-      552,  565,  578,  590,  603,  616,  629,  642,  655,   85,
-      668,  681,  694,   59
+      108,  110,  131,  179,  227,  249,  116,  142,  798,  799,
+      795,   55,   64,  799,  267,  799,    0,   44,   79,  799,
+      799,    0,  799,  799,  799,    0,   97,   99,  784,  799,
+      799,    0,  119,  122,  799,  799,    0,  799,  799,  126,
+      138,  799,    0,    0,  145,  153,  799,  311,  799,  155,
+      157,  799,    0,  159,  164,  799,  159,  799,   62,  164,
+      799,  799,  799,  799,    0,  185,  189,  799,  125,  799,
+      185,  192,  201,  203,  205,  207,  209,  793,  211,  213,
+      216,  219,  799,  760,  763,  187,  758,   49,  198,  747,
+
+      199,  756,  109,  208,  751,  758,  761,  799,    0,  799,
+        0,  212,  767,    0,  241,  255,  259,  261,  799,    0,
+      263,  265,  272,  274,  799,  276,  278,  280,  282,  799,
+        0,  284,  286,  288,  296,  799,  799,  772,  799,  799,
+      799,  799,  799,  799,  799,    0,  298,  314,  316,  318,
+        0,  322,  324,  326,  328,  799,  322,  326,    0,  799,
+        0,  799,  330,  332,    0,  344,  347,  355,  357,  243,
+      263,  799,  359,  361,  363,  365,  367,  369,  371,  746,
+      349,  742,  742,  144,  750,  752,  742,  367,  748,  734,
+      746,  734,  742,  743,  746,  730,  735,  729,  734,  726,
+
+      738,    0,  799,  752,    0,  745,    0,  375,  378,  737,
+      718,  727,  717,  720,  728,  727,  726,  712,  728,  723,
+      716,  725,  709,  709,  720,  717,  713,  709,  703,  706,
+      712,  711,  701,  712,  710,  799,  799,  397,  696,  704,
+      697,  693,  692,  704,  721,  701,  799,  686,  161,  694,
+      685,  689,  681,  799,  373,  681,  693,  679,  799,  683,
+      799,  682,  656,  799,  644,  799,  639,  622,  376,  601,
+      603,  379,  606,  595,  596,  590,  799,  588,  590,  799,
+      584,  799,  384,  799,  580,  799,  578,  591,  573,  799,
+      576,  565,  555,  552,  562,  540,  799,  540,  518,  513,
+
+      525,  799,  509,  518,  513,  498,  500,  390,  377,  390,
+      376,  378,  389,  799,  375,  372,  381,  365,  354,  359,
+      799,  799,  346,  799,  360,  344,  357,  321,  313,  799,
+      307,  303,  287,  799,  265,  249,  228,  214,  207,  216,
+      200,  799,  193,  799,  799,  799,  172,  396,  799,  169,
+      164,   91,   85,   62,  799,  799,  421,  434,  447,  460,
+      473,  486,  499,  512,  517,  527,  540,  553,  564,  577,
+      590,  602,  615,  628,  641,  654,  667,   85,  680,  693,
+      706,   59
     } ;
 
-static yyconst short int yy_def[375] =
+static yyconst short int yy_def[383] =
     {   0,
-      348,    1,  349,  349,  350,  350,  351,  351,  352,  352,
-      353,  353,  354,  354,  355,  355,  356,  356,  348,  348,
-      348,  348,  348,  348,  348,  348,  357,  348,  348,  348,
-      348,  358,  348,  348,  348,  359,  348,  348,  348,  348,
-      348,  360,  348,  348,  348,  348,  361,  348,  348,  348,
-      348,  348,  362,  363,  348,  348,  348,  364,  348,  348,
-      348,  348,  365,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  366,  348,  348,  348,  367,  348,
-      348,  368,  368,  368,  368,  368,  368,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-
-      348,  348,  348,  348,  348,  348,  348,  348,  357,  348,
-      369,  348,  358,  359,  348,  348,  348,  348,  348,  360,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      363,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  370,  348,  348,  348,  348,
-      365,  348,  348,  348,  348,  348,  348,  348,  371,  348,
-      372,  348,  348,  348,  366,  348,  348,  348,  348,  367,
-      367,  348,  368,  368,  368,  368,  368,  368,  373,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-
-      348,  369,  348,  348,  374,  371,  372,  373,  373,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,    0,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348
+      356,    1,  357,  357,  358,  358,  359,  359,  360,  360,
+      361,  361,  362,  362,  363,  363,  364,  364,  356,  356,
+      356,  356,  356,  356,  356,  356,  365,  356,  356,  356,
+      356,  366,  356,  356,  356,  367,  356,  356,  356,  356,
+      356,  368,  356,  356,  356,  356,  369,  356,  356,  356,
+      356,  356,  370,  371,  356,  356,  356,  372,  356,  356,
+      356,  356,  373,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  374,  356,  356,  356,  375,  356,
+      356,  376,  376,  376,  376,  376,  376,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+
+      356,  356,  356,  356,  356,  356,  356,  356,  365,  356,
+      377,  356,  366,  367,  356,  356,  356,  356,  356,  368,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      371,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  378,  356,  356,  356,  356,
+      373,  356,  356,  356,  356,  356,  356,  356,  379,  356,
+      380,  356,  356,  356,  374,  356,  356,  356,  356,  375,
+      375,  356,  376,  376,  376,  376,  376,  376,  381,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+
+      356,  377,  356,  356,  382,  379,  380,  381,  381,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,    0,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356
     } ;
 
-static yyconst short int yy_nxt[842] =
+static yyconst short int yy_nxt[850] =
     {   0,
        20,   21,   22,   23,   24,   20,   25,   26,   20,   20,
        27,   28,   29,   29,   30,   31,   32,   33,   20,   20,
@@ -492,96 +495,96 @@ static yyconst short int yy_nxt[842] =
        27,   27,   27,   27,   27,   27,   27,   27,   27,   27,
        27,   27,   27,   27,   27,   27,   27,   34,   35,   20,
        37,   38,  110,   37,   38,  111,   39,   89,   90,   39,
-       43,   44,   45,   43,   44,   45,   91,   92,  236,   40,
+       43,   44,   45,   43,   44,   45,   91,   92,  237,   40,
       160,   41,   40,  161,   41,   55,   56,   57,  185,   46,
        47,   48,   46,   47,   48,   50,   51,  186,   50,   51,
        52,  112,  112,   52,  205,   58,   55,   56,   57,  115,
 
-      116,  117,  118,  347,   46,   53,   48,   46,   53,   48,
-       60,   61,   60,   61,  346,   62,   58,   62,   83,   84,
-       85,  121,  122,   86,  123,  124,  345,   87,  126,  127,
+      116,  117,  118,  355,   46,   53,   48,   46,   53,   48,
+       60,   61,   60,   61,  354,   62,   58,   62,   83,   84,
+       85,  121,  122,   86,  123,  124,  353,   87,  126,  127,
        58,  171,   58,   64,   65,   66,   67,   46,   68,   48,
       128,  129,   69,  194,   83,   84,   85,  132,  133,   86,
        70,  195,   71,   87,   72,  134,  135,  147,  148,  149,
       150,  152,  153,   46,  156,   48,  154,  155,  157,  162,
-      344,  158,  158,  163,  172,  159,  164,  164,   73,  343,
-       74,   64,   65,   66,   67,  211,   68,  166,  167,  212,
-       69,  168,  169,  160,  174,  175,  161,  341,   70,  340,
+      274,  158,  158,  163,  172,  159,  164,  164,   73,  216,
+       74,   64,   65,   66,   67,  274,   68,  166,  167,  217,
+       69,  168,  169,  160,  174,  175,  161,  352,   70,  351,
 
-       71,  339,   72,  174,  176,  177,  175,  174,  175,  174,
+       71,  349,   72,  174,  176,  177,  175,  174,  175,  174,
       175,  174,  175,   89,   90,   91,   92,  178,   89,   90,
       179,   91,   92,  187,  112,  112,   73,  182,   74,   76,
-       77,   78,  183,   79,   80,  215,  188,  196,   81,  191,
-      189,  338,  192,  115,  116,  216,  197,  337,   46,  348,
-       48,   76,   77,   78,  198,   79,   80,  117,  118,  336,
+       77,   78,  183,   79,   80,  348,  188,  196,   81,  191,
+      189,  347,  192,  115,  116,  346,  197,  345,   46,  356,
+       48,   76,   77,   78,  198,   79,   80,  117,  118,  344,
        81,  115,  116,  117,  118,  121,  122,  123,  124,  171,
-       46,  335,   48,   93,  121,  122,  123,  124,  126,  127,
+       46,  343,   48,   93,  121,  122,  123,  124,  126,  127,
       128,  129,  126,  127,  128,  129,  132,  133,  134,  135,
-      132,  133,  348,   94,  334,   95,   96,   97,  134,  135,
-
-      147,  148,   98,  333,   99,  100,  101,  102,  103,  104,
-      105,  106,  348,  107,  108,  137,  149,  150,  147,  148,
-      149,  150,  332,  138,  152,  153,  154,  155,  152,  153,
-      154,  155,  331,  137,  158,  158,  139,  140,  158,  158,
-      330,  141,  164,  164,  164,  164,  166,  167,  142,  168,
-      169,  143,  329,  144,  328,  145,  146,  166,  167,  168,
+      132,  133,  356,   94,  342,   95,   96,   97,  134,  135,
+
+      147,  148,   98,  341,   99,  100,  101,  102,  103,  104,
+      105,  106,  356,  107,  108,  137,  149,  150,  147,  148,
+      149,  150,  340,  138,  152,  153,  154,  155,  152,  153,
+      154,  155,  339,  137,  158,  158,  139,  140,  158,  158,
+      338,  141,  164,  164,  164,  164,  166,  167,  142,  168,
+      169,  143,  337,  144,  336,  145,  146,  166,  167,  168,
       169,  174,  175,  174,  176,  177,  175,  177,  175,  174,
-      176,  174,  175,  174,  209,  220,  174,  209,  156,  177,
-      209,  271,  157,  327,  276,  158,  158,  285,  326,  288,
-      220,  296,  207,  342,  207,  207,  271,  207,  207,  276,
-
-      207,  325,  285,  221,  288,  324,  296,  323,  342,   36,
-       36,   36,   36,   36,   36,   36,   36,   36,   36,   36,
-       36,   36,   42,   42,   42,   42,   42,   42,   42,   42,
-       42,   42,   42,   42,   42,   49,   49,   49,   49,   49,
-       49,   49,   49,   49,   49,   49,   49,   49,   54,   54,
+      176,  174,  175,  174,  209,  211,  221,  174,  209,  212,
+      177,  209,  279,  335,  334,  289,  333,  332,  292,  331,
+      213,  221,  207,  300,  207,  330,  207,  279,  207,  207,
+
+      289,  207,  156,  292,  222,  350,  157,  329,  300,  158,
+      158,  328,  327,  326,  325,  324,  323,  322,  321,  320,
+      350,   36,   36,   36,   36,   36,   36,   36,   36,   36,
+       36,   36,   36,   36,   42,   42,   42,   42,   42,   42,
+       42,   42,   42,   42,   42,   42,   42,   49,   49,   49,
+       49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
        54,   54,   54,   54,   54,   54,   54,   54,   54,   54,
-       54,   59,   59,   59,   59,   59,   59,   59,   59,   59,
-       59,   59,   59,   59,   63,   63,   63,   63,   63,   63,
-       63,   63,   63,   63,   63,   63,   63,   75,   75,   75,
+       54,   54,   54,   59,   59,   59,   59,   59,   59,   59,
+       59,   59,   59,   59,   59,   59,   63,   63,   63,   63,
+       63,   63,   63,   63,   63,   63,   63,   63,   63,   75,
+
        75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
+       75,   75,   82,   82,   82,   82,   82,   82,   82,   82,
+       82,   82,   82,   82,   82,  109,  109,  113,  113,  113,
+      113,  113,  113,  113,  113,  113,  113,  319,  113,  113,
+      114,  318,  317,  114,  114,  114,  114,  316,  114,  114,
+      114,  315,  114,  120,  314,  313,  312,  120,  120,  120,
+      120,  120,  120,  120,  125,  311,  125,  125,  125,  125,
+      125,  125,  125,  125,  125,  125,  125,  130,  310,  130,
+      130,  130,  130,  130,  130,  130,  130,  130,  130,  130,
+      131,  309,  308,  307,  131,  131,  131,  131,  131,  131,
+
+      131,  131,  136,  306,  136,  136,  136,  136,  136,  136,
+      136,  136,  136,  136,  136,  151,  305,  304,  303,  302,
+      151,  301,  151,  151,  151,  151,  299,  151,  165,  298,
+      297,  296,  165,  295,  294,  165,  165,  165,  165,  293,
+      165,  170,  291,  290,  170,  170,  170,  170,  170,  170,
+      170,  170,  170,  170,  173,  173,  173,  173,  173,  173,
+      173,  173,  173,  173,  173,  288,  173,  202,  287,  202,
+      202,  202,  202,  202,  202,  202,  202,  202,  202,  202,
+      206,  206,  206,  206,  206,  206,  206,  206,  206,  206,
+      286,  206,  206,  207,  285,  207,  207,  207,  207,  207,
+
+      207,  207,  207,  207,  207,  207,  208,  208,  208,  208,
+      208,  208,  208,  208,  208,  208,  208,  208,  208,  284,
+      283,  282,  281,  280,  278,  277,  276,  275,  273,  272,
+      271,  270,  269,  268,  267,  266,  265,  264,  263,  262,
+      261,  260,  259,  258,  257,  256,  255,  254,  253,  252,
+      251,  250,  249,  248,  247,  246,  245,  244,  243,  242,
+      241,  240,  239,  238,  236,  235,  234,  233,  232,  231,
+      230,  229,  228,  227,  226,  225,  224,  223,  220,  219,
+      218,  215,  214,  210,  204,  203,  201,  200,  199,  193,
+      190,  184,  181,  180,   88,  119,   88,  356,   19,  356,
 
-       82,   82,   82,   82,   82,   82,   82,   82,   82,   82,
-       82,   82,   82,  109,  109,  113,  113,  113,  113,  113,
-      113,  113,  113,  113,  113,  322,  113,  113,  114,  321,
-      320,  114,  114,  114,  114,  319,  114,  114,  114,  318,
-      114,  120,  317,  316,  315,  120,  120,  120,  120,  120,
-      120,  120,  125,  314,  125,  125,  125,  125,  125,  125,
-      125,  125,  125,  125,  125,  130,  313,  130,  130,  130,
-      130,  130,  130,  130,  130,  130,  130,  130,  131,  312,
-      311,  310,  131,  131,  131,  131,  131,  131,  131,  131,
-      136,  309,  136,  136,  136,  136,  136,  136,  136,  136,
-
-      136,  136,  136,  151,  308,  307,  306,  305,  151,  304,
-      151,  151,  151,  151,  303,  151,  165,  302,  301,  300,
-      165,  299,  298,  165,  165,  165,  165,  297,  165,  170,
-      295,  294,  170,  170,  170,  170,  170,  170,  170,  170,
-      170,  170,  173,  173,  173,  173,  173,  173,  173,  173,
-      173,  173,  173,  293,  173,  202,  292,  202,  202,  202,
-      202,  202,  202,  202,  202,  202,  202,  202,  206,  206,
-      206,  206,  206,  206,  206,  206,  206,  206,  291,  206,
-      206,  207,  290,  207,  207,  207,  207,  207,  207,  207,
-      207,  207,  207,  207,  208,  208,  208,  208,  208,  208,
-
-      208,  208,  208,  208,  208,  208,  208,  289,  287,  286,
-      284,  283,  282,  281,  280,  279,  278,  277,  275,  274,
-      273,  272,  270,  269,  268,  267,  266,  265,  264,  263,
-      262,  261,  260,  259,  258,  257,  256,  255,  254,  253,
-      252,  251,  250,  249,  248,  247,  246,  245,  244,  243,
-      242,  241,  240,  239,  238,  237,  235,  234,  233,  232,
-      231,  230,  229,  228,  227,  226,  225,  224,  223,  222,
-      219,  218,  217,  214,  213,  210,  204,  203,  201,  200,
-      199,  193,  190,  184,  181,  180,   88,  119,   88,  348,
-       19,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356
     } ;
 
-static yyconst short int yy_chk[842] =
+static yyconst short int yy_chk[850] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -589,93 +592,93 @@ static yyconst short int yy_chk[842] =
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         3,    3,   28,    4,    4,   28,    3,   22,   22,    4,
-        5,    5,    5,    6,    6,    6,   23,   23,  374,    3,
+        5,    5,    5,    6,    6,    6,   23,   23,  382,    3,
        69,    3,    4,   69,    4,    9,    9,    9,   98,    5,
         5,    5,    6,    6,    6,    7,    7,   98,    8,    8,
-        7,   29,   29,    8,  370,    9,   10,   10,   10,   37,
+        7,   29,   29,    8,  378,    9,   10,   10,   10,   37,
 
-       37,   38,   38,  346,    7,    7,    7,    8,    8,    8,
-       11,   11,   12,   12,  345,   11,   10,   12,   17,   17,
-       17,   43,   43,   17,   44,   44,  344,   17,   50,   50,
+       37,   38,   38,  354,    7,    7,    7,    8,    8,    8,
+       11,   11,   12,   12,  353,   11,   10,   12,   17,   17,
+       17,   43,   43,   17,   44,   44,  352,   17,   50,   50,
        11,   79,   12,   13,   13,   13,   13,   17,   13,   17,
        51,   51,   13,  103,   18,   18,   18,   55,   55,   18,
        13,  103,   13,   18,   13,   56,   56,   60,   60,   61,
        61,   64,   64,   18,   67,   18,   65,   65,   67,   70,
-      343,   67,   67,   70,   79,   67,   70,   70,   13,  342,
-       13,   14,   14,   14,   14,  181,   14,   76,   76,  181,
-       14,   77,   77,   81,   82,   82,   81,  339,   14,  335,
+      249,   67,   67,   70,   79,   67,   70,   70,   13,  184,
+       13,   14,   14,   14,   14,  249,   14,   76,   76,  184,
+       14,   77,   77,   81,   82,   82,   81,  351,   14,  350,
 
-       14,  333,   14,   83,   83,   84,   84,   85,   85,   86,
+       14,  347,   14,   83,   83,   84,   84,   85,   85,   86,
        86,   87,   87,   89,   89,   90,   90,   87,   91,   91,
        87,   92,   92,   99,  112,  112,   14,   96,   14,   15,
-       15,   15,   96,   15,   15,  184,   99,  104,   15,  101,
-       99,  332,  101,  115,  115,  184,  104,  331,   15,  170,
-       15,   16,   16,   16,  104,   16,   16,  116,  116,  330,
+       15,   15,   96,   15,   15,  343,   99,  104,   15,  101,
+       99,  341,  101,  115,  115,  340,  104,  339,   15,  170,
+       15,   16,   16,   16,  104,   16,   16,  116,  116,  338,
        16,  117,  117,  118,  118,  121,  121,  122,  122,  171,
-       16,  329,   16,   25,  123,  123,  124,  124,  126,  126,
+       16,  337,   16,   25,  123,  123,  124,  124,  126,  126,
       127,  127,  128,  128,  129,  129,  132,  132,  133,  133,
-      134,  134,  170,   25,  328,   25,   25,   25,  135,  135,
+      134,  134,  170,   25,  336,   25,   25,   25,  135,  135,
 
-      147,  147,   25,  327,   25,   25,   25,   25,   25,   25,
+      147,  147,   25,  335,   25,   25,   25,   25,   25,   25,
        25,   25,  171,   25,   25,   58,  148,  148,  149,  149,
-      150,  150,  326,   58,  152,  152,  153,  153,  154,  154,
-      155,  155,  325,   58,  157,  157,   58,   58,  158,  158,
-      324,   58,  163,  163,  164,  164,  166,  166,   58,  167,
-      167,   58,  322,   58,  321,   58,   58,  168,  168,  169,
+      150,  150,  333,   58,  152,  152,  153,  153,  154,  154,
+      155,  155,  332,   58,  157,  157,   58,   58,  158,  158,
+      331,   58,  163,  163,  164,  164,  166,  166,   58,  167,
+      167,   58,  329,   58,  328,   58,   58,  168,  168,  169,
       169,  173,  173,  174,  174,  175,  175,  176,  176,  177,
-      177,  178,  178,  179,  179,  188,  208,  208,  237,  209,
-      209,  247,  237,  320,  253,  237,  237,  266,  319,  269,
-      188,  280,  179,  340,  179,  208,  247,  208,  209,  253,
-
-      209,  317,  266,  188,  269,  314,  280,  313,  340,  349,
-      349,  349,  349,  349,  349,  349,  349,  349,  349,  349,
-      349,  349,  350,  350,  350,  350,  350,  350,  350,  350,
-      350,  350,  350,  350,  350,  351,  351,  351,  351,  351,
-      351,  351,  351,  351,  351,  351,  351,  351,  352,  352,
-      352,  352,  352,  352,  352,  352,  352,  352,  352,  352,
-      352,  353,  353,  353,  353,  353,  353,  353,  353,  353,
-      353,  353,  353,  353,  354,  354,  354,  354,  354,  354,
-      354,  354,  354,  354,  354,  354,  354,  355,  355,  355,
-      355,  355,  355,  355,  355,  355,  355,  355,  355,  355,
+      177,  178,  178,  179,  179,  181,  188,  208,  208,  181,
+      209,  209,  255,  327,  326,  269,  325,  323,  272,  320,
+      181,  188,  179,  283,  179,  319,  208,  255,  208,  209,
+
+      269,  209,  238,  272,  188,  348,  238,  318,  283,  238,
+      238,  317,  316,  315,  313,  312,  311,  310,  309,  308,
+      348,  357,  357,  357,  357,  357,  357,  357,  357,  357,
+      357,  357,  357,  357,  358,  358,  358,  358,  358,  358,
+      358,  358,  358,  358,  358,  358,  358,  359,  359,  359,
+      359,  359,  359,  359,  359,  359,  359,  359,  359,  359,
+      360,  360,  360,  360,  360,  360,  360,  360,  360,  360,
+      360,  360,  360,  361,  361,  361,  361,  361,  361,  361,
+      361,  361,  361,  361,  361,  361,  362,  362,  362,  362,
+      362,  362,  362,  362,  362,  362,  362,  362,  362,  363,
+
+      363,  363,  363,  363,  363,  363,  363,  363,  363,  363,
+      363,  363,  364,  364,  364,  364,  364,  364,  364,  364,
+      364,  364,  364,  364,  364,  365,  365,  366,  366,  366,
+      366,  366,  366,  366,  366,  366,  366,  307,  366,  366,
+      367,  306,  305,  367,  367,  367,  367,  304,  367,  367,
+      367,  303,  367,  368,  301,  300,  299,  368,  368,  368,
+      368,  368,  368,  368,  369,  298,  369,  369,  369,  369,
+      369,  369,  369,  369,  369,  369,  369,  370,  296,  370,
+      370,  370,  370,  370,  370,  370,  370,  370,  370,  370,
+      371,  295,  294,  293,  371,  371,  371,  371,  371,  371,
+
+      371,  371,  372,  292,  372,  372,  372,  372,  372,  372,
+      372,  372,  372,  372,  372,  373,  291,  289,  288,  287,
+      373,  285,  373,  373,  373,  373,  281,  373,  374,  279,
+      278,  276,  374,  275,  274,  374,  374,  374,  374,  273,
+      374,  375,  271,  270,  375,  375,  375,  375,  375,  375,
+      375,  375,  375,  375,  376,  376,  376,  376,  376,  376,
+      376,  376,  376,  376,  376,  268,  376,  377,  267,  377,
+      377,  377,  377,  377,  377,  377,  377,  377,  377,  377,
+      379,  379,  379,  379,  379,  379,  379,  379,  379,  379,
+      265,  379,  379,  380,  263,  380,  380,  380,  380,  380,
+
+      380,  380,  380,  380,  380,  380,  381,  381,  381,  381,
+      381,  381,  381,  381,  381,  381,  381,  381,  381,  262,
+      260,  258,  257,  256,  253,  252,  251,  250,  248,  246,
+      245,  244,  243,  242,  241,  240,  239,  235,  234,  233,
+      232,  231,  230,  229,  228,  227,  226,  225,  224,  223,
+      222,  221,  220,  219,  218,  217,  216,  215,  214,  213,
+      212,  211,  210,  206,  204,  201,  200,  199,  198,  197,
+      196,  195,  194,  193,  192,  191,  190,  189,  187,  186,
+      185,  183,  182,  180,  138,  113,  107,  106,  105,  102,
+      100,   97,   95,   94,   88,   39,   21,   19,  356,  356,
 
       356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
-      356,  356,  356,  357,  357,  358,  358,  358,  358,  358,
-      358,  358,  358,  358,  358,  312,  358,  358,  359,  311,
-      310,  359,  359,  359,  359,  308,  359,  359,  359,  307,
-      359,  360,  306,  305,  304,  360,  360,  360,  360,  360,
-      360,  360,  361,  303,  361,  361,  361,  361,  361,  361,
-      361,  361,  361,  361,  361,  362,  302,  362,  362,  362,
-      362,  362,  362,  362,  362,  362,  362,  362,  363,  301,
-      300,  299,  363,  363,  363,  363,  363,  363,  363,  363,
-      364,  297,  364,  364,  364,  364,  364,  364,  364,  364,
-
-      364,  364,  364,  365,  296,  295,  294,  292,  365,  291,
-      365,  365,  365,  365,  290,  365,  366,  289,  288,  287,
-      366,  285,  284,  366,  366,  366,  366,  282,  366,  367,
-      278,  276,  367,  367,  367,  367,  367,  367,  367,  367,
-      367,  367,  368,  368,  368,  368,  368,  368,  368,  368,
-      368,  368,  368,  275,  368,  369,  273,  369,  369,  369,
-      369,  369,  369,  369,  369,  369,  369,  369,  371,  371,
-      371,  371,  371,  371,  371,  371,  371,  371,  272,  371,
-      371,  372,  271,  372,  372,  372,  372,  372,  372,  372,
-      372,  372,  372,  372,  373,  373,  373,  373,  373,  373,
-
-      373,  373,  373,  373,  373,  373,  373,  270,  268,  267,
-      265,  263,  261,  260,  258,  256,  255,  254,  251,  250,
-      249,  248,  246,  244,  243,  242,  241,  240,  239,  238,
-      234,  233,  232,  231,  230,  229,  228,  227,  226,  225,
-      224,  223,  222,  221,  220,  219,  218,  217,  216,  215,
-      214,  213,  212,  211,  210,  206,  204,  201,  200,  199,
-      198,  197,  196,  195,  194,  193,  192,  191,  190,  189,
-      187,  186,  185,  183,  182,  180,  138,  113,  107,  106,
-      105,  102,  100,   97,   95,   94,   88,   39,   21,   19,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348,  348,  348,  348,  348,  348,  348,  348,  348,  348,
-      348
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356,  356,
+      356,  356,  356,  356,  356,  356,  356,  356,  356
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -684,18 +687,18 @@ static char *yy_last_accepting_cpos;
 extern int yy_flex_debug;
 int yy_flex_debug = 1;
 
-static yyconst short int yy_rule_linenum[92] =
+static yyconst short int yy_rule_linenum[93] =
     {   0,
-      121,  122,  123,  124,  125,  126,  127,  128,  129,  130,
-      131,  132,  133,  134,  135,  136,  137,  138,  139,  140,
-      141,  142,  143,  144,  145,  146,  147,  149,  150,  151,
-      152,  154,  155,  156,  161,  164,  167,  170,  171,  174,
-      177,  180,  188,  194,  210,  211,  222,  234,  235,  236,
-      253,  262,  264,  284,  298,  300,  320,  332,  336,  337,
-      338,  339,  340,  341,  342,  343,  344,  359,  365,  366,
-      368,  386,  392,  393,  395,  413,  416,  419,  420,  431,
-      442,  444,  445,  447,  448,  451,  471,  478,  479,  480,
-      501
+      122,  123,  124,  125,  126,  127,  128,  129,  130,  131,
+      132,  133,  134,  135,  136,  137,  138,  139,  140,  141,
+      142,  143,  144,  145,  146,  147,  148,  149,  151,  152,
+      153,  154,  156,  157,  158,  163,  166,  169,  172,  173,
+      176,  179,  182,  190,  196,  212,  213,  224,  236,  237,
+      238,  255,  264,  266,  286,  300,  302,  322,  334,  338,
+      339,  340,  341,  342,  343,  344,  345,  346,  361,  367,
+      368,  370,  388,  394,  395,  397,  415,  418,  421,  422,
+      433,  444,  446,  458,  460,  461,  464,  484,  491,  492,
+      493,  514
 
     } ;
 
@@ -790,7 +793,8 @@ scanner_last_string_free (void)
 static int braces_level = 0;
 static int percent_percent_count = 0;
 
-static void handle_dollar PARAMS ((char *cp, location_t location));
+static void handle_action_dollar PARAMS ((char *cp, location_t location));
+static void handle_destructor_dollar PARAMS ((char *cp, location_t location));
 static void handle_at PARAMS ((char *cp));
 
 #define SC_COMMENT 1
@@ -805,7 +809,7 @@ static void handle_at PARAMS ((char *cp));
 #define SC_PROLOGUE 7
 #define SC_EPILOGUE 8
 
-#line 809 "lex.yy.c"
+#line 813 "lex.yy.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -967,7 +971,7 @@ YY_DECL
        register char *yy_cp, *yy_bp;
        register int yy_act;
 
-#line 97 "scan-gram.l"
+#line 98 "scan-gram.l"
 
 
   /* At each yylex invocation, mark the current position as the
@@ -990,7 +994,7 @@ YY_DECL
   /*----------------------------.
   | Scanning Bison directives.  |
   `----------------------------*/
-#line 994 "lex.yy.c"
+#line 998 "lex.yy.c"
 
        if ( yy_init )
                {
@@ -1041,13 +1045,13 @@ yy_match:
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 349 )
+                               if ( yy_current_state >= 357 )
                                        yy_c = yy_meta[(unsigned int) yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        ++yy_cp;
                        }
-               while ( yy_base[yy_current_state] != 791 );
+               while ( yy_base[yy_current_state] != 799 );
 
 yy_find_action:
                yy_act = yy_accept[yy_current_state];
@@ -1067,13 +1071,13 @@ do_action:      /* This label is used only to access EOF actions. */
                        {
                        if ( yy_act == 0 )
                                fprintf( stderr, "--scanner backing up\n" );
-                       else if ( yy_act < 92 )
+                       else if ( yy_act < 93 )
                                fprintf( stderr, "--accepting rule at line %d (\"%s\")\n",
                                         yy_rule_linenum[yy_act], yytext );
-                       else if ( yy_act == 92 )
+                       else if ( yy_act == 93 )
                                fprintf( stderr, "--accepting default rule (\"%s\")\n",
                                         yytext );
-                       else if ( yy_act == 93 )
+                       else if ( yy_act == 94 )
                                fprintf( stderr, "--(end of buffer or a NUL)\n" );
                        else
                                fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -1092,221 +1096,226 @@ do_action:    /* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
-#line 121 "scan-gram.l"
+#line 122 "scan-gram.l"
 return PERCENT_NONASSOC;
        YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 122 "scan-gram.l"
+#line 123 "scan-gram.l"
 return PERCENT_DEBUG;
        YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 123 "scan-gram.l"
+#line 124 "scan-gram.l"
 return PERCENT_DEFINE;
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 124 "scan-gram.l"
+#line 125 "scan-gram.l"
 return PERCENT_DEFINES;
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 125 "scan-gram.l"
-return PERCENT_ERROR_VERBOSE;
+#line 126 "scan-gram.l"
+return PERCENT_DESTRUCTOR;
        YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 126 "scan-gram.l"
-return PERCENT_EXPECT;
+#line 127 "scan-gram.l"
+return PERCENT_ERROR_VERBOSE;
        YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 127 "scan-gram.l"
-return PERCENT_FILE_PREFIX;
+#line 128 "scan-gram.l"
+return PERCENT_EXPECT;
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 128 "scan-gram.l"
-return PERCENT_YACC;
+#line 129 "scan-gram.l"
+return PERCENT_FILE_PREFIX;
        YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 129 "scan-gram.l"
-return PERCENT_LEFT;
+#line 130 "scan-gram.l"
+return PERCENT_YACC;
        YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 130 "scan-gram.l"
-return PERCENT_LOCATIONS;
+#line 131 "scan-gram.l"
+return PERCENT_LEFT;
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 131 "scan-gram.l"
-return PERCENT_NAME_PREFIX;
+#line 132 "scan-gram.l"
+return PERCENT_LOCATIONS;
        YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 132 "scan-gram.l"
-return PERCENT_NO_LINES;
+#line 133 "scan-gram.l"
+return PERCENT_NAME_PREFIX;
        YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 133 "scan-gram.l"
-return PERCENT_NONASSOC;
+#line 134 "scan-gram.l"
+return PERCENT_NO_LINES;
        YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 134 "scan-gram.l"
-return PERCENT_NTERM;
+#line 135 "scan-gram.l"
+return PERCENT_NONASSOC;
        YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 135 "scan-gram.l"
-return PERCENT_OUTPUT;
+#line 136 "scan-gram.l"
+return PERCENT_NTERM;
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 136 "scan-gram.l"
-return PERCENT_PREC;
+#line 137 "scan-gram.l"
+return PERCENT_OUTPUT;
        YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 137 "scan-gram.l"
-return PERCENT_PURE_PARSER;
+#line 138 "scan-gram.l"
+return PERCENT_PREC;
        YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 138 "scan-gram.l"
-return PERCENT_RIGHT;
+#line 139 "scan-gram.l"
+return PERCENT_PURE_PARSER;
        YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 139 "scan-gram.l"
-return PERCENT_SKELETON;
+#line 140 "scan-gram.l"
+return PERCENT_RIGHT;
        YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 140 "scan-gram.l"
-return PERCENT_START;
+#line 141 "scan-gram.l"
+return PERCENT_SKELETON;
        YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 141 "scan-gram.l"
-return PERCENT_TOKEN;
+#line 142 "scan-gram.l"
+return PERCENT_START;
        YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 142 "scan-gram.l"
+#line 143 "scan-gram.l"
 return PERCENT_TOKEN;
        YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 143 "scan-gram.l"
-return PERCENT_TOKEN_TABLE;
+#line 144 "scan-gram.l"
+return PERCENT_TOKEN;
        YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 144 "scan-gram.l"
-return PERCENT_TYPE;
+#line 145 "scan-gram.l"
+return PERCENT_TOKEN_TABLE;
        YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 145 "scan-gram.l"
-return PERCENT_UNION;
+#line 146 "scan-gram.l"
+return PERCENT_TYPE;
        YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 146 "scan-gram.l"
-return PERCENT_VERBOSE;
+#line 147 "scan-gram.l"
+return PERCENT_UNION;
        YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 147 "scan-gram.l"
-return PERCENT_YACC;
+#line 148 "scan-gram.l"
+return PERCENT_VERBOSE;
        YY_BREAK
 case 28:
 YY_RULE_SETUP
 #line 149 "scan-gram.l"
-return EQUAL;
+return PERCENT_YACC;
        YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 150 "scan-gram.l"
-return COLON;
+#line 151 "scan-gram.l"
+return EQUAL;
        YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 151 "scan-gram.l"
-return PIPE;
+#line 152 "scan-gram.l"
+return COLON;
        YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 152 "scan-gram.l"
-return SEMICOLON;
+#line 153 "scan-gram.l"
+return PIPE;
        YY_BREAK
 case 32:
 YY_RULE_SETUP
 #line 154 "scan-gram.l"
-YY_LINES; YY_STEP;
+return SEMICOLON;
        YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 155 "scan-gram.l"
-YY_STEP;
+#line 156 "scan-gram.l"
+YY_LINES; YY_STEP;
        YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 156 "scan-gram.l"
+#line 157 "scan-gram.l"
+YY_STEP;
+       YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 158 "scan-gram.l"
 {
     yylval->symbol = getsym (yytext, *yylloc);
     return ID;
   }
        YY_BREAK
-case 35:
+case 36:
 YY_RULE_SETUP
-#line 161 "scan-gram.l"
+#line 163 "scan-gram.l"
 yylval->integer = strtol (yytext, 0, 10); return INT;
        YY_BREAK
 /* Characters.  We don't check there is only one.  */
-case 36:
+case 37:
 YY_RULE_SETUP
-#line 164 "scan-gram.l"
+#line 166 "scan-gram.l"
 YY_OBS_GROW; yy_push_state (SC_ESCAPED_CHARACTER);
        YY_BREAK
 /* Strings. */
-case 37:
+case 38:
 YY_RULE_SETUP
-#line 167 "scan-gram.l"
+#line 169 "scan-gram.l"
 YY_OBS_GROW; yy_push_state (SC_ESCAPED_STRING);
        YY_BREAK
 /* Comments. */
-case 38:
+case 39:
 YY_RULE_SETUP
-#line 170 "scan-gram.l"
+#line 172 "scan-gram.l"
 yy_push_state (SC_COMMENT);
        YY_BREAK
-case 39:
+case 40:
 YY_RULE_SETUP
-#line 171 "scan-gram.l"
+#line 173 "scan-gram.l"
 YY_STEP;
        YY_BREAK
 /* Prologue. */
-case 40:
+case 41:
 YY_RULE_SETUP
-#line 174 "scan-gram.l"
+#line 176 "scan-gram.l"
 yy_push_state (SC_PROLOGUE);
        YY_BREAK
 /* Code in between braces.  */
-case 41:
+case 42:
 YY_RULE_SETUP
-#line 177 "scan-gram.l"
+#line 179 "scan-gram.l"
 YY_OBS_GROW; ++braces_level; yy_push_state (SC_BRACED_CODE);
        YY_BREAK
 /* A type. */
-case 42:
+case 43:
 YY_RULE_SETUP
-#line 180 "scan-gram.l"
+#line 182 "scan-gram.l"
 {
     obstack_grow (&string_obstack, yytext + 1, yyleng - 2);
     YY_OBS_FINISH;
@@ -1314,18 +1323,18 @@ YY_RULE_SETUP
     return TYPE;
   }
        YY_BREAK
-case 43:
+case 44:
 YY_RULE_SETUP
-#line 188 "scan-gram.l"
+#line 190 "scan-gram.l"
 {
     if (++percent_percent_count == 2)
       yy_push_state (SC_EPILOGUE);
     return PERCENT_PERCENT;
   }
        YY_BREAK
-case 44:
+case 45:
 YY_RULE_SETUP
-#line 194 "scan-gram.l"
+#line 196 "scan-gram.l"
 {
     LOCATION_PRINT (stderr, *yylloc);
     fprintf (stderr, ": invalid character: `%c'\n", *yytext);
@@ -1340,14 +1349,14 @@ YY_RULE_SETUP
   `------------------------------------------------------------*/
 
 
-case 45:
+case 46:
 YY_RULE_SETUP
-#line 210 "scan-gram.l"
+#line 212 "scan-gram.l"
 if (YY_START != SC_COMMENT) obstack_sgrow (&string_obstack, "@<:@");
        YY_BREAK
-case 46:
+case 47:
 YY_RULE_SETUP
-#line 211 "scan-gram.l"
+#line 213 "scan-gram.l"
 if (YY_START != SC_COMMENT) obstack_sgrow (&string_obstack, "@:>@");
        YY_BREAK
 
@@ -1356,9 +1365,9 @@ if (YY_START != SC_COMMENT) obstack_sgrow (&string_obstack, "@:>@");
   `-----------------------------------------------------------*/
 
 
-case 47:
+case 48:
 YY_RULE_SETUP
-#line 222 "scan-gram.l"
+#line 224 "scan-gram.l"
 { /* End of the comment. */
     if (yy_top_state () == INITIAL)
       {
@@ -1371,23 +1380,23 @@ YY_RULE_SETUP
     yy_pop_state ();
   }
        YY_BREAK
-case 48:
+case 49:
 YY_RULE_SETUP
-#line 234 "scan-gram.l"
+#line 236 "scan-gram.l"
 if (yy_top_state () != INITIAL) YY_OBS_GROW;
        YY_BREAK
-case 49:
+case 50:
 YY_RULE_SETUP
-#line 235 "scan-gram.l"
+#line 237 "scan-gram.l"
 if (yy_top_state () != INITIAL) YY_OBS_GROW; YY_LINES;
        YY_BREAK
-case 50:
+case 51:
 YY_RULE_SETUP
-#line 236 "scan-gram.l"
+#line 238 "scan-gram.l"
 /* Stray `*'. */if (yy_top_state () != INITIAL) YY_OBS_GROW;
        YY_BREAK
 case YY_STATE_EOF(SC_COMMENT):
-#line 238 "scan-gram.l"
+#line 240 "scan-gram.l"
 {
     LOCATION_PRINT (stderr, *yylloc);
     fprintf (stderr, ": unexpected end of file in a comment\n");
@@ -1401,9 +1410,9 @@ case YY_STATE_EOF(SC_COMMENT):
   `----------------------------------------------------------------*/
 
 
-case 51:
+case 52:
 YY_RULE_SETUP
-#line 253 "scan-gram.l"
+#line 255 "scan-gram.l"
 {
     assert (yy_top_state () == INITIAL);
     YY_OBS_GROW;
@@ -1413,18 +1422,18 @@ YY_RULE_SETUP
     return STRING;
   }
        YY_BREAK
-case 52:
+case 53:
 YY_RULE_SETUP
-#line 262 "scan-gram.l"
+#line 264 "scan-gram.l"
 YY_OBS_GROW;
        YY_BREAK
-case 53:
+case 54:
 YY_RULE_SETUP
-#line 264 "scan-gram.l"
+#line 266 "scan-gram.l"
 obstack_1grow (&string_obstack, '\n'); YY_LINES;
        YY_BREAK
 case YY_STATE_EOF(SC_ESCAPED_STRING):
-#line 266 "scan-gram.l"
+#line 268 "scan-gram.l"
 {
     LOCATION_PRINT (stderr, *yylloc);
     fprintf (stderr, ": unexpected end of file in a string\n");
@@ -1442,9 +1451,9 @@ case YY_STATE_EOF(SC_ESCAPED_STRING):
   `---------------------------------------------------------------*/
 
 
-case 54:
+case 55:
 YY_RULE_SETUP
-#line 284 "scan-gram.l"
+#line 286 "scan-gram.l"
 {
     YY_OBS_GROW;
     assert (yy_top_state () == INITIAL);
@@ -1459,18 +1468,18 @@ YY_RULE_SETUP
     }
   }
        YY_BREAK
-case 55:
+case 56:
 YY_RULE_SETUP
-#line 298 "scan-gram.l"
+#line 300 "scan-gram.l"
 YY_OBS_GROW;
        YY_BREAK
-case 56:
+case 57:
 YY_RULE_SETUP
-#line 300 "scan-gram.l"
+#line 302 "scan-gram.l"
 obstack_1grow (&string_obstack, '\n'); YY_LINES;
        YY_BREAK
 case YY_STATE_EOF(SC_ESCAPED_CHARACTER):
-#line 302 "scan-gram.l"
+#line 304 "scan-gram.l"
 {
     LOCATION_PRINT (stderr, *yylloc);
     fprintf (stderr, ": unexpected end of file in a character\n");
@@ -1487,9 +1496,9 @@ case YY_STATE_EOF(SC_ESCAPED_CHARACTER):
   `----------------------------*/
 
 
-case 57:
+case 58:
 YY_RULE_SETUP
-#line 320 "scan-gram.l"
+#line 322 "scan-gram.l"
 {
     long c = strtol (yytext + 1, 0, 8);
     if (c > 255)
@@ -1502,56 +1511,56 @@ YY_RULE_SETUP
       obstack_1grow (&string_obstack, c);
   }
        YY_BREAK
-case 58:
+case 59:
 YY_RULE_SETUP
-#line 332 "scan-gram.l"
+#line 334 "scan-gram.l"
 {
     obstack_1grow (&string_obstack, strtol (yytext + 2, 0, 16));
   }
        YY_BREAK
-case 59:
+case 60:
 YY_RULE_SETUP
-#line 336 "scan-gram.l"
+#line 338 "scan-gram.l"
 obstack_1grow (&string_obstack, '\a');
        YY_BREAK
-case 60:
+case 61:
 YY_RULE_SETUP
-#line 337 "scan-gram.l"
+#line 339 "scan-gram.l"
 obstack_1grow (&string_obstack, '\b');
        YY_BREAK
-case 61:
+case 62:
 YY_RULE_SETUP
-#line 338 "scan-gram.l"
+#line 340 "scan-gram.l"
 obstack_1grow (&string_obstack, '\f');
        YY_BREAK
-case 62:
+case 63:
 YY_RULE_SETUP
-#line 339 "scan-gram.l"
+#line 341 "scan-gram.l"
 obstack_1grow (&string_obstack, '\n');
        YY_BREAK
-case 63:
+case 64:
 YY_RULE_SETUP
-#line 340 "scan-gram.l"
+#line 342 "scan-gram.l"
 obstack_1grow (&string_obstack, '\r');
        YY_BREAK
-case 64:
+case 65:
 YY_RULE_SETUP
-#line 341 "scan-gram.l"
+#line 343 "scan-gram.l"
 obstack_1grow (&string_obstack, '\t');
        YY_BREAK
-case 65:
+case 66:
 YY_RULE_SETUP
-#line 342 "scan-gram.l"
+#line 344 "scan-gram.l"
 obstack_1grow (&string_obstack, '\v');
        YY_BREAK
-case 66:
+case 67:
 YY_RULE_SETUP
-#line 343 "scan-gram.l"
+#line 345 "scan-gram.l"
 obstack_1grow (&string_obstack, yytext[1]);
        YY_BREAK
-case 67:
+case 68:
 YY_RULE_SETUP
-#line 344 "scan-gram.l"
+#line 346 "scan-gram.l"
 {
     LOCATION_PRINT (stderr, *yylloc);
     fprintf (stderr, ": unrecognized escape: %s\n", yytext);
@@ -1565,32 +1574,32 @@ YY_RULE_SETUP
   `----------------------------------------------------------*/
 
 
-case 68:
+case 69:
 YY_RULE_SETUP
-#line 359 "scan-gram.l"
+#line 361 "scan-gram.l"
 {
     YY_OBS_GROW;
     assert (yy_top_state () != INITIAL);
     yy_pop_state ();
   }
        YY_BREAK
-case 69:
-YY_RULE_SETUP
-#line 365 "scan-gram.l"
-YY_OBS_GROW;
-       YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 366 "scan-gram.l"
+#line 367 "scan-gram.l"
 YY_OBS_GROW;
        YY_BREAK
 case 71:
 YY_RULE_SETUP
 #line 368 "scan-gram.l"
+YY_OBS_GROW;
+       YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 370 "scan-gram.l"
 YY_OBS_GROW; YY_LINES;
        YY_BREAK
 case YY_STATE_EOF(SC_CHARACTER):
-#line 370 "scan-gram.l"
+#line 372 "scan-gram.l"
 {
     LOCATION_PRINT (stderr, *yylloc);
     fprintf (stderr, ": unexpected end of file in a character\n");
@@ -1605,32 +1614,32 @@ case YY_STATE_EOF(SC_CHARACTER):
   `----------------------------------------------------------------*/
 
 
-case 72:
+case 73:
 YY_RULE_SETUP
-#line 386 "scan-gram.l"
+#line 388 "scan-gram.l"
 {
     assert (yy_top_state () != INITIAL);
     YY_OBS_GROW;
     yy_pop_state ();
   }
        YY_BREAK
-case 73:
-YY_RULE_SETUP
-#line 392 "scan-gram.l"
-YY_OBS_GROW;
-       YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 393 "scan-gram.l"
+#line 394 "scan-gram.l"
 YY_OBS_GROW;
        YY_BREAK
 case 75:
 YY_RULE_SETUP
 #line 395 "scan-gram.l"
+YY_OBS_GROW;
+       YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 397 "scan-gram.l"
 YY_OBS_GROW; YY_LINES;
        YY_BREAK
 case YY_STATE_EOF(SC_STRING):
-#line 397 "scan-gram.l"
+#line 399 "scan-gram.l"
 {
     LOCATION_PRINT (stderr, *yylloc);
     fprintf (stderr, ": unexpected end of file in a string\n");
@@ -1645,26 +1654,26 @@ case YY_STATE_EOF(SC_STRING):
 
 
 /* Characters.  We don't check there is only one.  */
-case 76:
+case 77:
 YY_RULE_SETUP
-#line 413 "scan-gram.l"
+#line 415 "scan-gram.l"
 YY_OBS_GROW; yy_push_state (SC_CHARACTER);
        YY_BREAK
 /* Strings. */
-case 77:
+case 78:
 YY_RULE_SETUP
-#line 416 "scan-gram.l"
+#line 418 "scan-gram.l"
 YY_OBS_GROW; yy_push_state (SC_STRING);
        YY_BREAK
 /* Comments. */
-case 78:
+case 79:
 YY_RULE_SETUP
-#line 419 "scan-gram.l"
+#line 421 "scan-gram.l"
 YY_OBS_GROW; yy_push_state (SC_COMMENT);
        YY_BREAK
-case 79:
+case 80:
 YY_RULE_SETUP
-#line 420 "scan-gram.l"
+#line 422 "scan-gram.l"
 YY_OBS_GROW;
        YY_BREAK
 
@@ -1674,9 +1683,9 @@ YY_OBS_GROW;
   `---------------------------------------------------------------*/
 
 
-case 80:
+case 81:
 YY_RULE_SETUP
-#line 431 "scan-gram.l"
+#line 433 "scan-gram.l"
 {
     YY_OBS_GROW;
     if (--braces_level == 0)
@@ -1688,39 +1697,50 @@ YY_RULE_SETUP
       }
   }
        YY_BREAK
-case 81:
-YY_RULE_SETUP
-#line 442 "scan-gram.l"
-YY_OBS_GROW; braces_level++;
-       YY_BREAK
 case 82:
 YY_RULE_SETUP
 #line 444 "scan-gram.l"
-{ handle_dollar (yytext, *yylloc); }
+YY_OBS_GROW; braces_level++;
        YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 445 "scan-gram.l"
-{ handle_at (yytext); }
+#line 446 "scan-gram.l"
+{
+    switch (current_braced_code)
+      {
+      case action_braced_code:
+       handle_action_dollar (yytext, *yylloc);
+       break;
+
+      case destructor_braced_code:
+       handle_destructor_dollar (yytext, *yylloc);
+       break;
+      }
+  }
        YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 447 "scan-gram.l"
-YY_OBS_GROW;
+#line 458 "scan-gram.l"
+{ handle_at (yytext); }
        YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 448 "scan-gram.l"
+#line 460 "scan-gram.l"
+YY_OBS_GROW;
+       YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 461 "scan-gram.l"
 YY_OBS_GROW; YY_LINES;
        YY_BREAK
 /* A lose $, or /, or etc. */
-case 86:
+case 87:
 YY_RULE_SETUP
-#line 451 "scan-gram.l"
+#line 464 "scan-gram.l"
 YY_OBS_GROW;
        YY_BREAK
 case YY_STATE_EOF(SC_BRACED_CODE):
-#line 453 "scan-gram.l"
+#line 466 "scan-gram.l"
 {
     LOCATION_PRINT (stderr, *yylloc);
     fprintf (stderr, ": unexpected end of file in a braced code\n");
@@ -1736,9 +1756,9 @@ case YY_STATE_EOF(SC_BRACED_CODE):
   `--------------------------------------------------------------*/
 
 
-case 87:
+case 88:
 YY_RULE_SETUP
-#line 471 "scan-gram.l"
+#line 484 "scan-gram.l"
 {
     yy_pop_state ();
     YY_OBS_FINISH;
@@ -1746,23 +1766,23 @@ YY_RULE_SETUP
     return PROLOGUE;
   }
        YY_BREAK
-case 88:
+case 89:
 YY_RULE_SETUP
-#line 478 "scan-gram.l"
+#line 491 "scan-gram.l"
 YY_OBS_GROW;
        YY_BREAK
-case 89:
+case 90:
 YY_RULE_SETUP
-#line 479 "scan-gram.l"
+#line 492 "scan-gram.l"
 YY_OBS_GROW;
        YY_BREAK
-case 90:
+case 91:
 YY_RULE_SETUP
-#line 480 "scan-gram.l"
+#line 493 "scan-gram.l"
 YY_OBS_GROW; YY_LINES;
        YY_BREAK
 case YY_STATE_EOF(SC_PROLOGUE):
-#line 482 "scan-gram.l"
+#line 495 "scan-gram.l"
 {
     LOCATION_PRINT (stderr, *yylloc);
     fprintf (stderr, ": unexpected end of file in a prologue\n");
@@ -1779,13 +1799,13 @@ case YY_STATE_EOF(SC_PROLOGUE):
   `---------------------------------------------------------------*/
 
 
-case 91:
+case 92:
 YY_RULE_SETUP
-#line 501 "scan-gram.l"
+#line 514 "scan-gram.l"
 YY_OBS_GROW;
        YY_BREAK
 case YY_STATE_EOF(SC_EPILOGUE):
-#line 503 "scan-gram.l"
+#line 516 "scan-gram.l"
 {
     yy_pop_state ();
     YY_OBS_FINISH;
@@ -1794,12 +1814,12 @@ case YY_STATE_EOF(SC_EPILOGUE):
   }
        YY_BREAK
 
-case 92:
+case 93:
 YY_RULE_SETUP
-#line 512 "scan-gram.l"
+#line 525 "scan-gram.l"
 YY_FATAL_ERROR( "flex scanner jammed" );
        YY_BREAK
-#line 1803 "lex.yy.c"
+#line 1823 "lex.yy.c"
 case YY_STATE_EOF(INITIAL):
        yyterminate();
 
@@ -2091,7 +2111,7 @@ static yy_state_type yy_get_previous_state()
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 349 )
+                       if ( yy_current_state >= 357 )
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -2126,11 +2146,11 @@ yy_state_type yy_current_state;
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 349 )
+               if ( yy_current_state >= 357 )
                        yy_c = yy_meta[(unsigned int) yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 348);
+       yy_is_jam = (yy_current_state == 356);
 
        return yy_is_jam ? 0 : yy_current_state;
        }
@@ -2689,7 +2709,7 @@ int main()
        return 0;
        }
 #endif
-#line 512 "scan-gram.l"
+#line 525 "scan-gram.l"
 
 
 /*------------------------------------------------------------------.
@@ -2701,7 +2721,7 @@ int main()
 `------------------------------------------------------------------*/
 
 static void
-handle_dollar (char *cp, location_t location)
+handle_action_dollar (char *cp, location_t location)
 {
   const char *type_name = NULL;
 
@@ -2759,7 +2779,32 @@ handle_dollar (char *cp, location_t location)
     {
       char buf[] = "$c";
       buf[1] = *cp;
-      complain (_("%s is invalid"), quote (buf));
+      complain_at (location, _("%s is invalid"), quote (buf));
+    }
+}
+
+
+/*---------------------------------------------------------------.
+| CP is pointing to $$ in a destructor.  This should probably be |
+| done once the grammar completely parsed, instead of during its |
+| parsing, since that means %type must be specified before       |
+| %destructor.                                                   |
+`---------------------------------------------------------------*/
+
+static void
+handle_destructor_dollar (char *cp, location_t location)
+{
+  ++cp;
+  if (*cp == '$')
+    {
+      /* FIXME: We should find something more robust.  */
+      obstack_sgrow (&string_obstack, "b4_dollar_dollar");
+    }
+  else
+    {
+      char buf[] = "$c";
+      buf[1] = *cp;
+      complain_at (location, _("%s is invalid"), quote (buf));
     }
 }
 
index 2c80c65..61032dd 100644 (file)
@@ -80,7 +80,8 @@ scanner_last_string_free (void)
 static int braces_level = 0;
 static int percent_percent_count = 0;
 
-static void handle_dollar PARAMS ((char *cp, location_t location));
+static void handle_action_dollar PARAMS ((char *cp, location_t location));
+static void handle_destructor_dollar PARAMS ((char *cp, location_t location));
 static void handle_at PARAMS ((char *cp));
 
 %}
@@ -122,6 +123,7 @@ blanks   [ \t\f]+
   "%debug"                return PERCENT_DEBUG;
   "%define"               return PERCENT_DEFINE;
   "%defines"              return PERCENT_DEFINES;
+  "%destructor"           return PERCENT_DESTRUCTOR;
   "%error"[-_]"verbose"   return PERCENT_ERROR_VERBOSE;
   "%expect"               return PERCENT_EXPECT;
   "%file-prefix"          return PERCENT_FILE_PREFIX;
@@ -441,8 +443,19 @@ blanks   [ \t\f]+
 
   "{"                  YY_OBS_GROW; braces_level++;
 
-  "$"("<"[^>]+">")?(-?[0-9]+|"$") { handle_dollar (yytext, *yylloc); }
-  "@"(-?[0-9]+|"$")            { handle_at (yytext); }
+  "$"("<"[^>]+">")?(-?[0-9]+|"$") {
+    switch (current_braced_code)
+      {
+      case action_braced_code:
+       handle_action_dollar (yytext, *yylloc);
+       break;
+
+      case destructor_braced_code:
+       handle_destructor_dollar (yytext, *yylloc);
+       break;
+      }
+  }
+  "@"(-?[0-9]+|"$")               { handle_at (yytext); }
 
   [^$@\[\]/\'\"\{\}\n\r]+ YY_OBS_GROW;
   {eols}       YY_OBS_GROW; YY_LINES;
@@ -520,7 +533,7 @@ blanks   [ \t\f]+
 `------------------------------------------------------------------*/
 
 static void
-handle_dollar (char *cp, location_t location)
+handle_action_dollar (char *cp, location_t location)
 {
   const char *type_name = NULL;
 
@@ -578,7 +591,32 @@ handle_dollar (char *cp, location_t location)
     {
       char buf[] = "$c";
       buf[1] = *cp;
-      complain (_("%s is invalid"), quote (buf));
+      complain_at (location, _("%s is invalid"), quote (buf));
+    }
+}
+
+
+/*---------------------------------------------------------------.
+| CP is pointing to $$ in a destructor.  This should probably be |
+| done once the grammar completely parsed, instead of during its |
+| parsing, since that means %type must be specified before       |
+| %destructor.                                                   |
+`---------------------------------------------------------------*/
+
+static void
+handle_destructor_dollar (char *cp, location_t location)
+{
+  ++cp;
+  if (*cp == '$')
+    {
+      /* FIXME: We should find something more robust.  */
+      obstack_sgrow (&string_obstack, "b4_dollar_dollar");
+    }
+  else
+    {
+      char buf[] = "$c";
+      buf[1] = *cp;
+      complain_at (location, _("%s is invalid"), quote (buf));
     }
 }
 
index bdb965d..d86207c 100644 (file)
@@ -19,6 +19,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include "system.h"
+#include "complain.h"
 #include "symlist.h"
 
 
index d605687..0d8e1f4 100644 (file)
@@ -48,6 +48,7 @@ symbol_new (const char *tag, location_t location)
 
   res->tag = xstrdup (tag);
   res->type_name = NULL;
+  res->destructor = NULL;
   res->location = location;
   res->number = NUMBER_UNDEFINED;
   res->prec = 0;
@@ -114,6 +115,25 @@ symbol_type_set (symbol_t *symbol, location_t location, char *type_name)
 }
 
 
+/*-------------------------------------------------------------------.
+| Set the DESTRUCTOR associated to SYMBOL.  Does nothing if passed 0 |
+| as DESTRUCTOR.                                                      |
+`-------------------------------------------------------------------*/
+
+void
+symbol_destructor_set (symbol_t *symbol, location_t location, char *destructor)
+{
+  if (destructor)
+    {
+      if (symbol->destructor)
+       complain_at (location,
+                    _("destructor redeclaration for %s"),
+                    symbol_tag_get (symbol));
+      symbol->destructor = destructor;
+    }
+}
+
+
 /*------------------------------------------------------------------.
 | Set the PRECEDENCE associated to SYMBOL.  Does nothing if invoked |
 | with UNDEF_ASSOC as ASSOC.                                        |
index 6df5455..54ff80f 100644 (file)
@@ -57,8 +57,9 @@ struct symbol_s
   /* The key, name of the symbol.  */
   char *tag;
 
-  /* Its %type.  */
+  /* Its %type and associated destructor.  */
   char *type_name;
+  char *destructor;
 
   /* The location of its first occurence.  */
   location_t location;
@@ -110,6 +111,10 @@ void symbol_make_alias PARAMS ((symbol_t *symbol, symbol_t *symval));
 void symbol_type_set PARAMS ((symbol_t *symbol, location_t location,
                              char *type_name));
 
+/* Set the DESTRUCTOR associated to SYMBOL.  */
+void symbol_destructor_set PARAMS ((symbol_t *symbol, location_t location,
+                                   char *destructor));
+
 /* Set the PRECEDENCE associated to SYMBOL.  Ensures that SYMBOL is a
    terminal.  Does nothing if invoked with UNDEF_ASSOC as ASSOC.  */
 void symbol_precedence_set PARAMS ((symbol_t *symbol, location_t location,
index ed56174..2c61487 100644 (file)
@@ -88,8 +88,6 @@ AT_CLEANUP
 
 AT_SETUP([Exotic Dollars])
 
-# Make sure complex $n work.
-
 AT_DATA([[input.y]],
 [[%{
 # include <stdio.h>
@@ -152,3 +150,133 @@ AT_CHECK([./input], 0,
 ]])
 
 AT_CLEANUP
+
+
+
+## ------------- ##
+## Destructors.  ##
+## ------------- ##
+
+AT_SETUP([Destructors])
+
+# Make sure complex $n work.
+
+AT_DATA([[input.y]],
+[[%{
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#define YYERROR_VERBOSE 1
+#define YYDEBUG 1
+/* #define YYPRINT yyprint */
+
+static int yylex (void);
+static void yyerror (const char *msg);
+static void yyprint (FILE *out, int toknum, int tokval);
+%}
+
+%union
+{
+  int ival;
+}
+%type <ival> thing 'x'
+%destructor { printf ("Freeing thing %d\n", $$); } thing
+%destructor { printf ("Freeing 'x' %d\n", $$); } 'x'
+
+%%
+input:
+  /* Nothing. */
+| input line
+;
+
+line:
+  thing thing thing ';'
+    { printf ("input: thing(%d) thing(%d) thing(%d) ';'\n", $1, $2, $3); }
+| thing thing ';'
+    { printf ("input: thing(%d) thing(%d) ';'\n", $1, $2); }
+| thing ';'
+    { printf ("input: thing(%d) ';'\n", $1); }
+| error ';'
+    { printf ("input: error ';'\n"); }
+;
+
+thing:
+  'x'  { printf ("thing: 'x' (%d)\n", $1); $$ = $1; }
+;
+%%
+static int
+yylex (void)
+{
+  static const int input[] =
+    {
+      'x', 'x', 'x', 'x', 'x', 'x', ';',
+      'x', 'x', ';',
+      'x', ';',
+      'x', 'y', ';'
+    };
+  static int counter = 0;
+
+  if (counter < (sizeof(input) / sizeof (input[0])))
+    {
+       yylval.ival = counter;
+       return input[counter++];
+    }
+  else
+    return EOF;
+}
+
+static void
+yyerror (const char *msg)
+{
+  fprintf (stdout, "%s\n", msg);
+}
+
+static void
+yyprint (FILE *out, int toknum, int tokval)
+{
+  if (0 < toknum && toknum < 256)
+    fprintf (out, " = %d", tokval);
+}
+
+int
+main (void)
+{
+  yydebug = !!getenv ("YYDEBUG");
+  if (yyparse ())
+    {
+      fprintf (stdout, "Parsing FAILED.\n");
+      exit (1);
+    }
+  fprintf (stdout, "Successful parse.\n");
+  return 0;
+}
+]])
+
+AT_CHECK([bison input.y -d -v -o input.c])
+AT_CHECK([$CC $CFLAGS $CPPFLAGS input.c -o input], 0, [], [ignore])
+AT_CHECK([./input], 0,
+[[thing: 'x' (0)
+thing: 'x' (1)
+thing: 'x' (2)
+parse error, unexpected 'x', expecting ';'
+Freeing thing 2
+Freeing thing 1
+Freeing thing 0
+Freeing 'x' 3
+Freeing 'x' 4
+Freeing 'x' 5
+input: error ';'
+thing: 'x' (7)
+thing: 'x' (8)
+input: thing(7) thing(8) ';'
+thing: 'x' (10)
+input: thing(10) ';'
+thing: 'x' (12)
+parse error, unexpected $undefined., expecting 'x' or ';'
+Freeing thing 12
+input: error ';'
+Successful parse.
+]])
+
+AT_CLEANUP
index 28e16f9..3b2e137 100644 (file)
@@ -354,7 +354,16 @@ m4_bmatch([$1], [--debug],
 # Normalize the observed and expected error messages, depending upon the
 # options.
 # 1. Remove the traces from observed.
-egrep -v '^((Start|Enter|Read|Reduc|Shift)ing|state|Error:|Next|Discarding) ' stderr >at-stderr
+sed '/^Starting/d
+/^Entering/d
+/^Reading/d
+/^Reducing/d
+/^Shifting/d
+/^state/d
+/^Error:/d
+/^Next/d
+/^Discarding/d
+/^yydestructor:/d' stderr >at-stderr
 mv at-stderr stderr
 # 2. Create the reference error message.
 AT_DATA([[expout]],
@@ -406,18 +415,18 @@ _AT_CHECK_CALC([$1],
 (2^2)^3 = 64], [486])
 
 # Some parse errors.
-_AT_CHECK_CALC_ERROR([$1], [0 0], [11],
+_AT_CHECK_CALC_ERROR([$1], [0 0], [12],
                      [1.3-1.4: parse error, unexpected "number"])
-_AT_CHECK_CALC_ERROR([$1], [1//2], [15],
+_AT_CHECK_CALC_ERROR([$1], [1//2], [17],
                      [1.3-1.4: parse error, unexpected '/', expecting "number" or '-' or '('])
 _AT_CHECK_CALC_ERROR([$1], [error], [4],
                      [1.1-1.2: parse error, unexpected $undefined., expecting "number" or '-' or '\n' or '('])
-_AT_CHECK_CALC_ERROR([$1], [1 = 2 = 3], [22],
+_AT_CHECK_CALC_ERROR([$1], [1 = 2 = 3], [25],
                      [1.7-1.8: parse error, unexpected '='])
 _AT_CHECK_CALC_ERROR([$1],
                      [
 +1],
-                     [14],
+                     [15],
                      [2.1-2.2: parse error, unexpected '+'])
 # Exercise error messages with EOF: work on an empty file.
 _AT_CHECK_CALC_ERROR([$1],
@@ -430,7 +439,7 @@ _AT_CHECK_CALC_ERROR([$1],
 # associated to `error'.
 _AT_CHECK_CALC_ERROR([$1],
                      [(1 ++ 2) + (0 0) = 1],
-                     [82],
+                     [91],
 [1.5-1.6: parse error, unexpected '+', expecting "number" or '-' or '('
 1.15-1.16: parse error, unexpected "number"
 calc: error: 0 != 1])