
/* Grammar implementation */

#include "Python.h"
#include "pgenheaders.h"

#include <ctype.h>

#include "token.h"
#include "grammar.h"

#ifdef RISCOS
#include <unixlib.h>
#endif

extern int Py_DebugFlag;

grammar *
newgrammar(int start)
{
	grammar *g;
	
	g = (grammar *)PyObject_MALLOC(sizeof(grammar));
	if (g == NULL)
		Py_FatalError("no mem for new grammar");
	g->g_ndfas = 0;
	g->g_dfa = NULL;
	g->g_start = start;
	g->g_ll.ll_nlabels = 0;
	g->g_ll.ll_label = NULL;
	g->g_accel = 0;
	return g;
}

dfa *
adddfa(grammar *g, int type, char *name)
{
	dfa *d;
	
	g->g_dfa = (dfa *)PyObject_REALLOC(g->g_dfa, 
                                            sizeof(dfa) * (g->g_ndfas + 1));
	if (g->g_dfa == NULL)
		Py_FatalError("no mem to resize dfa in adddfa");
	d = &g->g_dfa[g->g_ndfas++];
	d->d_type = type;
	d->d_name = strdup(name);
	d->d_nstates = 0;
	d->d_state = NULL;
	d->d_initial = -1;
	d->d_first = NULL;
	return d; /* Only use while fresh! */
}

int
addstate(dfa *d)
{
	state *s;
	
	d->d_state = (state *)PyObject_REALLOC(d->d_state,
				      sizeof(state) * (d->d_nstates + 1));
	if (d->d_state == NULL)
		Py_FatalError("no mem to resize state in addstate");
	s = &d->d_state[d->d_nstates++];
	s->s_narcs = 0;
	s->s_arc = NULL;
	s->s_lower = 0;
	s->s_upper = 0;
	s->s_accel = NULL;
	s->s_accept = 0;
	return s - d->d_state;
}

void
addarc(dfa *d, int from, int to, int lbl)
{
	state *s;
	arc *a;
	
	assert(0 <= from && from < d->d_nstates);
	assert(0 <= to && to < d->d_nstates);
	
	s = &d->d_state[from];
	s->s_arc = (arc *)PyObject_REALLOC(s->s_arc, sizeof(arc) * (s->s_narcs + 1));
	if (s->s_arc == NULL)
		Py_FatalError("no mem to resize arc list in addarc");
	a = &s->s_arc[s->s_narcs++];
	a->a_lbl = lbl;
	a->a_arrow = to;
}

int
addlabel(labellist *ll, int type, char *str)
{
	int i;
	label *lb;
	
	for (i = 0; i < ll->ll_nlabels; i++) {
		if (ll->ll_label[i].lb_type == type &&
			strcmp(ll->ll_label[i].lb_str, str) == 0)
			return i;
	}
	ll->ll_label = (label *)PyObject_REALLOC(ll->ll_label,
					sizeof(label) * (ll->ll_nlabels + 1));
	if (ll->ll_label == NULL)
		Py_FatalError("no mem to resize labellist in addlabel");
	lb = &ll->ll_label[ll->ll_nlabels++];
	lb->lb_type = type;
	lb->lb_str = strdup(str);
	if (Py_DebugFlag)
		printf("Label @ %8p, %d: %s\n", ll, ll->ll_nlabels,
		       PyGrammar_LabelRepr(lb));
	return lb - ll->ll_label;
}

/* Same, but rather dies than adds */

int
findlabel(labellist *ll, int type, char *str)
{
	int i;
	
	for (i = 0; i < ll->ll_nlabels; i++) {
		if (ll->ll_label[i].lb_type == type /*&&
			strcmp(ll->ll_label[i].lb_str, str) == 0*/)
			return i;
	}
	fprintf(stderr, "Label %d/'%s' not found\n", type, str);
	Py_FatalError("grammar.c:findlabel()");
	return 0; /* Make gcc -Wall happy */
}

/* Forward */
static void translabel(grammar *, label *);

void
translatelabels(grammar *g)
{
	int i;

#ifdef Py_DEBUG
	printf("Translating labels ...\n");
#endif
	/* Don't translate EMPTY */
	for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
		translabel(g, &g->g_ll.ll_label[i]);
}

static void
translabel(grammar *g, label *lb)
{
	int i;
	
	if (Py_DebugFlag)
		printf("Translating label %s ...\n", PyGrammar_LabelRepr(lb));
	
	if (lb->lb_type == NAME) {
		for (i = 0; i < g->g_ndfas; i++) {
			if (strcmp(lb->lb_str, g->g_dfa[i].d_name) == 0) {
				if (Py_DebugFlag)
					printf(
					    "Label %s is non-terminal %d.\n",
					    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;
			}
		}
		for (i = 0; i < (int)N_TOKENS; i++) {
			if (strcmp(lb->lb_str, _PyParser_TokenNames[i]) == 0) {
				if (Py_DebugFlag)
					printf("Label %s is terminal %d.\n",
						lb->lb_str, i);
				lb->lb_type = i;
				free(lb->lb_str);
				lb->lb_str = NULL;
				return;
			}
		}
		printf("Can't translate NAME label '%s'\n", lb->lb_str);
		return;
	}
	
	if (lb->lb_type == STRING) {
		if (isalpha(Py_CHARMASK(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;
			src = lb->lb_str + 1;
			p = strchr(src, '\'');
			if (p)
				name_len = p - src;
			else
				name_len = strlen(src);
			dest = (char *)malloc(name_len + 1);
			if (!dest) {
				printf("Can't alloc dest '%s'\n", src);
				return;
			}
			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
				printf("Unknown OP label %s\n",
					lb->lb_str);
		}
		else if (lb->lb_str[2] && lb->lb_str[3] == lb->lb_str[0]) {
			int type = (int) PyToken_TwoChars(lb->lb_str[1],
						   lb->lb_str[2]);
			if (type != OP) {
				lb->lb_type = type;
				free(lb->lb_str);
				lb->lb_str = NULL;
			}
			else
				printf("Unknown OP label %s\n",
					lb->lb_str);
		}
		else if (lb->lb_str[2] && lb->lb_str[3] && lb->lb_str[4] == lb->lb_str[0]) {
			int type = (int) PyToken_ThreeChars(lb->lb_str[1],
							    lb->lb_str[2],
							    lb->lb_str[3]);
			if (type != OP) {
				lb->lb_type = type;
				free(lb->lb_str);
				lb->lb_str = NULL;
			}
			else
				printf("Unknown OP label %s\n",
					lb->lb_str);
		}
		else
			printf("Can't translate STRING label %s\n",
				lb->lb_str);
	}
	else
		printf("Can't translate label '%s'\n",
		       PyGrammar_LabelRepr(lb));
}
