Changes from Jonathan Riehl to allow his pgen extension (PEP 269) to
work.  This includes some more code that used to be part of pgen in
the main parser; I'm okay with that.  I'll see if the Windows build
needs work next.
diff --git a/Include/parsetok.h b/Include/parsetok.h
index 99a79b7..b788566 100644
--- a/Include/parsetok.h
+++ b/Include/parsetok.h
@@ -38,6 +38,10 @@
 					      const char *,
 					      grammar *, int,
                                               perrdetail *, int);
+
+/* Note that he following function is defined in pythonrun.c not parsetok.c. */
+PyAPI_FUNC(void) PyParser_SetError(perrdetail *);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/Include/pgen.h b/Include/pgen.h
new file mode 100644
index 0000000..8a325ed
--- /dev/null
+++ b/Include/pgen.h
@@ -0,0 +1,18 @@
+#ifndef Py_PGEN_H
+#define Py_PGEN_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Parser generator interface */
+
+extern grammar *meta_grammar(void);
+
+struct _node;
+extern grammar *pgen(struct _node *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_PGEN_H */
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 5313030..d461346 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -194,7 +194,10 @@
 		Parser/parser.o \
 		Parser/parsetok.o \
 		Parser/bitset.o \
-		Parser/metagrammar.o
+		Parser/metagrammar.o \
+		Parser/firstsets.o \
+		Parser/grammar.o \
+		Parser/pgen.o
 
 PARSER_OBJS=	$(POBJS) Parser/myreadline.o Parser/tokenizer.o
 
@@ -202,9 +205,6 @@
 		Objects/obmalloc.o \
 		Python/mysnprintf.o \
 		Parser/tokenizer_pgen.o \
-		Parser/firstsets.o \
-		Parser/grammar.o \
-		Parser/pgen.o \
 		Parser/printgrammar.o \
 		Parser/pgenmain.o
 
diff --git a/Parser/grammar.c b/Parser/grammar.c
index 2cc15b58..1f01562 100644
--- a/Parser/grammar.c
+++ b/Parser/grammar.c
@@ -38,7 +38,7 @@
 		Py_FatalError("no mem to resize dfa in adddfa");
 	d = &g->g_dfa[g->g_ndfas++];
 	d->d_type = type;
-	d->d_name = name;
+	d->d_name = strdup(name);
 	d->d_nstates = 0;
 	d->d_state = NULL;
 	d->d_initial = -1;
@@ -98,7 +98,10 @@
 		Py_FatalError("no mem to resize labellist in addlabel");
 	lb = &ll->ll_label[ll->ll_nlabels++];
 	lb->lb_type = type;
-	lb->lb_str = str; /* XXX strdup(str) ??? */
+	lb->lb_str = strdup(str);
+	if (Py_DebugFlag)
+		printf("Label @ %08x, %d: %s\n", (unsigned)ll, ll->ll_nlabels,
+		       PyGrammar_LabelRepr(lb));
 	return lb - ll->ll_label;
 }
 
@@ -152,6 +155,7 @@
 					    lb->lb_str,
 					    g->g_dfa[i].d_type);
 				lb->lb_type = g->g_dfa[i].d_type;
+				free(lb->lb_str);
 				lb->lb_str = NULL;
 				return;
 			}
@@ -162,6 +166,7 @@
 					printf("Label %s is terminal %d.\n",
 						lb->lb_str, i);
 				lb->lb_type = i;
+				free(lb->lb_str);
 				lb->lb_str = NULL;
 				return;
 			}
@@ -173,18 +178,29 @@
 	if (lb->lb_type == STRING) {
 		if (isalpha((int)(lb->lb_str[1])) || lb->lb_str[1] == '_') {
 			char *p;
+			char *src;
+			char *dest;
+			size_t name_len;
 			if (Py_DebugFlag)
 				printf("Label %s is a keyword\n", lb->lb_str);
 			lb->lb_type = NAME;
-			lb->lb_str++;
-			p = strchr(lb->lb_str, '\'');
+			src = lb->lb_str + 1;
+			p = strchr(src, '\'');
 			if (p)
-				*p = '\0';
+				name_len = p - src;
+			else
+				name_len = strlen(src);
+			dest = malloc(name_len + 1);
+			strncpy(dest, src, name_len);
+			dest[name_len] = '\0';
+			free(lb->lb_str);
+			lb->lb_str = dest;
 		}
 		else if (lb->lb_str[2] == lb->lb_str[0]) {
 			int type = (int) PyToken_OneChar(lb->lb_str[1]);
 			if (type != OP) {
 				lb->lb_type = type;
+				free(lb->lb_str);
 				lb->lb_str = NULL;
 			}
 			else
@@ -196,6 +212,7 @@
 						   lb->lb_str[2]);
 			if (type != OP) {
 				lb->lb_type = type;
+				free(lb->lb_str);
 				lb->lb_str = NULL;
 			}
 			else
@@ -208,6 +225,7 @@
 							    lb->lb_str[3]);
 			if (type != OP) {
 				lb->lb_type = type;
+				free(lb->lb_str);
 				lb->lb_str = NULL;
 			}
 			else
diff --git a/Parser/metagrammar.c b/Parser/metagrammar.c
index ae67eb1..b61bc6d 100644
--- a/Parser/metagrammar.c
+++ b/Parser/metagrammar.c
@@ -151,3 +151,9 @@
 {
 	return &_PyParser_Grammar;
 }
+
+grammar *
+Py_meta_grammar(void)
+{
+  return meta_grammar();
+}
diff --git a/Parser/pgen.c b/Parser/pgen.c
index f3fdb46..453deb4 100644
--- a/Parser/pgen.c
+++ b/Parser/pgen.c
@@ -669,6 +669,11 @@
 	return g;
 }
 
+grammar *
+Py_pgen(node *n)
+{
+  return pgen(n);
+}
 
 /*