예제 #1
0
static void
makedfa(nfagrammar *gr, nfa *nf, dfa *d)
{
  int nbits = nf->nf_nstates;
  bitset ss;
  int xx_nstates;
  ss_state *xx_state, *yy;
  ss_arc *zz;
  int istate, jstate, iarc, jarc, ibit;
  nfastate *st;
  nfaarc *ar;

  ss = newbitset(nbits);
  addclosure(ss, nf, nf->nf_start);
  xx_state = (ss_state *)PyObject_MALLOC(sizeof(ss_state));
  if (xx_state == NULL)
    Py_FatalError("no mem for xx_state in makedfa");
  xx_nstates = 1;
  yy = &xx_state[0];
  yy->ss_ss = ss;
  yy->ss_narcs = 0;
  yy->ss_arc = NULL;
  yy->ss_deleted = 0;
  yy->ss_finish = testbit(ss, nf->nf_finish);
  if (yy->ss_finish)
    printf("Error: nonterminal '%s' may produce empty.\n",
    nf->nf_name);

  /* This algorithm is from a book written before
  the invention of structured programming... */

  /* For each unmarked state... */
  for (istate = 0; istate < xx_nstates; ++istate) {
    size_t size;
    yy = &xx_state[istate];
    ss = yy->ss_ss;
    /* For all its states... */
    for (ibit = 0; ibit < nf->nf_nstates; ++ibit) {
      if (!testbit(ss, ibit))
        continue;
      st = &nf->nf_state[ibit];
      /* For all non-empty arcs from this state... */
      for (iarc = 0; iarc < st->st_narcs; iarc++) {
        ar = &st->st_arc[iarc];
        if (ar->ar_label == EMPTY)
          continue;
        /* Look up in list of arcs from this state */
        for (jarc = 0; jarc < yy->ss_narcs; ++jarc) {
          zz = &yy->ss_arc[jarc];
          if (ar->ar_label == zz->sa_label)
            goto found;
        }
        /* Add new arc for this state */
        size = sizeof(ss_arc) * (yy->ss_narcs + 1);
        yy->ss_arc = (ss_arc *)PyObject_REALLOC(
          yy->ss_arc, size);
        if (yy->ss_arc == NULL)
          Py_FatalError("out of mem");
        zz = &yy->ss_arc[yy->ss_narcs++];
        zz->sa_label = ar->ar_label;
        zz->sa_bitset = newbitset(nbits);
        zz->sa_arrow = -1;
found:             ;
        /* Add destination */
        addclosure(zz->sa_bitset, nf, ar->ar_arrow);
      }
    }
    /* Now look up all the arrow states */
    for (jarc = 0; jarc < xx_state[istate].ss_narcs; jarc++) {
      zz = &xx_state[istate].ss_arc[jarc];
      for (jstate = 0; jstate < xx_nstates; jstate++) {
        if (samebitset(zz->sa_bitset,
          xx_state[jstate].ss_ss, nbits)) {
            zz->sa_arrow = jstate;
            goto done;
        }
      }
      size = sizeof(ss_state) * (xx_nstates + 1);
      xx_state = (ss_state *)PyObject_REALLOC(xx_state,
        size);
      if (xx_state == NULL)
        Py_FatalError("out of mem");
      zz->sa_arrow = xx_nstates;
      yy = &xx_state[xx_nstates++];
      yy->ss_ss = zz->sa_bitset;
      yy->ss_narcs = 0;
      yy->ss_arc = NULL;
      yy->ss_deleted = 0;
      yy->ss_finish = testbit(yy->ss_ss, nf->nf_finish);
done:          ;
    }
  }

  if (Py_DebugFlag)
    printssdfa(xx_nstates, xx_state, nbits, &gr->gr_ll,
    "before minimizing");

  simplify(xx_nstates, xx_state);

  if (Py_DebugFlag)
    printssdfa(xx_nstates, xx_state, nbits, &gr->gr_ll,
    "after minimizing");

  convert(d, xx_nstates, xx_state);

  /* XXX cleanup */
  PyObject_FREE(xx_state);
}
예제 #2
0
static void
calcfirstset(grammar *g, dfa *d)
{
	int i, j;
	state *s;
	arc *a;
	int nsyms;
	int *sym;
	int nbits;
	static bitset dummy;
	bitset result;
	int type;
	dfa *d1;
	label *l0;
	
	if (Py_DebugFlag)
		printf("Calculate FIRST set for '%s'\n", d->d_name);
	
	if (dummy == NULL)
		dummy = newbitset(1);
	if (d->d_first == dummy) {
		fprintf(stderr, "Left-recursion for '%s'\n", d->d_name);
		return;
	}
	if (d->d_first != NULL) {
		fprintf(stderr, "Re-calculating FIRST set for '%s' ???\n",
			d->d_name);
	}
	d->d_first = dummy;
	
	l0 = g->g_ll.ll_label;
	nbits = g->g_ll.ll_nlabels;
	result = newbitset(nbits);
	
	sym = (int *)PyObject_MALLOC(sizeof(int));
	if (sym == NULL)
		Py_FatalError("no mem for new sym in calcfirstset");
	nsyms = 1;
	sym[0] = findlabel(&g->g_ll, d->d_type, (char *)NULL);
	
	s = &d->d_state[d->d_initial];
	for (i = 0; i < s->s_narcs; i++) {
		a = &s->s_arc[i];
		for (j = 0; j < nsyms; j++) {
			if (sym[j] == a->a_lbl)
				break;
		}
		if (j >= nsyms) { /* New label */
			sym = (int *)PyObject_REALLOC(sym, 
                                                sizeof(int) * (nsyms + 1));
			if (sym == NULL)
				Py_FatalError(
				    "no mem to resize sym in calcfirstset");
			sym[nsyms++] = a->a_lbl;
			type = l0[a->a_lbl].lb_type;
			if (ISNONTERMINAL(type)) {
				d1 = PyGrammar_FindDFA(g, type);
				if (d1->d_first == dummy) {
					fprintf(stderr,
						"Left-recursion below '%s'\n",
						d->d_name);
				}
				else {
					if (d1->d_first == NULL)
						calcfirstset(g, d1);
					mergebitset(result,
						    d1->d_first, nbits);
				}
			}
			else if (ISTERMINAL(type)) {
				addbit(result, a->a_lbl);
			}
		}
	}
	d->d_first = result;
	if (Py_DebugFlag) {
		printf("FIRST set for '%s': {", d->d_name);
		for (i = 0; i < nbits; i++) {
			if (testbit(result, i))
				printf(" %s", PyGrammar_LabelRepr(&l0[i]));
		}
		printf(" }\n");
	}

	PyObject_FREE(sym);
}
예제 #3
0
PyFrameObject *
PyFrame_New(PyThreadState *tstate, PyCodeObject *code,
            PyObject *globals, PyObject *locals)
{
	PyFrameObject *back = tstate->frame;
	static PyObject *builtin_object;
	PyFrameObject *f;
	PyObject *builtins;
	int extras;

	if (builtin_object == NULL) {
		builtin_object = PyString_InternFromString("__builtins__");
		if (builtin_object == NULL)
			return NULL;
	}
	if ((back != NULL && !PyFrame_Check(back)) ||
	    code == NULL || !PyCode_Check(code) ||
	    globals == NULL || !PyDict_Check(globals) ||
	    (locals != NULL && !PyDict_Check(locals))) {
		PyErr_BadInternalCall();
		return NULL;
	}
	extras = code->co_stacksize + code->co_nlocals;
	if (back == NULL || back->f_globals != globals) {
		builtins = PyDict_GetItem(globals, builtin_object);
		if (builtins != NULL && PyModule_Check(builtins))
			builtins = PyModule_GetDict(builtins);
	}
	else {
		/* If we share the globals, we share the builtins.
		   Save a lookup and a call. */
		builtins = back->f_builtins;
	}
	if (builtins != NULL && !PyDict_Check(builtins))
		builtins = NULL;
	if (free_list == NULL) {
		/* PyObject_New is inlined */
		f = (PyFrameObject *)
			PyObject_MALLOC(sizeof(PyFrameObject) +
					extras*sizeof(PyObject *));
		if (f == NULL)
			return (PyFrameObject *)PyErr_NoMemory();
		PyObject_INIT(f, &PyFrame_Type);
	}
	else {
		f = free_list;
		free_list = free_list->f_back;
		if (f->f_nlocals + f->f_stacksize < extras) {
			f = (PyFrameObject *)
				PyObject_REALLOC(f, sizeof(PyFrameObject) +
						 extras*sizeof(PyObject *));
			if (f == NULL)
				return (PyFrameObject *)PyErr_NoMemory();
		}
		else
			extras = f->f_nlocals + f->f_stacksize;
		PyObject_INIT(f, &PyFrame_Type);
	}
	if (builtins == NULL) {
		/* No builtins!  Make up a minimal one. */
		builtins = PyDict_New();
		if (builtins == NULL || /* Give them 'None', at least. */
		    PyDict_SetItemString(builtins, "None", Py_None) < 0) {
			Py_DECREF(f);
			return NULL;
		}
	}
	else
		Py_XINCREF(builtins);
	f->f_builtins = builtins;
	Py_XINCREF(back);
	f->f_back = back;
	Py_INCREF(code);
	f->f_code = code;
	Py_INCREF(globals);
	f->f_globals = globals;
	if (code->co_flags & CO_NEWLOCALS) {
		if (code->co_flags & CO_OPTIMIZED)
			locals = NULL; /* Let fast_2_locals handle it */
		else {
			locals = PyDict_New();
			if (locals == NULL) {
				Py_DECREF(f);
				return NULL;
			}
		}
	}
	else {
		if (locals == NULL)
			locals = globals;
		Py_INCREF(locals);
	}
	f->f_locals = locals;
	f->f_trace = NULL;
	f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL;
	f->f_tstate = tstate;

	f->f_lasti = 0;
	f->f_lineno = code->co_firstlineno;
	f->f_restricted = (builtins != tstate->interp->builtins);
	f->f_iblock = 0;
	f->f_nlocals = code->co_nlocals;
	f->f_stacksize = extras - code->co_nlocals;

	while (--extras >= 0)
		f->f_localsplus[extras] = NULL;

	f->f_valuestack = f->f_localsplus + f->f_nlocals;

	return f;
}
예제 #4
0
void *
PyObject_Realloc(void *p, size_t nbytes)
{
	return PyObject_REALLOC(p, nbytes);
}