--- /dev/null
+#!/bin/sh
+touch parse-gram.y
+(cd .. && make)
+./bison -dy parse-gram.y 2>a
+mv y.tab.c b
+mv y.tab.h c
+cp a parse-gram.y.xml
+../../pyacc2.git/bootstrap_pyacc.py --defines=parse-gram.h -o parse-gram.c parse-gram.y.xml
+cp parse-gram.c parse-gram.c.orig
+patch parse-gram.c <parse-gram.c.patch1
+(cd .. && make)
+./bison -dy parse-gram.y 2>d
+mv y.tab.c e
+mv y.tab.h f
+diff --unified a d
+diff --unified b e
+diff --unified c f
--- /dev/null
+--- parse-gram.c.orig 2018-07-29 21:32:24.147899386 +1000
++++ parse-gram.c 2018-07-29 21:35:50.379904829 +1000
+@@ -1870,6 +1870,17 @@
+ yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
++ int n = ((int)(yyvsp - yyvsa) - yylen) * 2;
++ gram_piece2 = n + 1;
++ gram_piece3 = n + yylen * 2;
++ if (yylen == 0) {
++ memmove(gram_piece + n + 2, gram_piece + n, (gram_piece1 - n) * sizeof(char *));
++ gram_piece[n] = strdup("");
++ gram_piece[n + 1] = strdup("");
++ gram_piece3 = n + 2;
++ gram_piece0 += 2;
++ gram_piece1 += 2;
++ }
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ '$$ = $1'.
+@@ -2630,6 +2641,23 @@
+
+ default: break;
+ }
++ int i;
++ size_t j = 0;
++ for (i = gram_piece2; i < gram_piece3; ++i)
++ j += strlen(gram_piece[i]);
++ char *q = malloc(j + 1);
++ j = 0;
++ for (i = gram_piece2; i < gram_piece3; ++i) {
++ size_t k = strlen(gram_piece[i]);
++ memcpy(q + j, gram_piece[i], k);
++ free(gram_piece[i]);
++ j += k;
++ }
++ q[j] = 0;
++ memmove(gram_piece + gram_piece2 + 1, gram_piece + gram_piece3, (gram_piece1 - gram_piece3) * sizeof(char *));
++ gram_piece[gram_piece2] = q;
++ gram_piece0 += gram_piece2 + 1 - gram_piece3;
++ gram_piece1 += gram_piece2 + 1 - gram_piece3;
+ /* User semantic actions sometimes alter yychar, and that requires
+ that yytoken be updated with the new translation. We take the
+ approach of translating immediately before every use of yytoken.