mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			153 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/***********************************************************
 | 
						|
Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
 | 
						|
Netherlands.
 | 
						|
 | 
						|
                        All Rights Reserved
 | 
						|
 | 
						|
Permission to use, copy, modify, and distribute this software and its 
 | 
						|
documentation for any purpose and without fee is hereby granted, 
 | 
						|
provided that the above copyright notice appear in all copies and that
 | 
						|
both that copyright notice and this permission notice appear in 
 | 
						|
supporting documentation, and that the names of Stichting Mathematisch
 | 
						|
Centrum or CWI not be used in advertising or publicity pertaining to
 | 
						|
distribution of the software without specific, written prior permission.
 | 
						|
 | 
						|
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
 | 
						|
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
						|
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
 | 
						|
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
						|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
						|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 | 
						|
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 | 
						|
******************************************************************/
 | 
						|
 | 
						|
/* Parser accelerator module */
 | 
						|
 | 
						|
/* The parser as originally conceived had disappointing performance.
 | 
						|
   This module does some precomputation that speeds up the selection
 | 
						|
   of a DFA based upon a token, turning a search through an array
 | 
						|
   into a simple indexing operation.  The parser now cannot work
 | 
						|
   without the accelerators installed.  Note that the accelerators
 | 
						|
   are installed dynamically when the parser is initialized, they
 | 
						|
   are not part of the static data structure written on graminit.[ch]
 | 
						|
   by the parser generator. */
 | 
						|
 | 
						|
#include "pgenheaders.h"
 | 
						|
#include "grammar.h"
 | 
						|
#include "token.h"
 | 
						|
#include "parser.h"
 | 
						|
 | 
						|
/* Forward references */
 | 
						|
static void fixdfa PROTO((grammar *, dfa *));
 | 
						|
static void fixstate PROTO((grammar *, dfa *, state *));
 | 
						|
 | 
						|
void
 | 
						|
addaccelerators(g)
 | 
						|
	grammar *g;
 | 
						|
{
 | 
						|
	dfa *d;
 | 
						|
	int i;
 | 
						|
#ifdef DEBUG
 | 
						|
	printf("Adding parser accellerators ...\n");
 | 
						|
#endif
 | 
						|
	d = g->g_dfa;
 | 
						|
	for (i = g->g_ndfas; --i >= 0; d++)
 | 
						|
		fixdfa(g, d);
 | 
						|
	g->g_accel = 1;
 | 
						|
#ifdef DEBUG
 | 
						|
	printf("Done.\n");
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
fixdfa(g, d)
 | 
						|
	grammar *g;
 | 
						|
	dfa *d;
 | 
						|
{
 | 
						|
	state *s;
 | 
						|
	int j;
 | 
						|
	s = d->d_state;
 | 
						|
	for (j = 0; j < d->d_nstates; j++, s++)
 | 
						|
		fixstate(g, d, s);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
fixstate(g, d, s)
 | 
						|
	grammar *g;
 | 
						|
	dfa *d;
 | 
						|
	state *s;
 | 
						|
{
 | 
						|
	arc *a;
 | 
						|
	int k;
 | 
						|
	int *accel;
 | 
						|
	int nl = g->g_ll.ll_nlabels;
 | 
						|
	s->s_accept = 0;
 | 
						|
	accel = NEW(int, nl);
 | 
						|
	for (k = 0; k < nl; k++)
 | 
						|
		accel[k] = -1;
 | 
						|
	a = s->s_arc;
 | 
						|
	for (k = s->s_narcs; --k >= 0; a++) {
 | 
						|
		int lbl = a->a_lbl;
 | 
						|
		label *l = &g->g_ll.ll_label[lbl];
 | 
						|
		int type = l->lb_type;
 | 
						|
		if (a->a_arrow >= (1 << 7)) {
 | 
						|
			printf("XXX too many states!\n");
 | 
						|
			continue;
 | 
						|
		}
 | 
						|
		if (ISNONTERMINAL(type)) {
 | 
						|
			dfa *d1 = finddfa(g, type);
 | 
						|
			int ibit;
 | 
						|
			if (type - NT_OFFSET >= (1 << 7)) {
 | 
						|
				printf("XXX too high nonterminal number!\n");
 | 
						|
				continue;
 | 
						|
			}
 | 
						|
			for (ibit = 0; ibit < g->g_ll.ll_nlabels; ibit++) {
 | 
						|
				if (testbit(d1->d_first, ibit)) {
 | 
						|
#ifdef applec
 | 
						|
#define MPW_881_bug			/* Undefine if bug below is fixed */
 | 
						|
#endif
 | 
						|
#ifdef MPW_881_BUG
 | 
						|
					/* In 881 mode MPW 3.1 has a code
 | 
						|
					   generation bug which seems to
 | 
						|
					   set the upper bits; fix this by
 | 
						|
					   explicitly masking them off */
 | 
						|
					int temp;
 | 
						|
#endif
 | 
						|
					if (accel[ibit] != -1)
 | 
						|
						printf("XXX ambiguity!\n");
 | 
						|
#ifdef MPW_881_BUG
 | 
						|
					temp = 0xFFFF &
 | 
						|
						(a->a_arrow | (1 << 7) |
 | 
						|
						 ((type - NT_OFFSET) << 8));
 | 
						|
					accel[ibit] = temp;
 | 
						|
#else
 | 
						|
					accel[ibit] = a->a_arrow | (1 << 7) |
 | 
						|
						((type - NT_OFFSET) << 8);
 | 
						|
#endif
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		else if (lbl == EMPTY)
 | 
						|
			s->s_accept = 1;
 | 
						|
		else if (lbl >= 0 && lbl < nl)
 | 
						|
			accel[lbl] = a->a_arrow;
 | 
						|
	}
 | 
						|
	while (nl > 0 && accel[nl-1] == -1)
 | 
						|
		nl--;
 | 
						|
	for (k = 0; k < nl && accel[k] == -1;)
 | 
						|
		k++;
 | 
						|
	if (k < nl) {
 | 
						|
		int i;
 | 
						|
		s->s_accel = NEW(int, nl-k);
 | 
						|
		if (s->s_accel == NULL) {
 | 
						|
			fprintf(stderr, "no mem to add parser accelerators\n");
 | 
						|
			exit(1);
 | 
						|
		}
 | 
						|
		s->s_lower = k;
 | 
						|
		s->s_upper = nl;
 | 
						|
		for (i = 0; k < nl; i++, k++)
 | 
						|
			s->s_accel[i] = accel[k];
 | 
						|
	}
 | 
						|
	DEL(accel);
 | 
						|
}
 |