+++ /dev/null
-\r
-/* Parser accelerator module */\r
-\r
-/* The parser as originally conceived had disappointing performance.\r
- This module does some precomputation that speeds up the selection\r
- of a DFA based upon a token, turning a search through an array\r
- into a simple indexing operation. The parser now cannot work\r
- without the accelerators installed. Note that the accelerators\r
- are installed dynamically when the parser is initialized, they\r
- are not part of the static data structure written on graminit.[ch]\r
- by the parser generator. */\r
-\r
-#include "pgenheaders.h"\r
-#include "grammar.h"\r
-#include "node.h"\r
-#include "token.h"\r
-#include "parser.h"\r
-\r
-/* Forward references */\r
-static void fixdfa(grammar *, dfa *);\r
-static void fixstate(grammar *, state *);\r
-\r
-void\r
-PyGrammar_AddAccelerators(grammar *g)\r
-{\r
- dfa *d;\r
- int i;\r
- d = g->g_dfa;\r
- for (i = g->g_ndfas; --i >= 0; d++)\r
- fixdfa(g, d);\r
- g->g_accel = 1;\r
-}\r
-\r
-void\r
-PyGrammar_RemoveAccelerators(grammar *g)\r
-{\r
- dfa *d;\r
- int i;\r
- g->g_accel = 0;\r
- d = g->g_dfa;\r
- for (i = g->g_ndfas; --i >= 0; d++) {\r
- state *s;\r
- int j;\r
- s = d->d_state;\r
- for (j = 0; j < d->d_nstates; j++, s++) {\r
- if (s->s_accel)\r
- PyObject_FREE(s->s_accel);\r
- s->s_accel = NULL;\r
- }\r
- }\r
-}\r
-\r
-static void\r
-fixdfa(grammar *g, dfa *d)\r
-{\r
- state *s;\r
- int j;\r
- s = d->d_state;\r
- for (j = 0; j < d->d_nstates; j++, s++)\r
- fixstate(g, s);\r
-}\r
-\r
-static void\r
-fixstate(grammar *g, state *s)\r
-{\r
- arc *a;\r
- int k;\r
- int *accel;\r
- int nl = g->g_ll.ll_nlabels;\r
- s->s_accept = 0;\r
- accel = (int *) PyObject_MALLOC(nl * sizeof(int));\r
- if (accel == NULL) {\r
- fprintf(stderr, "no mem to build parser accelerators\n");\r
- exit(1);\r
- }\r
- for (k = 0; k < nl; k++)\r
- accel[k] = -1;\r
- a = s->s_arc;\r
- for (k = s->s_narcs; --k >= 0; a++) {\r
- int lbl = a->a_lbl;\r
- label *l = &g->g_ll.ll_label[lbl];\r
- int type = l->lb_type;\r
- if (a->a_arrow >= (1 << 7)) {\r
- printf("XXX too many states!\n");\r
- continue;\r
- }\r
- if (ISNONTERMINAL(type)) {\r
- dfa *d1 = PyGrammar_FindDFA(g, type);\r
- int ibit;\r
- if (type - NT_OFFSET >= (1 << 7)) {\r
- printf("XXX too high nonterminal number!\n");\r
- continue;\r
- }\r
- for (ibit = 0; ibit < g->g_ll.ll_nlabels; ibit++) {\r
- if (testbit(d1->d_first, ibit)) {\r
- if (accel[ibit] != -1)\r
- printf("XXX ambiguity!\n");\r
- accel[ibit] = a->a_arrow | (1 << 7) |\r
- ((type - NT_OFFSET) << 8);\r
- }\r
- }\r
- }\r
- else if (lbl == EMPTY)\r
- s->s_accept = 1;\r
- else if (lbl >= 0 && lbl < nl)\r
- accel[lbl] = a->a_arrow;\r
- }\r
- while (nl > 0 && accel[nl-1] == -1)\r
- nl--;\r
- for (k = 0; k < nl && accel[k] == -1;)\r
- k++;\r
- if (k < nl) {\r
- int i;\r
- s->s_accel = (int *) PyObject_MALLOC((nl-k) * sizeof(int));\r
- if (s->s_accel == NULL) {\r
- fprintf(stderr, "no mem to add parser accelerators\n");\r
- exit(1);\r
- }\r
- s->s_lower = k;\r
- s->s_upper = nl;\r
- for (i = 0; k < nl; i++, k++)\r
- s->s_accel[i] = accel[k];\r
- }\r
- PyObject_FREE(accel);\r
-}\r