
/* Parser implementation */

/* For a description, see the comments at end of this file */

/* XXX To do: error recovery */

#include "pgenheaders.h"
#include "assert.h"
#include "token.h"
#include "grammar.h"
#include "node.h"
#include "parser.h"
#include "errcode.h"


#ifdef Py_DEBUG
extern int Py_DebugFlag;
#define D(x) if (!Py_DebugFlag); else x
#else
#define D(x)
#endif


/* STACK DATA TYPE */

static void s_reset(stack *);

static void
s_reset(stack *s)
{
	s->s_top = &s->s_base[MAXSTACK];
}

#define s_empty(s) ((s)->s_top == &(s)->s_base[MAXSTACK])

static int
s_push(register stack *s, dfa *d, node *parent)
{
	register stackentry *top;
	if (s->s_top == s->s_base) {
		fprintf(stderr, "s_push: parser stack overflow\n");
		return -1;
	}
	top = --s->s_top;
	top->s_dfa = d;
	top->s_parent = parent;
	top->s_state = 0;
	return 0;
}

#ifdef Py_DEBUG

static void
s_pop(register stack *s)
{
	if (s_empty(s))
		Py_FatalError("s_pop: parser stack underflow -- FATAL");
	s->s_top++;
}

#else /* !Py_DEBUG */

#define s_pop(s) (s)->s_top++

#endif


/* PARSER CREATION */

parser_state *
PyParser_New(grammar *g, int start)
{
	parser_state *ps;
	
	if (!g->g_accel)
		PyGrammar_AddAccelerators(g);
	ps = PyMem_NEW(parser_state, 1);
	if (ps == NULL)
		return NULL;
	ps->p_grammar = g;
	ps->p_tree = PyNode_New(start);
	if (ps->p_tree == NULL) {
		PyMem_DEL(ps);
		return NULL;
	}
	s_reset(&ps->p_stack);
	(void) s_push(&ps->p_stack, PyGrammar_FindDFA(g, start), ps->p_tree);
	return ps;
}

void
PyParser_Delete(parser_state *ps)
{
	/* NB If you want to save the parse tree,
	   you must set p_tree to NULL before calling delparser! */
	PyNode_Free(ps->p_tree);
	PyMem_DEL(ps);
}


/* PARSER STACK OPERATIONS */

static int
shift(register stack *s, int type, char *str, int newstate, int lineno)
{
	int err;
	assert(!s_empty(s));
	err = PyNode_AddChild(s->s_top->s_parent, type, str, lineno);
	if (err)
		return err;
	s->s_top->s_state = newstate;
	return 0;
}

static int
push(register stack *s, int type, dfa *d, int newstate, int lineno)
{
	int err;
	register node *n;
	n = s->s_top->s_parent;
	assert(!s_empty(s));
	err = PyNode_AddChild(n, type, (char *)NULL, lineno);
	if (err)
		return err;
	s->s_top->s_state = newstate;
	return s_push(s, d, CHILD(n, NCH(n)-1));
}


/* PARSER PROPER */

static int
classify(grammar *g, int type, char *str)
{
	register int n = g->g_ll.ll_nlabels;
	
	if (type == NAME) {
		register char *s = str;
		register label *l = g->g_ll.ll_label;
		register int i;
		for (i = n; i > 0; i--, l++) {
			if (l->lb_type == NAME && l->lb_str != NULL &&
					l->lb_str[0] == s[0] &&
					strcmp(l->lb_str, s) == 0) {
				D(printf("It's a keyword\n"));
				return n - i;
			}
		}
	}
	
	{
		register label *l = g->g_ll.ll_label;
		register int i;
		for (i = n; i > 0; i--, l++) {
			if (l->lb_type == type && l->lb_str == NULL) {
				D(printf("It's a token we know\n"));
				return n - i;
			}
		}
	}
	
	D(printf("Illegal token\n"));
	return -1;
}

int
PyParser_AddToken(register parser_state *ps, register int type, char *str,
	          int lineno, int *expected_ret)
{
	register int ilabel;
	int err;
	
	D(printf("Token %s/'%s' ... ", _PyParser_TokenNames[type], str));
	
	/* Find out which label this token is */
	ilabel = classify(ps->p_grammar, type, str);
	if (ilabel < 0)
		return E_SYNTAX;
	
	/* Loop until the token is shifted or an error occurred */
	for (;;) {
		/* Fetch the current dfa and state */
		register dfa *d = ps->p_stack.s_top->s_dfa;
		register state *s = &d->d_state[ps->p_stack.s_top->s_state];
		
		D(printf(" DFA '%s', state %d:",
			d->d_name, ps->p_stack.s_top->s_state));
		
		/* Check accelerator */
		if (s->s_lower <= ilabel && ilabel < s->s_upper) {
			register int x = s->s_accel[ilabel - s->s_lower];
			if (x != -1) {
				if (x & (1<<7)) {
					/* Push non-terminal */
					int nt = (x >> 8) + NT_OFFSET;
					int arrow = x & ((1<<7)-1);
					dfa *d1 = PyGrammar_FindDFA(
						ps->p_grammar, nt);
					if ((err = push(&ps->p_stack, nt, d1,
						arrow, lineno)) > 0) {
						D(printf(" MemError: push\n"));
						return err;
					}
					D(printf(" Push ...\n"));
					continue;
				}
				
				/* Shift the token */
				if ((err = shift(&ps->p_stack, type, str,
						x, lineno)) > 0) {
					D(printf(" MemError: shift.\n"));
					return err;
				}
				D(printf(" Shift.\n"));
				/* Pop while we are in an accept-only state */
				while (s = &d->d_state
						[ps->p_stack.s_top->s_state],
					s->s_accept && s->s_narcs == 1) {
					D(printf("  Direct pop.\n"));
					s_pop(&ps->p_stack);
					if (s_empty(&ps->p_stack)) {
						D(printf("  ACCEPT.\n"));
						return E_DONE;
					}
					d = ps->p_stack.s_top->s_dfa;
				}
				return E_OK;
			}
		}
		
		if (s->s_accept) {
			/* Pop this dfa and try again */
			s_pop(&ps->p_stack);
			D(printf(" Pop ...\n"));
			if (s_empty(&ps->p_stack)) {
				D(printf(" Error: bottom of stack.\n"));
				return E_SYNTAX;
			}
			continue;
		}
		
		/* Stuck, report syntax error */
		D(printf(" Error.\n"));
		if (expected_ret) {
			if (s->s_lower == s->s_upper - 1) {
				/* Only one possible expected token */
				*expected_ret = ps->p_grammar->
				    g_ll.ll_label[s->s_lower].lb_type;
			}
			else 
		        	*expected_ret = -1;
		}
		return E_SYNTAX;
	}
}


#ifdef Py_DEBUG

/* DEBUG OUTPUT */

void
dumptree(grammar *g, node *n)
{
	int i;
	
	if (n == NULL)
		printf("NIL");
	else {
		label l;
		l.lb_type = TYPE(n);
		l.lb_str = STR(n);
		printf("%s", PyGrammar_LabelRepr(&l));
		if (ISNONTERMINAL(TYPE(n))) {
			printf("(");
			for (i = 0; i < NCH(n); i++) {
				if (i > 0)
					printf(",");
				dumptree(g, CHILD(n, i));
			}
			printf(")");
		}
	}
}

void
showtree(grammar *g, node *n)
{
	int i;
	
	if (n == NULL)
		return;
	if (ISNONTERMINAL(TYPE(n))) {
		for (i = 0; i < NCH(n); i++)
			showtree(g, CHILD(n, i));
	}
	else if (ISTERMINAL(TYPE(n))) {
		printf("%s", _PyParser_TokenNames[TYPE(n)]);
		if (TYPE(n) == NUMBER || TYPE(n) == NAME)
			printf("(%s)", STR(n));
		printf(" ");
	}
	else
		printf("? ");
}

void
printtree(parser_state *ps)
{
	if (Py_DebugFlag) {
		printf("Parse tree:\n");
		dumptree(ps->p_grammar, ps->p_tree);
		printf("\n");
		printf("Tokens:\n");
		showtree(ps->p_grammar, ps->p_tree);
		printf("\n");
	}
	printf("Listing:\n");
	PyNode_ListTree(ps->p_tree);
	printf("\n");
}

#endif /* Py_DEBUG */

/*

Description
-----------

The parser's interface is different than usual: the function addtoken()
must be called for each token in the input.  This makes it possible to
turn it into an incremental parsing system later.  The parsing system
constructs a parse tree as it goes.

A parsing rule is represented as a Deterministic Finite-state Automaton
(DFA).  A node in a DFA represents a state of the parser; an arc represents
a transition.  Transitions are either labeled with terminal symbols or
with non-terminals.  When the parser decides to follow an arc labeled
with a non-terminal, it is invoked recursively with the DFA representing
the parsing rule for that as its initial state; when that DFA accepts,
the parser that invoked it continues.  The parse tree constructed by the
recursively called parser is inserted as a child in the current parse tree.

The DFA's can be constructed automatically from a more conventional
language description.  An extended LL(1) grammar (ELL(1)) is suitable.
Certain restrictions make the parser's life easier: rules that can produce
the empty string should be outlawed (there are other ways to put loops
or optional parts in the language).  To avoid the need to construct
FIRST sets, we can require that all but the last alternative of a rule
(really: arc going out of a DFA's state) must begin with a terminal
symbol.

As an example, consider this grammar:

expr:	term (OP term)*
term:	CONSTANT | '(' expr ')'

The DFA corresponding to the rule for expr is:

------->.---term-->.------->
	^          |
	|          |
	\----OP----/

The parse tree generated for the input a+b is:

(expr: (term: (NAME: a)), (OP: +), (term: (NAME: b)))

*/
